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

@@ -4,10 +4,11 @@ Following Django styleguide pattern for business logic encapsulation.
"""
import logging
from typing import Optional, Dict, Any, List, TYPE_CHECKING
from typing import TYPE_CHECKING, Any, Optional
from django.core.files.uploadedfile import UploadedFile
from django.db import transaction
from django.db.models import Q
from django.core.files.uploadedfile import UploadedFile
if TYPE_CHECKING:
from django.contrib.auth.models import AbstractUser
@@ -28,14 +29,14 @@ class ParkService:
name: str,
description: str = "",
status: str = "OPERATING",
operator_id: Optional[int] = None,
property_owner_id: Optional[int] = None,
opening_date: Optional[str] = None,
closing_date: Optional[str] = None,
operator_id: int | None = None,
property_owner_id: int | None = None,
opening_date: str | None = None,
closing_date: str | None = None,
operating_season: str = "",
size_acres: Optional[float] = None,
size_acres: float | None = None,
website: str = "",
location_data: Optional[Dict[str, Any]] = None,
location_data: dict[str, Any] | None = None,
created_by: Optional["AbstractUser"] = None,
) -> Park:
"""
@@ -99,7 +100,7 @@ class ParkService:
def update_park(
*,
park_id: int,
updates: Dict[str, Any],
updates: dict[str, Any],
updated_by: Optional["AbstractUser"] = None,
) -> Park:
"""
@@ -203,9 +204,10 @@ class ParkService:
Returns:
Updated Park instance with fresh statistics
"""
from apps.rides.models import Ride
from django.db.models import Avg, Count
from apps.parks.models import ParkReview
from django.db.models import Count, Avg
from apps.rides.models import Ride
with transaction.atomic():
park = Park.objects.select_for_update().get(id=park_id)
@@ -235,11 +237,11 @@ class ParkService:
@staticmethod
def create_park_with_moderation(
*,
changes: Dict[str, Any],
changes: dict[str, Any],
submitter: "AbstractUser",
reason: str = "",
source: str = "",
) -> Dict[str, Any]:
) -> dict[str, Any]:
"""
Create a park through the moderation system.
@@ -267,11 +269,11 @@ class ParkService:
def update_park_with_moderation(
*,
park: Park,
changes: Dict[str, Any],
changes: dict[str, Any],
submitter: "AbstractUser",
reason: str = "",
source: str = "",
) -> Dict[str, Any]:
) -> dict[str, Any]:
"""
Update a park through the moderation system.
@@ -300,14 +302,14 @@ class ParkService:
def create_or_update_location(
*,
park: Park,
latitude: Optional[float],
longitude: Optional[float],
latitude: float | None,
longitude: float | None,
street_address: str = "",
city: str = "",
state: str = "",
country: str = "USA",
postal_code: str = "",
) -> Optional[ParkLocation]:
) -> ParkLocation | None:
"""
Create or update a park's location.
@@ -356,9 +358,9 @@ class ParkService:
def upload_photos(
*,
park: Park,
photos: List[UploadedFile],
photos: list[UploadedFile],
uploaded_by: "AbstractUser",
) -> Dict[str, Any]:
) -> dict[str, Any]:
"""
Upload multiple photos for a park.
@@ -370,10 +372,9 @@ class ParkService:
Returns:
Dictionary with uploaded_count and errors list
"""
from django.contrib.contenttypes.models import ContentType
uploaded_count = 0
errors: List[str] = []
errors: list[str] = []
for photo_file in photos:
try:
@@ -396,11 +397,11 @@ class ParkService:
@staticmethod
def handle_park_creation_result(
*,
result: Dict[str, Any],
form_data: Dict[str, Any],
photos: List[UploadedFile],
result: dict[str, Any],
form_data: dict[str, Any],
photos: list[UploadedFile],
user: "AbstractUser",
) -> Dict[str, Any]:
) -> dict[str, Any]:
"""
Handle the result of park creation through moderation.
@@ -413,7 +414,7 @@ class ParkService:
Returns:
Dictionary with status, park (if created), uploaded_count, and errors
"""
response: Dict[str, Any] = {
response: dict[str, Any] = {
"status": result["status"],
"park": None,
"uploaded_count": 0,
@@ -454,12 +455,12 @@ class ParkService:
@staticmethod
def handle_park_update_result(
*,
result: Dict[str, Any],
result: dict[str, Any],
park: Park,
form_data: Dict[str, Any],
photos: List[UploadedFile],
form_data: dict[str, Any],
photos: list[UploadedFile],
user: "AbstractUser",
) -> Dict[str, Any]:
) -> dict[str, Any]:
"""
Handle the result of park update through moderation.
@@ -473,7 +474,7 @@ class ParkService:
Returns:
Dictionary with status, park, uploaded_count, and errors
"""
response: Dict[str, Any] = {
response: dict[str, Any] = {
"status": result["status"],
"park": park,
"uploaded_count": 0,