mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 06:11:11 -05:00
Add email templates for user notifications and account management
- Created a base email template (base.html) for consistent styling across all emails. - Added moderation approval email template (moderation_approved.html) to notify users of approved submissions. - Added moderation rejection email template (moderation_rejected.html) to inform users of required changes for their submissions. - Created password reset email template (password_reset.html) for users requesting to reset their passwords. - Developed a welcome email template (welcome.html) to greet new users and provide account details and tips for using ThrillWiki.
This commit is contained in:
369
django/api/v1/endpoints/versioning.py
Normal file
369
django/api/v1/endpoints/versioning.py
Normal file
@@ -0,0 +1,369 @@
|
||||
"""
|
||||
Versioning API endpoints for ThrillWiki.
|
||||
|
||||
Provides REST API for:
|
||||
- Version history for entities
|
||||
- Specific version details
|
||||
- Comparing versions
|
||||
- Diff with current state
|
||||
- Version restoration (optional)
|
||||
"""
|
||||
|
||||
from typing import List
|
||||
from uuid import UUID
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.http import Http404
|
||||
from ninja import Router
|
||||
|
||||
from apps.entities.models import Park, Ride, Company, RideModel
|
||||
from apps.versioning.models import EntityVersion
|
||||
from apps.versioning.services import VersionService
|
||||
from api.v1.schemas import (
|
||||
EntityVersionSchema,
|
||||
VersionHistoryResponseSchema,
|
||||
VersionDiffSchema,
|
||||
VersionComparisonSchema,
|
||||
ErrorSchema,
|
||||
MessageSchema
|
||||
)
|
||||
|
||||
router = Router(tags=['Versioning'])
|
||||
|
||||
|
||||
# Park Versions
|
||||
|
||||
@router.get(
|
||||
'/parks/{park_id}/versions',
|
||||
response={200: VersionHistoryResponseSchema, 404: ErrorSchema},
|
||||
summary="Get park version history"
|
||||
)
|
||||
def get_park_versions(request, park_id: UUID, limit: int = 50):
|
||||
"""
|
||||
Get version history for a park.
|
||||
|
||||
Returns up to `limit` versions in reverse chronological order (newest first).
|
||||
"""
|
||||
park = get_object_or_404(Park, id=park_id)
|
||||
versions = VersionService.get_version_history(park, limit=limit)
|
||||
|
||||
return {
|
||||
'entity_id': str(park.id),
|
||||
'entity_type': 'park',
|
||||
'entity_name': park.name,
|
||||
'total_versions': VersionService.get_version_count(park),
|
||||
'versions': [
|
||||
EntityVersionSchema.from_orm(v) for v in versions
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@router.get(
|
||||
'/parks/{park_id}/versions/{version_number}',
|
||||
response={200: EntityVersionSchema, 404: ErrorSchema},
|
||||
summary="Get specific park version"
|
||||
)
|
||||
def get_park_version(request, park_id: UUID, version_number: int):
|
||||
"""Get a specific version of a park by version number."""
|
||||
park = get_object_or_404(Park, id=park_id)
|
||||
version = VersionService.get_version_by_number(park, version_number)
|
||||
|
||||
if not version:
|
||||
raise Http404("Version not found")
|
||||
|
||||
return EntityVersionSchema.from_orm(version)
|
||||
|
||||
|
||||
@router.get(
|
||||
'/parks/{park_id}/versions/{version_number}/diff',
|
||||
response={200: VersionDiffSchema, 404: ErrorSchema},
|
||||
summary="Compare park version with current"
|
||||
)
|
||||
def get_park_version_diff(request, park_id: UUID, version_number: int):
|
||||
"""
|
||||
Compare a specific version with the current park state.
|
||||
|
||||
Returns the differences between the version and current values.
|
||||
"""
|
||||
park = get_object_or_404(Park, id=park_id)
|
||||
version = VersionService.get_version_by_number(park, version_number)
|
||||
|
||||
if not version:
|
||||
raise Http404("Version not found")
|
||||
|
||||
diff = VersionService.get_diff_with_current(version)
|
||||
|
||||
return {
|
||||
'entity_id': str(park.id),
|
||||
'entity_type': 'park',
|
||||
'entity_name': park.name,
|
||||
'version_number': version.version_number,
|
||||
'version_date': version.created,
|
||||
'differences': diff['differences'],
|
||||
'changed_field_count': diff['changed_field_count']
|
||||
}
|
||||
|
||||
|
||||
# Ride Versions
|
||||
|
||||
@router.get(
|
||||
'/rides/{ride_id}/versions',
|
||||
response={200: VersionHistoryResponseSchema, 404: ErrorSchema},
|
||||
summary="Get ride version history"
|
||||
)
|
||||
def get_ride_versions(request, ride_id: UUID, limit: int = 50):
|
||||
"""Get version history for a ride."""
|
||||
ride = get_object_or_404(Ride, id=ride_id)
|
||||
versions = VersionService.get_version_history(ride, limit=limit)
|
||||
|
||||
return {
|
||||
'entity_id': str(ride.id),
|
||||
'entity_type': 'ride',
|
||||
'entity_name': ride.name,
|
||||
'total_versions': VersionService.get_version_count(ride),
|
||||
'versions': [
|
||||
EntityVersionSchema.from_orm(v) for v in versions
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@router.get(
|
||||
'/rides/{ride_id}/versions/{version_number}',
|
||||
response={200: EntityVersionSchema, 404: ErrorSchema},
|
||||
summary="Get specific ride version"
|
||||
)
|
||||
def get_ride_version(request, ride_id: UUID, version_number: int):
|
||||
"""Get a specific version of a ride by version number."""
|
||||
ride = get_object_or_404(Ride, id=ride_id)
|
||||
version = VersionService.get_version_by_number(ride, version_number)
|
||||
|
||||
if not version:
|
||||
raise Http404("Version not found")
|
||||
|
||||
return EntityVersionSchema.from_orm(version)
|
||||
|
||||
|
||||
@router.get(
|
||||
'/rides/{ride_id}/versions/{version_number}/diff',
|
||||
response={200: VersionDiffSchema, 404: ErrorSchema},
|
||||
summary="Compare ride version with current"
|
||||
)
|
||||
def get_ride_version_diff(request, ride_id: UUID, version_number: int):
|
||||
"""Compare a specific version with the current ride state."""
|
||||
ride = get_object_or_404(Ride, id=ride_id)
|
||||
version = VersionService.get_version_by_number(ride, version_number)
|
||||
|
||||
if not version:
|
||||
raise Http404("Version not found")
|
||||
|
||||
diff = VersionService.get_diff_with_current(version)
|
||||
|
||||
return {
|
||||
'entity_id': str(ride.id),
|
||||
'entity_type': 'ride',
|
||||
'entity_name': ride.name,
|
||||
'version_number': version.version_number,
|
||||
'version_date': version.created,
|
||||
'differences': diff['differences'],
|
||||
'changed_field_count': diff['changed_field_count']
|
||||
}
|
||||
|
||||
|
||||
# Company Versions
|
||||
|
||||
@router.get(
|
||||
'/companies/{company_id}/versions',
|
||||
response={200: VersionHistoryResponseSchema, 404: ErrorSchema},
|
||||
summary="Get company version history"
|
||||
)
|
||||
def get_company_versions(request, company_id: UUID, limit: int = 50):
|
||||
"""Get version history for a company."""
|
||||
company = get_object_or_404(Company, id=company_id)
|
||||
versions = VersionService.get_version_history(company, limit=limit)
|
||||
|
||||
return {
|
||||
'entity_id': str(company.id),
|
||||
'entity_type': 'company',
|
||||
'entity_name': company.name,
|
||||
'total_versions': VersionService.get_version_count(company),
|
||||
'versions': [
|
||||
EntityVersionSchema.from_orm(v) for v in versions
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@router.get(
|
||||
'/companies/{company_id}/versions/{version_number}',
|
||||
response={200: EntityVersionSchema, 404: ErrorSchema},
|
||||
summary="Get specific company version"
|
||||
)
|
||||
def get_company_version(request, company_id: UUID, version_number: int):
|
||||
"""Get a specific version of a company by version number."""
|
||||
company = get_object_or_404(Company, id=company_id)
|
||||
version = VersionService.get_version_by_number(company, version_number)
|
||||
|
||||
if not version:
|
||||
raise Http404("Version not found")
|
||||
|
||||
return EntityVersionSchema.from_orm(version)
|
||||
|
||||
|
||||
@router.get(
|
||||
'/companies/{company_id}/versions/{version_number}/diff',
|
||||
response={200: VersionDiffSchema, 404: ErrorSchema},
|
||||
summary="Compare company version with current"
|
||||
)
|
||||
def get_company_version_diff(request, company_id: UUID, version_number: int):
|
||||
"""Compare a specific version with the current company state."""
|
||||
company = get_object_or_404(Company, id=company_id)
|
||||
version = VersionService.get_version_by_number(company, version_number)
|
||||
|
||||
if not version:
|
||||
raise Http404("Version not found")
|
||||
|
||||
diff = VersionService.get_diff_with_current(version)
|
||||
|
||||
return {
|
||||
'entity_id': str(company.id),
|
||||
'entity_type': 'company',
|
||||
'entity_name': company.name,
|
||||
'version_number': version.version_number,
|
||||
'version_date': version.created,
|
||||
'differences': diff['differences'],
|
||||
'changed_field_count': diff['changed_field_count']
|
||||
}
|
||||
|
||||
|
||||
# Ride Model Versions
|
||||
|
||||
@router.get(
|
||||
'/ride-models/{model_id}/versions',
|
||||
response={200: VersionHistoryResponseSchema, 404: ErrorSchema},
|
||||
summary="Get ride model version history"
|
||||
)
|
||||
def get_ride_model_versions(request, model_id: UUID, limit: int = 50):
|
||||
"""Get version history for a ride model."""
|
||||
model = get_object_or_404(RideModel, id=model_id)
|
||||
versions = VersionService.get_version_history(model, limit=limit)
|
||||
|
||||
return {
|
||||
'entity_id': str(model.id),
|
||||
'entity_type': 'ride_model',
|
||||
'entity_name': str(model),
|
||||
'total_versions': VersionService.get_version_count(model),
|
||||
'versions': [
|
||||
EntityVersionSchema.from_orm(v) for v in versions
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@router.get(
|
||||
'/ride-models/{model_id}/versions/{version_number}',
|
||||
response={200: EntityVersionSchema, 404: ErrorSchema},
|
||||
summary="Get specific ride model version"
|
||||
)
|
||||
def get_ride_model_version(request, model_id: UUID, version_number: int):
|
||||
"""Get a specific version of a ride model by version number."""
|
||||
model = get_object_or_404(RideModel, id=model_id)
|
||||
version = VersionService.get_version_by_number(model, version_number)
|
||||
|
||||
if not version:
|
||||
raise Http404("Version not found")
|
||||
|
||||
return EntityVersionSchema.from_orm(version)
|
||||
|
||||
|
||||
@router.get(
|
||||
'/ride-models/{model_id}/versions/{version_number}/diff',
|
||||
response={200: VersionDiffSchema, 404: ErrorSchema},
|
||||
summary="Compare ride model version with current"
|
||||
)
|
||||
def get_ride_model_version_diff(request, model_id: UUID, version_number: int):
|
||||
"""Compare a specific version with the current ride model state."""
|
||||
model = get_object_or_404(RideModel, id=model_id)
|
||||
version = VersionService.get_version_by_number(model, version_number)
|
||||
|
||||
if not version:
|
||||
raise Http404("Version not found")
|
||||
|
||||
diff = VersionService.get_diff_with_current(version)
|
||||
|
||||
return {
|
||||
'entity_id': str(model.id),
|
||||
'entity_type': 'ride_model',
|
||||
'entity_name': str(model),
|
||||
'version_number': version.version_number,
|
||||
'version_date': version.created,
|
||||
'differences': diff['differences'],
|
||||
'changed_field_count': diff['changed_field_count']
|
||||
}
|
||||
|
||||
|
||||
# Generic Version Endpoints
|
||||
|
||||
@router.get(
|
||||
'/versions/{version_id}',
|
||||
response={200: EntityVersionSchema, 404: ErrorSchema},
|
||||
summary="Get version by ID"
|
||||
)
|
||||
def get_version(request, version_id: UUID):
|
||||
"""Get a specific version by its ID."""
|
||||
version = get_object_or_404(EntityVersion, id=version_id)
|
||||
return EntityVersionSchema.from_orm(version)
|
||||
|
||||
|
||||
@router.get(
|
||||
'/versions/{version_id}/compare/{other_version_id}',
|
||||
response={200: VersionComparisonSchema, 404: ErrorSchema},
|
||||
summary="Compare two versions"
|
||||
)
|
||||
def compare_versions(request, version_id: UUID, other_version_id: UUID):
|
||||
"""
|
||||
Compare two versions of the same entity.
|
||||
|
||||
Both versions must be for the same entity.
|
||||
"""
|
||||
version1 = get_object_or_404(EntityVersion, id=version_id)
|
||||
version2 = get_object_or_404(EntityVersion, id=other_version_id)
|
||||
|
||||
comparison = VersionService.compare_versions(version1, version2)
|
||||
|
||||
return {
|
||||
'version1': EntityVersionSchema.from_orm(version1),
|
||||
'version2': EntityVersionSchema.from_orm(version2),
|
||||
'differences': comparison['differences'],
|
||||
'changed_field_count': comparison['changed_field_count']
|
||||
}
|
||||
|
||||
|
||||
# Optional: Version Restoration
|
||||
# Uncomment if you want to enable version restoration via API
|
||||
|
||||
# @router.post(
|
||||
# '/versions/{version_id}/restore',
|
||||
# response={200: MessageSchema, 404: ErrorSchema},
|
||||
# summary="Restore a version"
|
||||
# )
|
||||
# def restore_version(request, version_id: UUID):
|
||||
# """
|
||||
# Restore an entity to a previous version.
|
||||
#
|
||||
# This creates a new version with change_type='restored'.
|
||||
# Requires authentication and appropriate permissions.
|
||||
# """
|
||||
# version = get_object_or_404(EntityVersion, id=version_id)
|
||||
#
|
||||
# # Check authentication
|
||||
# if not request.user.is_authenticated:
|
||||
# return 401, {'error': 'Authentication required'}
|
||||
#
|
||||
# # Restore version
|
||||
# restored_version = VersionService.restore_version(
|
||||
# version,
|
||||
# user=request.user,
|
||||
# comment='Restored via API'
|
||||
# )
|
||||
#
|
||||
# return {
|
||||
# 'message': f'Successfully restored to version {version.version_number}',
|
||||
# 'new_version_number': restored_version.version_number
|
||||
# }
|
||||
Reference in New Issue
Block a user