Files
orion/docs/backend/middleware-reference.md
Samir Boulahtit b769f5a047 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>
2026-02-03 16:15:19 +01:00

9.2 KiB

API Reference

Complete technical reference for all middleware components, utilities, and core classes.

Overview

This reference provides detailed API documentation for all internal modules and classes. All documentation is auto-generated from source code docstrings.


Authentication & Authorization

AuthManager

The core authentication manager handling JWT tokens, password hashing, and role-based access control.

::: middleware.auth.AuthManager options: show_source: false heading_level: 4 show_root_heading: false show_root_toc_entry: false members: - init - hash_password - verify_password - authenticate_user - create_access_token - verify_token - get_current_user - require_role - require_admin - require_vendor - require_customer - create_default_admin_user


Multi-Tenant Context Management

VendorContextManager

Detects and manages vendor context from custom domains, subdomains, or path-based routing. This is the foundation of the multi-tenant system.

Key Features:

  • Custom domain routing (customdomain.com → Vendor)
  • Subdomain routing (vendor1.platform.com → Vendor)
  • Path-based routing (/vendor/vendor1/ → Vendor)
  • Clean path extraction for nested routing

::: middleware.vendor_context.VendorContextManager options: show_source: false heading_level: 4 show_root_heading: false

VendorContextMiddleware

ASGI middleware that wraps VendorContextManager for FastAPI integration.

::: middleware.vendor_context.VendorContextMiddleware options: show_source: false heading_level: 4 show_root_heading: false


Frontend Type Detection

FrontendType

Enum defining all possible frontend types in the application.

::: app.modules.enums.FrontendType options: show_source: false heading_level: 4 show_root_heading: false members: - PLATFORM - ADMIN - VENDOR - STOREFRONT

FrontendDetector

Centralized class for detecting which frontend a request targets based on URL patterns.

