Refactor code structure and remove redundant changes

This commit is contained in:
pacnpal
2025-08-26 13:19:04 -04:00
parent bf7e0c0f40
commit 831be6a2ee
151 changed files with 16260 additions and 9137 deletions

View File

@@ -0,0 +1,229 @@
"""
Services domain serializers for ThrillWiki API v1.
This module contains serializers for various services like email, maps,
history tracking, moderation, and roadtrip planning.
"""
from rest_framework import serializers
from drf_spectacular.utils import (
extend_schema_serializer,
extend_schema_field,
OpenApiExample,
)
# === EMAIL SERVICE SERIALIZERS ===
class EmailSendInputSerializer(serializers.Serializer):
"""Input serializer for sending emails."""
to = serializers.EmailField()
subject = serializers.CharField(max_length=255)
text = serializers.CharField()
html = serializers.CharField(required=False)
template = serializers.CharField(required=False)
context = serializers.JSONField(required=False)
class EmailTemplateOutputSerializer(serializers.Serializer):
"""Output serializer for email templates."""
id = serializers.CharField()
name = serializers.CharField()
subject = serializers.CharField()
text_template = serializers.CharField()
html_template = serializers.CharField(required=False)
# === MAP SERVICE SERIALIZERS ===
class MapDataOutputSerializer(serializers.Serializer):
"""Output serializer for map data."""
parks = serializers.ListField(child=serializers.DictField())
rides = serializers.ListField(child=serializers.DictField())
bounds = serializers.DictField()
zoom_level = serializers.IntegerField()
class CoordinateInputSerializer(serializers.Serializer):
"""Input serializer for coordinate-based requests."""
latitude = serializers.FloatField(min_value=-90, max_value=90)
longitude = serializers.FloatField(min_value=-180, max_value=180)
radius_km = serializers.FloatField(min_value=0, max_value=1000, default=10)
# === HISTORY SERIALIZERS ===
class HistoryEventSerializer(serializers.Serializer):
"""Base serializer for history events from pghistory."""
pgh_id = serializers.IntegerField(read_only=True)
pgh_created_at = serializers.DateTimeField(read_only=True)
pgh_label = serializers.CharField(read_only=True)
pgh_obj_id = serializers.IntegerField(read_only=True)
pgh_context = serializers.JSONField(read_only=True, allow_null=True)
pgh_diff = serializers.SerializerMethodField()
@extend_schema_field(serializers.DictField())
def get_pgh_diff(self, obj) -> dict:
"""Get diff from previous version if available."""
if hasattr(obj, "diff_against_previous"):
return obj.diff_against_previous()
return {}
class HistoryEntryOutputSerializer(serializers.Serializer):
"""Output serializer for history entries."""
id = serializers.IntegerField()
model_type = serializers.CharField()
object_id = serializers.IntegerField()
object_name = serializers.CharField()
action = serializers.CharField()
changes = serializers.JSONField()
timestamp = serializers.DateTimeField()
user = serializers.SerializerMethodField()
@extend_schema_field(serializers.DictField(allow_null=True))
def get_user(self, obj) -> dict | None:
if hasattr(obj, "user") and obj.user:
return {
"id": obj.user.id,
"username": obj.user.username,
}
return None
class HistoryCreateInputSerializer(serializers.Serializer):
"""Input serializer for creating history entries."""
action = serializers.CharField(max_length=50)
description = serializers.CharField(max_length=500)
metadata = serializers.JSONField(required=False)
# === MODERATION SERIALIZERS ===
class ModerationSubmissionSerializer(serializers.Serializer):
"""Serializer for moderation submissions."""
submission_type = serializers.ChoiceField(
choices=["EDIT", "PHOTO", "REVIEW"], help_text="Type of submission"
)
content_type = serializers.CharField(help_text="Content type being modified")
object_id = serializers.IntegerField(help_text="ID of object being modified")
changes = serializers.JSONField(help_text="Changes being submitted")
reason = serializers.CharField(
max_length=500,
required=False,
allow_blank=True,
help_text="Reason for the changes",
)
class ModerationSubmissionOutputSerializer(serializers.Serializer):
"""Output serializer for moderation submission responses."""
status = serializers.CharField()
message = serializers.CharField()
submission_id = serializers.IntegerField(required=False)
auto_approved = serializers.BooleanField(required=False)
# === ROADTRIP SERIALIZERS ===
class RoadtripParkSerializer(serializers.Serializer):
"""Serializer for parks in roadtrip planning."""
id = serializers.IntegerField()
name = serializers.CharField()
slug = serializers.CharField()
latitude = serializers.FloatField()
longitude = serializers.FloatField()
coaster_count = serializers.IntegerField()
status = serializers.CharField()
class RoadtripCreateInputSerializer(serializers.Serializer):
"""Input serializer for creating roadtrips."""
name = serializers.CharField(max_length=255)
park_ids = serializers.ListField(
child=serializers.IntegerField(),
min_length=2,
max_length=10,
help_text="List of park IDs (2-10 parks)",
)
start_date = serializers.DateField(required=False)
end_date = serializers.DateField(required=False)
notes = serializers.CharField(max_length=1000, required=False, allow_blank=True)
def validate_park_ids(self, value):
"""Validate park IDs."""
if len(value) < 2:
raise serializers.ValidationError("At least 2 parks are required")
if len(value) > 10:
raise serializers.ValidationError("Maximum 10 parks allowed")
if len(set(value)) != len(value):
raise serializers.ValidationError("Duplicate park IDs not allowed")
return value
class RoadtripOutputSerializer(serializers.Serializer):
"""Output serializer for roadtrip responses."""
id = serializers.CharField()
name = serializers.CharField()
parks = RoadtripParkSerializer(many=True)
total_distance_miles = serializers.FloatField()
estimated_drive_time_hours = serializers.FloatField()
route_coordinates = serializers.ListField(
child=serializers.ListField(child=serializers.FloatField())
)
created_at = serializers.DateTimeField()
class GeocodeInputSerializer(serializers.Serializer):
"""Input serializer for geocoding requests."""
address = serializers.CharField(max_length=500, help_text="Address to geocode")
class GeocodeOutputSerializer(serializers.Serializer):
"""Output serializer for geocoding responses."""
status = serializers.CharField()
coordinates = serializers.JSONField(required=False)
formatted_address = serializers.CharField(required=False)
# === DISTANCE CALCULATION SERIALIZERS ===
class DistanceCalculationInputSerializer(serializers.Serializer):
"""Input serializer for distance calculation requests."""
park1_id = serializers.IntegerField(help_text="ID of first park")
park2_id = serializers.IntegerField(help_text="ID of second park")
def validate(self, data):
"""Validate that park IDs are different."""
if data["park1_id"] == data["park2_id"]:
raise serializers.ValidationError("Park IDs must be different")
return data
class DistanceCalculationOutputSerializer(serializers.Serializer):
"""Output serializer for distance calculation responses."""
status = serializers.CharField()
distance_miles = serializers.FloatField(required=False)
distance_km = serializers.FloatField(required=False)
drive_time_hours = serializers.FloatField(required=False)
message = serializers.CharField(required=False)