Revert "update"

This reverts commit 75cc618c2b.
This commit is contained in:
pacnpal
2025-09-21 20:11:00 -04:00
parent 75cc618c2b
commit 540f40e689
610 changed files with 4812 additions and 1715 deletions

View File

@@ -1,421 +0,0 @@
"""
Maps domain serializers for ThrillWiki API v1.
This module contains all serializers related to map functionality,
including location data, search results, and clustering.
"""
from rest_framework import serializers
from drf_spectacular.utils import (
extend_schema_serializer,
extend_schema_field,
OpenApiExample,
)
# === MAP LOCATION SERIALIZERS ===
@extend_schema_serializer(
examples=[
OpenApiExample(
"Map Location Example",
summary="Example map location response",
description="A location point on the map",
value={
"id": 1,
"type": "park",
"name": "Cedar Point",
"slug": "cedar-point",
"latitude": 41.4793,
"longitude": -82.6833,
"status": "OPERATING",
"location": {
"city": "Sandusky",
"state": "Ohio",
"country": "United States",
},
"stats": {
"coaster_count": 17,
"ride_count": 70,
"average_rating": 4.5,
},
},
)
]
)
class MapLocationSerializer(serializers.Serializer):
"""Serializer for individual map locations (parks and rides)."""
id = serializers.IntegerField()
type = serializers.CharField() # 'park' or 'ride'
name = serializers.CharField()
slug = serializers.CharField()
latitude = serializers.FloatField(allow_null=True)
longitude = serializers.FloatField(allow_null=True)
status = serializers.CharField()
# Location details
location = serializers.SerializerMethodField()
# Statistics
stats = serializers.SerializerMethodField()
@extend_schema_field(serializers.DictField())
def get_location(self, obj) -> dict:
"""Get location information."""
if hasattr(obj, "location") and obj.location:
return {
"city": obj.location.city,
"state": obj.location.state,
"country": obj.location.country,
"formatted_address": obj.location.formatted_address,
}
return {}
@extend_schema_field(serializers.DictField())
def get_stats(self, obj) -> dict:
"""Get relevant statistics based on object type."""
if obj._meta.model_name == "park":
return {
"coaster_count": obj.coaster_count or 0,
"ride_count": obj.ride_count or 0,
"average_rating": (
float(obj.average_rating) if obj.average_rating else None
),
}
elif obj._meta.model_name == "ride":
return {
"category": obj.get_category_display() if obj.category else None,
"average_rating": (
float(obj.average_rating) if obj.average_rating else None
),
"park_name": obj.park.name if obj.park else None,
}
return {}
@extend_schema_serializer(
examples=[
OpenApiExample(
"Map Cluster Example",
summary="Example map cluster response",
description="A cluster of locations on the map",
value={
"id": "cluster_1",
"type": "cluster",
"latitude": 41.5,
"longitude": -82.7,
"count": 5,
"bounds": {
"north": 41.6,
"south": 41.4,
"east": -82.6,
"west": -82.8,
},
},
)
]
)
class MapClusterSerializer(serializers.Serializer):
"""Serializer for map clusters."""
id = serializers.CharField()
type = serializers.CharField(default="cluster")
latitude = serializers.FloatField()
longitude = serializers.FloatField()
count = serializers.IntegerField()
bounds = serializers.DictField()
@extend_schema_serializer(
examples=[
OpenApiExample(
"Map Locations Response Example",
summary="Example map locations response",
description="Response containing locations and optional clusters",
value={
"status": "success",
"data": {
"locations": [
{
"id": 1,
"type": "park",
"name": "Cedar Point",
"slug": "cedar-point",
"latitude": 41.4793,
"longitude": -82.6833,
"status": "OPERATING",
}
],
"clusters": [],
"bounds": {
"north": 41.5,
"south": 41.4,
"east": -82.6,
"west": -82.8,
},
"total_count": 1,
"clustered": False,
},
},
)
]
)
class MapLocationsResponseSerializer(serializers.Serializer):
"""Response serializer for map locations endpoint."""
status = serializers.CharField(default="success")
locations = serializers.ListField(child=serializers.DictField())
clusters = serializers.ListField(child=serializers.DictField(), default=list)
bounds = serializers.DictField(default=dict)
total_count = serializers.IntegerField(default=0)
clustered = serializers.BooleanField(default=False)
# === MAP SEARCH SERIALIZERS ===
@extend_schema_serializer(
examples=[
OpenApiExample(
"Map Search Result Example",
summary="Example map search result",
description="A search result for map locations",
value={
"id": 1,
"type": "park",
"name": "Cedar Point",
"slug": "cedar-point",
"latitude": 41.4793,
"longitude": -82.6833,
"location": {
"city": "Sandusky",
"state": "Ohio",
"country": "United States",
},
"relevance_score": 0.95,
},
)
]
)
class MapSearchResultSerializer(serializers.Serializer):
"""Serializer for map search results."""
id = serializers.IntegerField()
type = serializers.CharField()
name = serializers.CharField()
slug = serializers.CharField()
latitude = serializers.FloatField(allow_null=True)
longitude = serializers.FloatField(allow_null=True)
location = serializers.SerializerMethodField()
relevance_score = serializers.FloatField(required=False)
@extend_schema_field(serializers.DictField())
def get_location(self, obj) -> dict:
"""Get location information."""
if hasattr(obj, "location") and obj.location:
return {
"city": obj.location.city,
"state": obj.location.state,
"country": obj.location.country,
}
return {}
@extend_schema_serializer(
examples=[
OpenApiExample(
"Map Search Response Example",
summary="Example map search response",
description="Response containing search results",
value={
"status": "success",
"data": {
"results": [
{
"id": 1,
"type": "park",
"name": "Cedar Point",
"slug": "cedar-point",
"latitude": 41.4793,
"longitude": -82.6833,
}
],
"query": "cedar point",
"total_count": 1,
"page": 1,
"page_size": 20,
},
},
)
]
)
class MapSearchResponseSerializer(serializers.Serializer):
"""Response serializer for map search endpoint."""
status = serializers.CharField(default="success")
results = serializers.ListField(child=serializers.DictField())
query = serializers.CharField()
total_count = serializers.IntegerField(default=0)
page = serializers.IntegerField(default=1)
page_size = serializers.IntegerField(default=20)
# === MAP DETAIL SERIALIZERS ===
@extend_schema_serializer(
examples=[
OpenApiExample(
"Map Location Detail Example",
summary="Example map location detail response",
description="Detailed information about a specific location",
value={
"id": 1,
"type": "park",
"name": "Cedar Point",
"slug": "cedar-point",
"description": "America's Roller Coast",
"latitude": 41.4793,
"longitude": -82.6833,
"status": "OPERATING",
"location": {
"street_address": "1 Cedar Point Dr",
"city": "Sandusky",
"state": "Ohio",
"country": "United States",
"postal_code": "44870",
"formatted_address": "1 Cedar Point Dr, Sandusky, Ohio, 44870, United States",
},
"stats": {
"coaster_count": 17,
"ride_count": 70,
"average_rating": 4.5,
},
"nearby_locations": [],
},
)
]
)
class MapLocationDetailSerializer(serializers.Serializer):
"""Serializer for detailed map location information."""
id = serializers.IntegerField()
type = serializers.CharField()
name = serializers.CharField()
slug = serializers.CharField()
description = serializers.CharField()
latitude = serializers.FloatField(allow_null=True)
longitude = serializers.FloatField(allow_null=True)
status = serializers.CharField()
# Detailed location information
location = serializers.SerializerMethodField()
# Statistics
stats = serializers.SerializerMethodField()
# Nearby locations
nearby_locations = serializers.SerializerMethodField()
@extend_schema_field(serializers.DictField())
def get_location(self, obj) -> dict:
"""Get detailed location information."""
if hasattr(obj, "location") and obj.location:
return {
"street_address": obj.location.street_address,
"city": obj.location.city,
"state": obj.location.state,
"country": obj.location.country,
"postal_code": obj.location.postal_code,
"formatted_address": obj.location.formatted_address,
}
return {}
@extend_schema_field(serializers.DictField())
def get_stats(self, obj) -> dict:
"""Get detailed statistics based on object type."""
if obj._meta.model_name == "park":
return {
"coaster_count": obj.coaster_count or 0,
"ride_count": obj.ride_count or 0,
"average_rating": (
float(obj.average_rating) if obj.average_rating else None
),
"size_acres": float(obj.size_acres) if obj.size_acres else None,
"opening_date": (
obj.opening_date.isoformat() if obj.opening_date else None
),
}
elif obj._meta.model_name == "ride":
return {
"category": obj.get_category_display() if obj.category else None,
"average_rating": (
float(obj.average_rating) if obj.average_rating else None
),
"park_name": obj.park.name if obj.park else None,
"opening_date": (
obj.opening_date.isoformat() if obj.opening_date else None
),
"manufacturer": obj.manufacturer.name if obj.manufacturer else None,
}
return {}
@extend_schema_field(serializers.ListField(child=serializers.DictField()))
def get_nearby_locations(self, obj) -> list:
"""Get nearby locations (placeholder for now)."""
# TODO: Implement nearby location logic
return []
# === INPUT SERIALIZERS ===
class MapBoundsInputSerializer(serializers.Serializer):
"""Input serializer for map bounds queries."""
north = serializers.FloatField(min_value=-90, max_value=90)
south = serializers.FloatField(min_value=-90, max_value=90)
east = serializers.FloatField(min_value=-180, max_value=180)
west = serializers.FloatField(min_value=-180, max_value=180)
def validate(self, attrs):
"""Validate that bounds make geographic sense."""
if attrs["north"] <= attrs["south"]:
raise serializers.ValidationError(
"North bound must be greater than south bound"
)
# Handle longitude wraparound (e.g., crossing the international date line)
# For now, we'll require west < east for simplicity
if attrs["west"] >= attrs["east"]:
raise serializers.ValidationError("West bound must be less than east bound")
return attrs
class MapSearchInputSerializer(serializers.Serializer):
"""Input serializer for map search queries."""
q = serializers.CharField(min_length=1, max_length=255)
types = serializers.CharField(required=False, allow_blank=True)
bounds = MapBoundsInputSerializer(required=False)
page = serializers.IntegerField(min_value=1, default=1)
page_size = serializers.IntegerField(min_value=1, max_value=100, default=20)
def validate_types(self, value):
"""Validate location types."""
if not value:
return []
valid_types = ["park", "ride"]
types = [t.strip().lower() for t in value.split(",")]
for location_type in types:
if location_type not in valid_types:
raise serializers.ValidationError(
f"Invalid location type: {location_type}. Valid types: {', '.join(valid_types)}"
)
return types