refactor: centralize frontend detection with FrontendDetector

Major architecture change to unify frontend detection:

## Problem Solved
- Eliminated code duplication across 3 middleware files
- Fixed incomplete path detection (now detects /api/v1/admin/*)
- Unified on FrontendType enum (deprecates RequestContext)
- Added request.state.frontend_type for all requests

## New Components
- app/core/frontend_detector.py: Centralized FrontendDetector class
- middleware/frontend_type.py: FrontendTypeMiddleware (replaces ContextMiddleware)
- docs/architecture/frontend-detection.md: Complete architecture documentation

## Changes
- main.py: Use FrontendTypeMiddleware instead of ContextMiddleware
- middleware/context.py: Deprecated (kept for backwards compatibility)
- middleware/platform_context.py: Use FrontendDetector.is_admin()
- middleware/vendor_context.py: Use FrontendDetector.is_admin()
- middleware/language.py: Use FrontendType instead of context_value
- app/exceptions/handler.py: Use FrontendType.STOREFRONT
- app/exceptions/error_renderer.py: Use FrontendType
- Customer routes: Cookie path changed from /shop to /storefront

## Documentation
- docs/architecture/frontend-detection.md: New comprehensive docs
- docs/architecture/middleware.md: Updated for new system
- docs/architecture/request-flow.md: Updated for FrontendType
- docs/backend/middleware-reference.md: Updated API reference

## Tests
- tests/unit/core/test_frontend_detector.py: 37 new tests
- tests/unit/middleware/test_frontend_type.py: 11 new tests
- tests/unit/middleware/test_context.py: Updated for compatibility

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-03 16:15:19 +01:00
parent e77535e2cd
commit b769f5a047
17 changed files with 1393 additions and 915 deletions

16
main.py
View File

@@ -69,7 +69,7 @@ from app.modules.routes import (
get_vendor_page_routes,
)
from app.utils.i18n import get_jinja2_globals
from middleware.context import ContextMiddleware
from middleware.frontend_type import FrontendTypeMiddleware
from middleware.language import LanguageMiddleware
from middleware.logging import LoggingMiddleware
from middleware.theme_context import ThemeContextMiddleware
@@ -122,15 +122,15 @@ app.add_middleware(
# Desired execution order:
# 1. PlatformContextMiddleware (detect platform from domain/path)
# 2. VendorContextMiddleware (detect vendor, uses platform_clean_path)
# 3. ContextMiddleware (detect context using clean_path)
# 4. LanguageMiddleware (detect language based on context)
# 3. FrontendTypeMiddleware (detect frontend type using FrontendDetector)
# 4. LanguageMiddleware (detect language based on frontend type)
# 5. ThemeContextMiddleware (load theme)
# 6. LoggingMiddleware (log all requests)
#
# Therefore we add them in REVERSE:
# - Add ThemeContextMiddleware FIRST (runs LAST in request)
# - Add LanguageMiddleware SECOND
# - Add ContextMiddleware THIRD
# - Add FrontendTypeMiddleware THIRD
# - Add VendorContextMiddleware FOURTH
# - Add PlatformContextMiddleware FIFTH
# - Add LoggingMiddleware LAST (runs FIRST for timing)
@@ -152,9 +152,9 @@ app.add_middleware(ThemeContextMiddleware)
logger.info("Adding LanguageMiddleware (detects language based on context)")
app.add_middleware(LanguageMiddleware)
# Add context detection middleware (runs after vendor context extraction)
logger.info("Adding ContextMiddleware (detects context type using clean_path)")
app.add_middleware(ContextMiddleware)
# Add frontend type detection middleware (runs after vendor context extraction)
logger.info("Adding FrontendTypeMiddleware (detects frontend type using FrontendDetector)")
app.add_middleware(FrontendTypeMiddleware)
# Add vendor context middleware (runs after platform context)
logger.info("Adding VendorContextMiddleware (detects vendor, uses platform_clean_path)")
@@ -170,7 +170,7 @@ logger.info(" Execution order (request →):")
logger.info(" 1. LoggingMiddleware (timing)")
logger.info(" 2. PlatformContextMiddleware (platform detection)")
logger.info(" 3. VendorContextMiddleware (vendor detection)")
logger.info(" 4. ContextMiddleware (context detection)")
logger.info(" 4. FrontendTypeMiddleware (frontend type detection)")
logger.info(" 5. LanguageMiddleware (language detection)")
logger.info(" 6. ThemeContextMiddleware (theme loading)")
logger.info(" 7. FastAPI Router")