feat: Implement MFA authentication, add ride statistics model, and update various services, APIs, and tests across the application.

This commit is contained in:
pacnpal
2025-12-28 17:32:53 -05:00
parent aa56c46c27
commit c95f99ca10
452 changed files with 7948 additions and 6073 deletions

View File

@@ -11,17 +11,17 @@ This file exposes comprehensive endpoints for ride model management:
from django.urls import path
from .views import (
RideModelListCreateAPIView,
RideModelDetailAPIView,
RideModelSearchAPIView,
RideModelFilterOptionsAPIView,
RideModelStatsAPIView,
RideModelVariantListCreateAPIView,
RideModelVariantDetailAPIView,
RideModelTechnicalSpecListCreateAPIView,
RideModelTechnicalSpecDetailAPIView,
RideModelPhotoListCreateAPIView,
RideModelListCreateAPIView,
RideModelPhotoDetailAPIView,
RideModelPhotoListCreateAPIView,
RideModelSearchAPIView,
RideModelStatsAPIView,
RideModelTechnicalSpecDetailAPIView,
RideModelTechnicalSpecListCreateAPIView,
RideModelVariantDetailAPIView,
RideModelVariantListCreateAPIView,
)
app_name = "api_v1_ride_models"

View File

@@ -12,40 +12,40 @@ This module implements comprehensive endpoints for ride model management:
- Photos: CRUD operations for ride model photos
"""
from typing import Any
from datetime import timedelta
from typing import Any
from rest_framework import status, permissions
from rest_framework.views import APIView
from django.db.models import Count, Q
from django.utils import timezone
from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiParameter, extend_schema
from rest_framework import permissions, status
from rest_framework.exceptions import NotFound, ValidationError
from rest_framework.pagination import PageNumberPagination
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.pagination import PageNumberPagination
from rest_framework.exceptions import NotFound, ValidationError
from drf_spectacular.utils import extend_schema, OpenApiParameter
from drf_spectacular.types import OpenApiTypes
from django.db.models import Q, Count
from django.utils import timezone
from rest_framework.views import APIView
# Import serializers
from apps.api.v1.serializers.ride_models import (
RideModelListOutputSerializer,
RideModelDetailOutputSerializer,
RideModelCreateInputSerializer,
RideModelUpdateInputSerializer,
RideModelDetailOutputSerializer,
RideModelFilterInputSerializer,
RideModelVariantOutputSerializer,
RideModelVariantCreateInputSerializer,
RideModelVariantUpdateInputSerializer,
RideModelListOutputSerializer,
RideModelStatsOutputSerializer,
RideModelUpdateInputSerializer,
RideModelVariantCreateInputSerializer,
RideModelVariantOutputSerializer,
RideModelVariantUpdateInputSerializer,
)
# Attempt to import models; fall back gracefully if not present
try:
from apps.rides.models import (
RideModel,
RideModelVariant,
RideModelPhoto,
RideModelTechnicalSpec,
RideModelVariant,
)
from apps.rides.models.company import Company
@@ -54,12 +54,12 @@ except ImportError:
try:
# Try alternative import path
from apps.rides.models.rides import (
Company,
RideModel,
RideModelVariant,
RideModelPhoto,
RideModelTechnicalSpec,
RideModelVariant,
)
from apps.rides.models.rides import Company
MODELS_AVAILABLE = True
except ImportError:
@@ -486,14 +486,14 @@ class RideModelFilterOptionsAPIView(APIView):
"""Return filter options for ride models with Rich Choice Objects metadata."""
# Import Rich Choice registry
from apps.core.choices.registry import get_choices
if not MODELS_AVAILABLE:
# Use Rich Choice Objects for fallback options
try:
# Get rich choice objects from registry
categories = get_choices('categories', 'rides')
target_markets = get_choices('target_markets', 'rides')
# Convert Rich Choice Objects to frontend format with metadata
categories_data = [
{
@@ -507,7 +507,7 @@ class RideModelFilterOptionsAPIView(APIView):
}
for choice in categories
]
target_markets_data = [
{
"value": choice.value,
@@ -520,7 +520,7 @@ class RideModelFilterOptionsAPIView(APIView):
}
for choice in target_markets
]
except Exception:
# Ultimate fallback with basic structure
categories_data = [
@@ -538,7 +538,7 @@ class RideModelFilterOptionsAPIView(APIView):
{"value": "KIDDIE", "label": "Kiddie", "description": "Designed for young children", "color": "pink", "icon": "kiddie", "css_class": "bg-pink-100 text-pink-800", "sort_order": 4},
{"value": "ALL_AGES", "label": "All Ages", "description": "Enjoyable for all age groups", "color": "blue", "icon": "all-ages", "css_class": "bg-blue-100 text-blue-800", "sort_order": 5},
]
return Response({
"categories": categories_data,
"target_markets": target_markets_data,
@@ -557,11 +557,11 @@ class RideModelFilterOptionsAPIView(APIView):
# Get static choice definitions from Rich Choice Objects (primary source)
# Get dynamic data from database queries
# Get rich choice objects from registry
categories = get_choices('categories', 'rides')
target_markets = get_choices('target_markets', 'rides')
# Convert Rich Choice Objects to frontend format with metadata
categories_data = [
{
@@ -575,7 +575,7 @@ class RideModelFilterOptionsAPIView(APIView):
}
for choice in categories
]
target_markets_data = [
{
"value": choice.value,