Detection Rules (Priority Order):

  1. Admin subdomain (admin.*) → ADMIN
  2. Path-based detection:
    • /admin/*, /api/v1/admin/* → ADMIN
    • /vendor/*, /api/v1/vendor/* → VENDOR
    • /storefront/*, /shop/*, /vendors/* → STOREFRONT
    • /api/v1/platform/* → PLATFORM
  3. Vendor subdomain → STOREFRONT
  4. Vendor context set → STOREFRONT
  5. Default → PLATFORM

::: app.core.frontend_detector.FrontendDetector options: show_source: false heading_level: 4 show_root_heading: false

FrontendTypeMiddleware

ASGI middleware for frontend type detection. Must run AFTER VendorContextMiddleware.

::: middleware.frontend_type.FrontendTypeMiddleware options: show_source: false heading_level: 4 show_root_heading: false

Note

: The old RequestContext enum and ContextMiddleware are deprecated. See Frontend Detection Architecture for migration guide.


Theme Management

ThemeContextManager

Manages vendor-specific theme configuration and injection into request context.

::: middleware.theme_context.ThemeContextManager options: show_source: false heading_level: 4 show_root_heading: false

ThemeContextMiddleware

ASGI middleware for theme injection. Must run AFTER ContextDetectionMiddleware.

::: middleware.theme_context.ThemeContextMiddleware options: show_source: false heading_level: 4 show_root_heading: false


Rate Limiting

RateLimiter

In-memory rate limiter using a sliding window algorithm for request throttling.

Features:

  • Sliding window algorithm for accurate rate limiting
  • Per-client tracking
  • Automatic cleanup of old entries
  • Configurable limits and time windows

::: middleware.rate_limiter.RateLimiter options: show_source: false heading_level: 4 show_root_heading: false

Rate Limiting Decorator

Decorator for applying rate limits to FastAPI endpoints.

::: middleware.decorators.rate_limit options: show_source: true heading_level: 4 show_root_heading: false

Usage Example:

from middleware.decorators import rate_limit

@app.post("/api/v1/resource")
@rate_limit(max_requests=10, window_seconds=60)
async def create_resource():
    return {"status": "created"}

Logging & Monitoring

LoggingMiddleware

Middleware for request/response logging and performance monitoring.

Logged Information:

  • Request method, path, and client IP
  • Response status code
  • Request processing time
  • Errors and exceptions

Added Headers:

  • X-Process-Time: Request processing duration in seconds

::: middleware.logging.LoggingMiddleware options: show_source: false heading_level: 4 show_root_heading: false


Path-Based Routing Solution

Modern Approach: Double Router Mounting

Instead of using middleware to rewrite paths, the application registers shop routes twice with different prefixes:

# In main.py
app.include_router(shop_pages.router, prefix="/shop")
app.include_router(shop_pages.router, prefix="/vendors/{vendor_code}/shop")

How It Works:

  • Subdomain/Custom Domain Mode: Routes match /shop/* prefix
  • Path-Based Development Mode: Routes match /vendors/{vendor_code}/shop/* prefix
  • FastAPI handles routing naturally without path manipulation
  • Vendor code is available as a path parameter when needed

Benefits:

  • No middleware complexity
  • Explicit route definitions
  • FastAPI native routing
  • Vendor code accessible via path parameter

Note: Previous implementations used path_rewrite_middleware to rewrite paths at runtime. This approach has been deprecated in favor of double mounting, which is simpler and more maintainable.


Middleware Execution Order

The middleware stack must be configured in the correct order for proper functionality:

graph TD
    A[Request] --> B[LoggingMiddleware]
    B --> C[PlatformContextMiddleware]
    C --> D[VendorContextMiddleware]
    D --> E[FrontendTypeMiddleware]
    E --> F[LanguageMiddleware]
    F --> G[ThemeContextMiddleware]
    G --> H[Application Routes]
    H --> I[Response]

Critical Dependencies:

  1. LoggingMiddleware runs first for request timing
  2. PlatformContextMiddleware detects platform and sets platform context
  3. VendorContextMiddleware detects vendor and sets clean_path
  4. FrontendTypeMiddleware detects frontend type (ADMIN/VENDOR/STOREFRONT/PLATFORM)
  5. LanguageMiddleware resolves language based on frontend type
  6. ThemeContextMiddleware loads vendor theme based on context

Note: Path-based routing (e.g., /vendors/{code}/storefront/*) is handled by double router mounting in main.py, not by middleware.


Request State Variables

Middleware components inject the following variables into request.state:

Variable Set By Type Description
platform PlatformContextMiddleware Platform Current platform object
vendor VendorContextMiddleware Vendor Current vendor object
vendor_id VendorContextMiddleware int Current vendor ID
clean_path VendorContextMiddleware str Path without vendor prefix
frontend_type FrontendTypeMiddleware FrontendType Frontend type (ADMIN/VENDOR/STOREFRONT/PLATFORM)
language LanguageMiddleware str Detected language code
theme ThemeContextMiddleware dict Vendor theme configuration

Usage in Routes:

from fastapi import Request
from app.modules.enums import FrontendType
from middleware.frontend_type import get_frontend_type

@app.get("/storefront/products")
async def get_products(request: Request):
    vendor = request.state.vendor
    frontend_type = get_frontend_type(request)
    theme = request.state.theme

    if frontend_type == FrontendType.STOREFRONT:
        return {"vendor": vendor.name, "frontend": frontend_type.value}

Best Practices

Error Handling

All middleware should properly handle exceptions and log errors for debugging:

try:
    # Middleware logic
except Exception as e:
    logger.error(f"Middleware error: {e}")
    raise

Performance

  • Keep middleware logic minimal and fast
  • Use async/await properly for non-blocking operations
  • Log performance metrics for monitoring

Testing

  • Test middleware in isolation
  • Mock request.state for unit tests
  • Test middleware execution order
  • Verify error handling paths

For testing examples, see the Testing Guide.