docs: update documentation for /platforms/ URL routing strategy
- Add multi-platform URL routing section to url-routing/overview.md - Update multi-platform-cms.md with new request flow diagrams - Add PlatformContextMiddleware documentation to middleware.md - Update middleware execution order diagram - Add Phase 7 (Platform URL Routing Strategy) to implementation plan - Update platform URL summary tables across all docs Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,61 @@ This middleware layer is **system-wide** and enables the multi-tenant architectu
|
||||
|
||||
## Middleware Components
|
||||
|
||||
### 1. Logging Middleware
|
||||
### 1. Platform Context Middleware
|
||||
|
||||
**Purpose**: Detect which platform (OMS, Loyalty, Main) the request is for
|
||||
|
||||
**What it does**:
|
||||
- Detects platform from:
|
||||
- Custom domain (e.g., `oms.lu`, `loyalty.lu`)
|
||||
- Path prefix in development (e.g., `/platforms/oms/`, `/platforms/loyalty/`)
|
||||
- Default to `main` platform for localhost without prefix
|
||||
- Rewrites path for platform-prefixed requests (strips `/platforms/{code}/`)
|
||||
- Queries database to find platform by domain or code
|
||||
- Injects platform object into `request.state.platform`
|
||||
|
||||
**URL Detection Logic**:
|
||||
```
|
||||
Request arrives
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────┐
|
||||
│ Production domain? (oms.lu, etc.) │
|
||||
└─────────────────────────────────────┘
|
||||
│ YES → Use that platform
|
||||
│
|
||||
▼ NO (localhost)
|
||||
┌─────────────────────────────────────┐
|
||||
│ Path starts with /platforms/{code}? │
|
||||
└─────────────────────────────────────┘
|
||||
│ YES → Strip prefix, use platform
|
||||
│ /platforms/oms/pricing → /pricing
|
||||
│
|
||||
▼ NO
|
||||
┌─────────────────────────────────────┐
|
||||
│ Use 'main' platform (DEFAULT) │
|
||||
│ Path unchanged │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Example**:
|
||||
```
|
||||
Request: https://localhost:9999/platforms/oms/pricing
|
||||
↓
|
||||
Middleware detects: platform_code = "oms"
|
||||
↓
|
||||
Rewrites path: /platforms/oms/pricing → /pricing
|
||||
↓
|
||||
Queries database: SELECT * FROM platforms WHERE code = 'oms'
|
||||
↓
|
||||
Injects: request.state.platform = <Platform object>
|
||||
```
|
||||
|
||||
**Why it's critical**: Without this, the system wouldn't know which platform's content to serve
|
||||
|
||||
**Configuration**: Runs BEFORE VendorContextMiddleware (sets platform context first)
|
||||
|
||||
### 2. Logging Middleware
|
||||
|
||||
**Purpose**: Request/response logging and performance monitoring
|
||||
|
||||
@@ -221,13 +275,14 @@ from middleware import context_middleware
|
||||
```mermaid
|
||||
graph TD
|
||||
A[Client Request] --> B[1. LoggingMiddleware]
|
||||
B --> C[2. VendorContextMiddleware]
|
||||
C --> D[3. ContextDetectionMiddleware]
|
||||
D --> E[4. ThemeContextMiddleware]
|
||||
E --> F[5. FastAPI Router]
|
||||
F --> G[Route Handler]
|
||||
G --> H[Response]
|
||||
H --> I[Client]
|
||||
B --> C[2. PlatformContextMiddleware]
|
||||
C --> D[3. VendorContextMiddleware]
|
||||
D --> E[4. ContextDetectionMiddleware]
|
||||
E --> F[5. ThemeContextMiddleware]
|
||||
F --> G[6. FastAPI Router]
|
||||
G --> H[Route Handler]
|
||||
H --> I[Response]
|
||||
I --> J[Client]
|
||||
```
|
||||
|
||||
### Why This Order Matters
|
||||
@@ -238,21 +293,27 @@ graph TD
|
||||
- Needs to wrap everything to measure total time
|
||||
- Must log errors from all other middleware
|
||||
|
||||
2. **VendorContextMiddleware second**
|
||||
2. **PlatformContextMiddleware second**
|
||||
- Must run before VendorContextMiddleware (sets platform context)
|
||||
- Rewrites path for `/platforms/{code}/` prefixed requests
|
||||
- Sets `request.state.platform` for downstream middleware
|
||||
|
||||
3. **VendorContextMiddleware third**
|
||||
- Uses rewritten path from PlatformContextMiddleware
|
||||
- Must run before ContextDetectionMiddleware (provides vendor and clean_path)
|
||||
- Must run before ThemeContextMiddleware (provides vendor_id)
|
||||
|
||||
3. **ContextDetectionMiddleware third**
|
||||
4. **ContextDetectionMiddleware fourth**
|
||||
- Uses clean_path from VendorContextMiddleware
|
||||
- Provides context_type for ThemeContextMiddleware
|
||||
|
||||
4. **ThemeContextMiddleware last**
|
||||
5. **ThemeContextMiddleware last**
|
||||
- Depends on vendor from VendorContextMiddleware
|
||||
- Depends on context_type from ContextDetectionMiddleware
|
||||
|
||||
**Breaking this order will break the application!**
|
||||
|
||||
**Note:** Path-based routing (e.g., `/vendors/{code}/shop/*`) is handled by double router mounting in `main.py`, not by middleware.
|
||||
**Note:** Path-based routing (e.g., `/vendors/{code}/shop/*`) is handled by double router mounting in `main.py`, not by middleware. Platform path-based routing (e.g., `/platforms/oms/`) IS handled by PlatformContextMiddleware which rewrites the path.
|
||||
|
||||
## Request State Variables
|
||||
|
||||
@@ -260,6 +321,8 @@ Middleware components inject these variables into `request.state`:
|
||||
|
||||
| Variable | Set By | Type | Used By | Description |
|
||||
|----------|--------|------|---------|-------------|
|
||||
| `platform` | PlatformContextMiddleware | Platform | Routes, Content | Current platform object (main, oms, loyalty) |
|
||||
| `platform_context` | PlatformContextMiddleware | dict | Routes | Platform detection details (method, paths) |
|
||||
| `vendor` | VendorContextMiddleware | Vendor | Theme, Templates | Current vendor object |
|
||||
| `vendor_id` | VendorContextMiddleware | int | Queries, Theme | Current vendor ID |
|
||||
| `clean_path` | VendorContextMiddleware | str | Context | Path without vendor prefix (for context detection) |
|
||||
|
||||
Reference in New Issue
Block a user