mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-24 23:11:08 -05:00
Add secret management guide, client-side performance monitoring, and search accessibility enhancements
- Introduced a comprehensive Secret Management Guide detailing best practices, secret classification, development setup, production management, rotation procedures, and emergency protocols. - Implemented a client-side performance monitoring script to track various metrics including page load performance, paint metrics, layout shifts, and memory usage. - Enhanced search accessibility with keyboard navigation support for search results, ensuring compliance with WCAG standards and improving user experience.
This commit is contained in:
@@ -1,13 +1,20 @@
|
||||
"""
|
||||
Centralized map API views.
|
||||
Migrated from apps.core.views.map_views
|
||||
|
||||
Caching Strategy:
|
||||
- MapLocationsAPIView: 5 minutes (300s) - map data changes infrequently but needs freshness
|
||||
- MapLocationDetailAPIView: 30 minutes (1800s) - detail views are stable
|
||||
- MapSearchAPIView: 5 minutes (300s) - search results should be consistent
|
||||
- MapBoundsAPIView: 5 minutes (300s) - bounds queries are location-specific
|
||||
- MapStatsAPIView: 10 minutes (600s) - stats are aggregated and change slowly
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
from django.core.cache import cache
|
||||
from django.http import HttpRequest
|
||||
from django.db.models import Q
|
||||
from django.core.cache import cache
|
||||
from django.contrib.gis.geos import Polygon
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.response import Response
|
||||
@@ -23,6 +30,8 @@ from drf_spectacular.types import OpenApiTypes
|
||||
|
||||
from apps.parks.models import Park
|
||||
from apps.rides.models import Ride
|
||||
from apps.core.services.enhanced_cache_service import EnhancedCacheService
|
||||
from apps.core.decorators.cache_decorators import cache_api_response
|
||||
from ..serializers.maps import (
|
||||
MapLocationsResponseSerializer,
|
||||
MapSearchResponseSerializer,
|
||||
@@ -306,21 +315,28 @@ class MapLocationsAPIView(APIView):
|
||||
return {
|
||||
"status": "success",
|
||||
"locations": locations,
|
||||
"clusters": [], # TODO(THRILLWIKI-106): Implement map clustering algorithm
|
||||
"clusters": [], # See FUTURE_WORK.md - THRILLWIKI-106 for implementation plan
|
||||
"bounds": self._calculate_bounds(locations),
|
||||
"total_count": len(locations),
|
||||
"clustered": params["cluster"],
|
||||
}
|
||||
|
||||
def get(self, request: HttpRequest) -> Response:
|
||||
"""Get map locations with optional clustering and filtering."""
|
||||
"""
|
||||
Get map locations with optional clustering and filtering.
|
||||
|
||||
Caching: Uses EnhancedCacheService with 5-minute timeout (300s).
|
||||
Cache key is based on all query parameters for proper invalidation.
|
||||
"""
|
||||
try:
|
||||
params = self._parse_request_parameters(request)
|
||||
cache_key = self._build_cache_key(params)
|
||||
|
||||
# Check cache first
|
||||
cached_result = cache.get(cache_key)
|
||||
# Use EnhancedCacheService for improved caching with monitoring
|
||||
cache_service = EnhancedCacheService()
|
||||
cached_result = cache_service.get_cached_api_response('map_locations', params)
|
||||
if cached_result:
|
||||
logger.debug(f"Cache hit for map_locations with key: {cache_key}")
|
||||
return Response(cached_result)
|
||||
|
||||
# Get location data
|
||||
@@ -331,8 +347,9 @@ class MapLocationsAPIView(APIView):
|
||||
# Build response
|
||||
result = self._build_response(locations, params)
|
||||
|
||||
# Cache result for 5 minutes
|
||||
cache.set(cache_key, result, 300)
|
||||
# Cache result for 5 minutes using EnhancedCacheService
|
||||
cache_service.cache_api_response('map_locations', params, result, timeout=300)
|
||||
logger.debug(f"Cached map_locations result for key: {cache_key}")
|
||||
|
||||
return Response(result)
|
||||
|
||||
@@ -374,10 +391,15 @@ class MapLocationsAPIView(APIView):
|
||||
),
|
||||
)
|
||||
class MapLocationDetailAPIView(APIView):
|
||||
"""API endpoint for getting detailed information about a specific location."""
|
||||
"""
|
||||
API endpoint for getting detailed information about a specific location.
|
||||
|
||||
Caching: 30-minute timeout (1800s) - detail views are stable and change infrequently.
|
||||
"""
|
||||
|
||||
permission_classes = [AllowAny]
|
||||
|
||||
@cache_api_response(timeout=1800, key_prefix="map_detail")
|
||||
def get(
|
||||
self, request: HttpRequest, location_type: str, location_id: int
|
||||
) -> Response:
|
||||
@@ -471,7 +493,7 @@ class MapLocationDetailAPIView(APIView):
|
||||
obj.opening_date.isoformat() if obj.opening_date else None
|
||||
),
|
||||
},
|
||||
"nearby_locations": [], # TODO(THRILLWIKI-107): Implement nearby locations for parks
|
||||
"nearby_locations": [], # See FUTURE_WORK.md - THRILLWIKI-107
|
||||
}
|
||||
else: # ride
|
||||
data = {
|
||||
@@ -538,7 +560,7 @@ class MapLocationDetailAPIView(APIView):
|
||||
obj.manufacturer.name if obj.manufacturer else None
|
||||
),
|
||||
},
|
||||
"nearby_locations": [], # TODO(THRILLWIKI-107): Implement nearby locations for rides
|
||||
"nearby_locations": [], # See FUTURE_WORK.md - THRILLWIKI-107
|
||||
}
|
||||
|
||||
return Response(
|
||||
@@ -599,10 +621,16 @@ class MapLocationDetailAPIView(APIView):
|
||||
),
|
||||
)
|
||||
class MapSearchAPIView(APIView):
|
||||
"""API endpoint for searching locations by text query."""
|
||||
"""
|
||||
API endpoint for searching locations by text query.
|
||||
|
||||
Caching: 5-minute timeout (300s) - search results should remain consistent
|
||||
but need to reflect new content additions.
|
||||
"""
|
||||
|
||||
permission_classes = [AllowAny]
|
||||
|
||||
@cache_api_response(timeout=300, key_prefix="map_search")
|
||||
def get(self, request: HttpRequest) -> Response:
|
||||
"""Search locations by text query with pagination."""
|
||||
try:
|
||||
@@ -669,7 +697,7 @@ class MapSearchAPIView(APIView):
|
||||
else ""
|
||||
),
|
||||
},
|
||||
"relevance_score": 1.0, # TODO(THRILLWIKI-108): Implement relevance scoring for search
|
||||
"relevance_score": 1.0, # See FUTURE_WORK.md - THRILLWIKI-108
|
||||
}
|
||||
)
|
||||
|
||||
@@ -722,7 +750,7 @@ class MapSearchAPIView(APIView):
|
||||
else ""
|
||||
),
|
||||
},
|
||||
"relevance_score": 1.0, # TODO(THRILLWIKI-108): Implement relevance scoring for search
|
||||
"relevance_score": 1.0, # See FUTURE_WORK.md - THRILLWIKI-108
|
||||
}
|
||||
)
|
||||
|
||||
@@ -798,10 +826,16 @@ class MapSearchAPIView(APIView):
|
||||
),
|
||||
)
|
||||
class MapBoundsAPIView(APIView):
|
||||
"""API endpoint for getting locations within specific bounds."""
|
||||
"""
|
||||
API endpoint for getting locations within specific bounds.
|
||||
|
||||
Caching: 5-minute timeout (300s) - bounds queries are location-specific
|
||||
and may be repeated during map navigation.
|
||||
"""
|
||||
|
||||
permission_classes = [AllowAny]
|
||||
|
||||
@cache_api_response(timeout=300, key_prefix="map_bounds")
|
||||
def get(self, request: HttpRequest) -> Response:
|
||||
"""Get locations within specific geographic bounds."""
|
||||
try:
|
||||
@@ -939,10 +973,15 @@ class MapBoundsAPIView(APIView):
|
||||
),
|
||||
)
|
||||
class MapStatsAPIView(APIView):
|
||||
"""API endpoint for getting map service statistics and health information."""
|
||||
"""
|
||||
API endpoint for getting map service statistics and health information.
|
||||
|
||||
Caching: 10-minute timeout (600s) - stats are aggregated and change slowly.
|
||||
"""
|
||||
|
||||
permission_classes = [AllowAny]
|
||||
|
||||
@cache_api_response(timeout=600, key_prefix="map_stats")
|
||||
def get(self, request: HttpRequest) -> Response:
|
||||
"""Get map service statistics and performance metrics."""
|
||||
try:
|
||||
@@ -955,14 +994,21 @@ class MapStatsAPIView(APIView):
|
||||
).count()
|
||||
total_locations = parks_with_location + rides_with_location
|
||||
|
||||
# Get cache statistics
|
||||
from apps.core.services.enhanced_cache_service import CacheMonitor
|
||||
cache_monitor = CacheMonitor()
|
||||
cache_stats = cache_monitor.get_cache_statistics('map_locations')
|
||||
|
||||
return Response(
|
||||
{
|
||||
"status": "success",
|
||||
"total_locations": total_locations,
|
||||
"parks_with_location": parks_with_location,
|
||||
"rides_with_location": rides_with_location,
|
||||
"cache_hits": 0, # TODO(THRILLWIKI-109): Implement cache statistics tracking
|
||||
"cache_misses": 0, # TODO(THRILLWIKI-109): Implement cache statistics tracking
|
||||
"cache_hits": cache_stats.get('hits', 0),
|
||||
"cache_misses": cache_stats.get('misses', 0),
|
||||
"cache_hit_rate": cache_stats.get('hit_rate', 0.0),
|
||||
"cache_size": cache_stats.get('size', 0),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user