mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-24 13:51:09 -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:
@@ -11,6 +11,16 @@ This module implements a "full fat" set of endpoints:
|
||||
Notes:
|
||||
- These views try to use real Django models if available. If the domain models/services
|
||||
are not present, they return a clear 501 response explaining what to wire up.
|
||||
|
||||
Caching Strategy:
|
||||
- RideListCreateAPIView.get: 10 minutes (600s) - ride lists are frequently queried
|
||||
- RideDetailAPIView.get: 30 minutes (1800s) - detail views are stable
|
||||
- FilterOptionsAPIView.get: 30 minutes (1800s) - filter options change rarely
|
||||
- HybridRideAPIView.get: 10 minutes (600s) - ride lists with filters
|
||||
- RideFilterMetadataAPIView.get: 30 minutes (1800s) - metadata is stable
|
||||
- CompanySearchAPIView.get: 10 minutes (600s) - company data is stable
|
||||
- RideModelSearchAPIView.get: 10 minutes (600s) - ride model data is stable
|
||||
- RideSearchSuggestionsAPIView.get: 5 minutes (300s) - suggestions should be fresh
|
||||
"""
|
||||
|
||||
import logging
|
||||
@@ -33,6 +43,7 @@ from apps.api.v1.serializers.rides import (
|
||||
RideListOutputSerializer,
|
||||
RideUpdateInputSerializer,
|
||||
)
|
||||
from apps.core.decorators.cache_decorators import cache_api_response
|
||||
from apps.rides.services.hybrid_loader import SmartRideLoader
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -73,6 +84,13 @@ class StandardResultsSetPagination(PageNumberPagination):
|
||||
|
||||
# --- Ride list & create -----------------------------------------------------
|
||||
class RideListCreateAPIView(APIView):
|
||||
"""
|
||||
API View for listing and creating rides.
|
||||
|
||||
Caching: GET requests are cached for 10 minutes (600s).
|
||||
POST requests bypass cache and invalidate related cache entries.
|
||||
"""
|
||||
|
||||
permission_classes = [permissions.AllowAny]
|
||||
|
||||
@extend_schema(
|
||||
@@ -281,6 +299,7 @@ class RideListCreateAPIView(APIView):
|
||||
responses={200: RideListOutputSerializer(many=True)},
|
||||
tags=["Rides"],
|
||||
)
|
||||
@cache_api_response(timeout=600, key_prefix="ride_list")
|
||||
def get(self, request: Request) -> Response:
|
||||
"""List rides with comprehensive filtering and pagination."""
|
||||
if not MODELS_AVAILABLE:
|
||||
@@ -658,6 +677,13 @@ class RideListCreateAPIView(APIView):
|
||||
tags=["Rides"],
|
||||
)
|
||||
class RideDetailAPIView(APIView):
|
||||
"""
|
||||
API View for retrieving, updating, or deleting a single ride.
|
||||
|
||||
Caching: GET requests are cached for 30 minutes (1800s).
|
||||
PATCH/PUT/DELETE requests bypass cache and should trigger cache invalidation.
|
||||
"""
|
||||
|
||||
permission_classes = [permissions.AllowAny]
|
||||
|
||||
def _get_ride_or_404(self, pk: int) -> Any:
|
||||
@@ -671,6 +697,7 @@ class RideDetailAPIView(APIView):
|
||||
except Ride.DoesNotExist: # type: ignore
|
||||
raise NotFound("Ride not found")
|
||||
|
||||
@cache_api_response(timeout=1800, key_prefix="ride_detail")
|
||||
def get(self, request: Request, pk: int) -> Response:
|
||||
ride = self._get_ride_or_404(pk)
|
||||
serializer = RideDetailOutputSerializer(ride, context={"request": request})
|
||||
@@ -743,8 +770,16 @@ class RideDetailAPIView(APIView):
|
||||
tags=["Rides"],
|
||||
)
|
||||
class FilterOptionsAPIView(APIView):
|
||||
"""
|
||||
API View for ride filter options.
|
||||
|
||||
Caching: 30-minute timeout (1800s) - filter options change rarely
|
||||
and are expensive to compute.
|
||||
"""
|
||||
|
||||
permission_classes = [permissions.AllowAny]
|
||||
|
||||
@cache_api_response(timeout=1800, key_prefix="ride_filter_options")
|
||||
def get(self, request: Request) -> Response:
|
||||
"""Return comprehensive filter options with Rich Choice Objects metadata."""
|
||||
# Import Rich Choice registry
|
||||
@@ -1733,8 +1768,13 @@ class FilterOptionsAPIView(APIView):
|
||||
tags=["Rides"],
|
||||
)
|
||||
class CompanySearchAPIView(APIView):
|
||||
"""
|
||||
Caching: 10-minute timeout (600s) - company data is stable.
|
||||
"""
|
||||
|
||||
permission_classes = [permissions.AllowAny]
|
||||
|
||||
@cache_api_response(timeout=600, key_prefix="company_search")
|
||||
def get(self, request: Request) -> Response:
|
||||
q = request.query_params.get("q", "")
|
||||
if not q:
|
||||
@@ -1767,8 +1807,13 @@ class CompanySearchAPIView(APIView):
|
||||
tags=["Rides"],
|
||||
)
|
||||
class RideModelSearchAPIView(APIView):
|
||||
"""
|
||||
Caching: 10-minute timeout (600s) - ride model data is stable.
|
||||
"""
|
||||
|
||||
permission_classes = [permissions.AllowAny]
|
||||
|
||||
@cache_api_response(timeout=600, key_prefix="ride_model_search")
|
||||
def get(self, request: Request) -> Response:
|
||||
q = request.query_params.get("q", "")
|
||||
if not q:
|
||||
@@ -1805,8 +1850,13 @@ class RideModelSearchAPIView(APIView):
|
||||
tags=["Rides"],
|
||||
)
|
||||
class RideSearchSuggestionsAPIView(APIView):
|
||||
"""
|
||||
Caching: 5-minute timeout (300s) - suggestions should be relatively fresh.
|
||||
"""
|
||||
|
||||
permission_classes = [permissions.AllowAny]
|
||||
|
||||
@cache_api_response(timeout=300, key_prefix="ride_suggestions")
|
||||
def get(self, request: Request) -> Response:
|
||||
q = request.query_params.get("q", "")
|
||||
if not q:
|
||||
@@ -2048,10 +2098,14 @@ class HybridRideAPIView(APIView):
|
||||
Automatically chooses between client-side and server-side filtering
|
||||
based on data size and complexity. Provides progressive loading
|
||||
for large datasets and complete data for smaller sets.
|
||||
|
||||
Caching: 10-minute timeout (600s) - ride lists are frequently queried
|
||||
but need to reflect new additions within reasonable time.
|
||||
"""
|
||||
|
||||
permission_classes = [permissions.AllowAny]
|
||||
|
||||
@cache_api_response(timeout=600, key_prefix="hybrid_rides")
|
||||
def get(self, request):
|
||||
"""Get rides with hybrid filtering strategy."""
|
||||
try:
|
||||
@@ -2367,10 +2421,14 @@ class RideFilterMetadataAPIView(APIView):
|
||||
|
||||
Provides information about available filter options and ranges
|
||||
to help build dynamic filter interfaces.
|
||||
|
||||
Caching: 30-minute timeout (1800s) - filter metadata is stable
|
||||
and only changes when new entities are added.
|
||||
"""
|
||||
|
||||
permission_classes = [permissions.AllowAny]
|
||||
|
||||
@cache_api_response(timeout=1800, key_prefix="ride_filter_metadata")
|
||||
def get(self, request):
|
||||
"""Get ride filter metadata."""
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user