import os from typing import Any from django.conf import settings from django.conf.urls.static import static from django.contrib import admin from django.urls import include, path from django.views.generic import TemplateView from django.views.static import serve from apps.accounts import views as accounts_views from . import views from .views import HomeView # Import API documentation views # Ensure names are always defined for static analyzers / type checkers. # Annotate as Any so static analysis won't complain that they might be None SpectacularAPIView: Any = None SpectacularSwaggerView: Any = None SpectacularRedocView: Any = None try: from drf_spectacular.views import ( SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView, ) HAS_SPECTACULAR = True except ImportError: HAS_SPECTACULAR = False # Health check views are now consolidated in the API v1 HAS_HEALTH_VIEWS = False # Import autocomplete URLs try: from autocomplete import urls as autocomplete_urls HAS_AUTOCOMPLETE = True except ImportError: autocomplete_urls = None HAS_AUTOCOMPLETE = False # Build URL patterns list dynamically urlpatterns = [ path("admin/", admin.site.urls), # Main app URLs path("", HomeView.as_view(), name="home"), # Health Check URLs path("health/", include("health_check.urls")), # Centralized API URLs - routes through main API router path("api/", include("apps.api.urls")), # All API endpoints are now consolidated under /api/v1/ # Parks and Rides URLs path("parks/", include("apps.parks.urls", namespace="parks")), # Global rides URLs path("rides/", include("apps.rides.urls", namespace="rides")), # Operators URLs path("operators/", include("apps.parks.urls", namespace="operators")), # Note: Photo URLs handled through domain-specific APIs at /api/v1/parks/ and /api/v1/rides/ # Legacy photo namespace removed - functionality moved to domain-specific APIs path("search/", include("apps.core.urls.search", namespace="search")), path("maps/", include("apps.core.urls.maps", namespace="maps")), # Map HTML views path( "terms/", TemplateView.as_view(template_name="pages/terms.html"), name="terms", ), path( "privacy/", TemplateView.as_view(template_name="pages/privacy.html"), name="privacy", ), # Custom authentication URLs first (to override allauth defaults) path("accounts/", include("apps.accounts.urls")), # Default allauth URLs (for social auth and other features) path("accounts/", include("allauth.urls")), path( "accounts/email-required/", accounts_views.email_required, name="email_required", ), # User profile URLs path( "user//", accounts_views.ProfileView.as_view(), name="user_profile", ), path( "profile//", accounts_views.ProfileView.as_view(), name="profile", ), path("settings/", accounts_views.SettingsView.as_view(), name="settings"), # Redirect /user/ to the user's profile if logged in path("user/", accounts_views.user_redirect_view, name="user_redirect"), # Moderation URLs - placed after other URLs but before static/media serving path("moderation/", include("apps.moderation.urls", namespace="moderation")), # Core app URLs (FSM transitions, entity search) path("core/", include("apps.core.urls", namespace="core")), path( "env-settings/", views.environment_and_settings_view, name="environment_and_settings", ), ] # Add autocomplete URLs if available if HAS_AUTOCOMPLETE and autocomplete_urls: urlpatterns.insert( 2, path("ac/", include(autocomplete_urls[:2], namespace=autocomplete_urls[2])), ) # Add API Documentation URLs if available if HAS_SPECTACULAR: urlpatterns.extend( [ path("api/schema/", SpectacularAPIView.as_view(), name="schema"), path( "api/docs/", SpectacularSwaggerView.as_view(url_name="schema"), name="swagger-ui", ), path( "api/redoc/", SpectacularRedocView.as_view(url_name="schema"), name="redoc", ), ] ) else: # Do not add API documentation URLs if drf_spectacular is not installed pass # Health check API endpoints are now available at /api/v1/health/ # Serve static files in development if settings.DEBUG: # Only serve static files, not media files since we're using Cloudflare Images urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) # Design system test page (development only) urlpatterns += [ path( "design-system-test/", TemplateView.as_view(template_name="tests/design-system-test.html"), name="design_system_test", ), ] # Note: Media files are handled by Cloudflare Images, not Django static serving # This prevents the catch-all pattern from interfering with API routes # Silk has been disabled for performance # urlpatterns += [path("silk/", include("silk.urls", namespace="silk"))] # Serve test coverage reports in development coverage_dir = os.path.join(settings.BASE_DIR, "tests", "coverage_html") if os.path.exists(coverage_dir): urlpatterns += [ path( "coverage/", serve, {"document_root": coverage_dir, "path": "index.html"}, ), path( "coverage/", serve, { "document_root": coverage_dir, }, ), ] handler404 = "thrillwiki.views.handler404" handler500 = "thrillwiki.views.handler500"