From 4f55fe31c83b5c2655c2901d494fac0331cc8cca Mon Sep 17 00:00:00 2001 From: Samir Boulahtit Date: Mon, 19 Jan 2026 18:32:03 +0100 Subject: [PATCH] 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 --- docs/architecture/middleware.md | 87 ++++++++++++-- docs/architecture/multi-platform-cms.md | 64 +++++++++-- docs/architecture/url-routing/overview.md | 72 ++++++++++++ ...rm-cms-architecture-implementation-plan.md | 106 +++++++++++++++--- 4 files changed, 297 insertions(+), 32 deletions(-) diff --git a/docs/architecture/middleware.md b/docs/architecture/middleware.md index fe3fd83e..810ba8e7 100644 --- a/docs/architecture/middleware.md +++ b/docs/architecture/middleware.md @@ -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 = +``` + +**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) | diff --git a/docs/architecture/multi-platform-cms.md b/docs/architecture/multi-platform-cms.md index 9e996694..e45ebb52 100644 --- a/docs/architecture/multi-platform-cms.md +++ b/docs/architecture/multi-platform-cms.md @@ -113,13 +113,29 @@ ALTER TABLE content_pages ADD COLUMN is_platform_page BOOLEAN DEFAULT FALSE; ## Request Flow +### URL Routing Structure + +The system uses different URL patterns for development vs production: + +**Development (localhost):** +- Main marketing site: `localhost:9999/` (no prefix) → `main` platform +- Platform sites: `localhost:9999/platforms/{code}/` → specific platform + +**Production (custom domains):** +- Main marketing site: `wizamart.lu/` → `main` platform +- Platform sites: `oms.lu/`, `loyalty.lu/` → specific platform + +### Request Processing + ``` -Request: GET /oms/vendors/shopname/about +Request: GET /platforms/oms/vendors/shopname/about │ ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ PlatformContextMiddleware │ -│ - Detects platform from path prefix (/oms) or domain │ +│ - Detects platform from /platforms/{code}/ prefix or domain │ +│ - Rewrites path: /platforms/oms/vendors/shopname/about │ +│ → /vendors/shopname/about │ │ - Sets request.state.platform = Platform(code='oms') │ │ - Sets request.state.platform_clean_path = /vendors/shopname/about │ └─────────────────────────────────────────────────────────────────────┘ @@ -127,7 +143,7 @@ Request: GET /oms/vendors/shopname/about ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ VendorContextMiddleware │ -│ - Uses platform_clean_path for vendor detection │ +│ - Uses rewritten path for vendor detection │ │ - Sets request.state.vendor = Vendor(subdomain='shopname') │ └─────────────────────────────────────────────────────────────────────┘ │ @@ -142,6 +158,30 @@ Request: GET /oms/vendors/shopname/about └─────────────────────────────────────────────────────────────────────┘ ``` +### Main Marketing Site (No Platform Prefix) + +For requests without the `/platforms/` prefix (e.g., `localhost:9999/about`): + +``` +Request: GET /about + │ + ▼ +┌─────────────────────────────────────────────────────────────────────┐ +│ PlatformContextMiddleware │ +│ - No /platforms/ prefix detected │ +│ - Uses DEFAULT_PLATFORM_CODE = 'main' │ +│ - Sets request.state.platform = Platform(code='main') │ +│ - Path unchanged: /about │ +└─────────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────────┐ +│ Route Handler (platform_pages.py) │ +│ - Gets platform_id from request.state.platform (main) │ +│ - Loads CMS content for main marketing site │ +└─────────────────────────────────────────────────────────────────────┘ +``` + ## Admin Interface ### Platform Management (`/admin/platforms`) @@ -218,8 +258,8 @@ Request: GET /oms/vendors/shopname/about 1. Insert platform record: ```sql - INSERT INTO platforms (code, name, description, path_prefix) - VALUES ('loyalty', 'Loyalty Program', 'Customer loyalty and rewards', '/loyalty'); + INSERT INTO platforms (code, name, description, domain, path_prefix) + VALUES ('loyalty', 'Loyalty Program', 'Customer loyalty and rewards', 'loyalty.lu', 'loyalty'); ``` 2. Create platform-specific content pages: @@ -228,8 +268,10 @@ Request: GET /oms/vendors/shopname/about VALUES (2, 'home', 'Loyalty Program', '

Welcome

', TRUE); ``` -3. Configure routing (if using path prefix): - - Platform detected by `PlatformContextMiddleware` +3. Configure routing: + - **Development:** Access at `localhost:9999/platforms/loyalty/` + - **Production:** Access at `loyalty.lu/` + - Platform detected automatically by `PlatformContextMiddleware` - No additional route configuration needed 4. Assign vendors to platform: @@ -237,3 +279,11 @@ Request: GET /oms/vendors/shopname/about INSERT INTO vendor_platforms (vendor_id, platform_id) VALUES (1, 2); ``` + +### Platform URL Summary + +| Platform | Code | Dev URL | Prod URL | +|----------|------|---------|----------| +| Main Marketing | `main` | `localhost:9999/` | `wizamart.lu/` | +| OMS | `oms` | `localhost:9999/platforms/oms/` | `oms.lu/` | +| Loyalty | `loyalty` | `localhost:9999/platforms/loyalty/` | `loyalty.lu/` | diff --git a/docs/architecture/url-routing/overview.md b/docs/architecture/url-routing/overview.md index 7b3dd5fb..ade01d06 100644 --- a/docs/architecture/url-routing/overview.md +++ b/docs/architecture/url-routing/overview.md @@ -37,6 +37,78 @@ http://localhost:8000/vendors/techpro/shop/checkout --- +## Multi-Platform URL Routing + +Wizamart supports multiple platforms (OMS, Loyalty, Site Builder), each with its own marketing site and vendor ecosystem. + +### Platform URL Structure + +#### Development Mode (localhost) + +| URL | What it serves | +|-----|----------------| +| `/` | Main marketing site homepage (`main` platform) | +| `/about` | Main marketing site about page | +| `/platforms/oms/` | OMS platform homepage | +| `/platforms/oms/pricing` | OMS platform pricing page | +| `/platforms/oms/vendors/{code}/` | Vendor storefront on OMS | +| `/platforms/loyalty/` | Loyalty platform homepage | +| `/platforms/loyalty/features` | Loyalty platform features page | + +#### Production Mode (custom domains) + +| URL | What it serves | +|-----|----------------| +| `wizamart.lu/` | Main marketing site homepage | +| `wizamart.lu/about` | Main marketing site about page | +| `oms.lu/` | OMS platform homepage | +| `oms.lu/pricing` | OMS platform pricing page | +| `oms.lu/vendors/{code}/` | Vendor storefront on OMS | +| `loyalty.lu/` | Loyalty platform homepage | + +### Platform Routing Logic + +``` +Request arrives + │ + ▼ +┌─────────────────────────────────────┐ +│ Check: Is this production domain? │ +│ (oms.lu, loyalty.lu, etc.) │ +└─────────────────────────────────────┘ + │ + ├── YES → Route to that platform + │ + ▼ NO (localhost) +┌─────────────────────────────────────┐ +│ Check: Does path start with │ +│ /platforms/{code}/ ? │ +└─────────────────────────────────────┘ + │ + ├── YES → Strip prefix, route to platform + │ /platforms/oms/pricing → /pricing on OMS + │ + ▼ NO +┌─────────────────────────────────────┐ +│ Route to MAIN MARKETING SITE │ +│ (no platform context) │ +│ /faq → Main site FAQ page │ +└─────────────────────────────────────┘ +``` + +### Platform Codes + +| Platform | Code | Dev URL | Prod Domain | +|----------|------|---------|-------------| +| Main Marketing | `main` | `localhost:9999/` | `wizamart.lu` | +| OMS | `oms` | `localhost:9999/platforms/oms/` | `oms.lu` | +| Loyalty | `loyalty` | `localhost:9999/platforms/loyalty/` | `loyalty.lu` | +| Site Builder | `site-builder` | `localhost:9999/platforms/site-builder/` | `sitebuilder.lu` | + +**See:** [Multi-Platform CMS Architecture](../multi-platform-cms.md) for content management details. + +--- + ## Three Deployment Modes Explained ### 1. SUBDOMAIN MODE (Production - Recommended) diff --git a/docs/proposals/multi-platform-cms-architecture-implementation-plan.md b/docs/proposals/multi-platform-cms-architecture-implementation-plan.md index d36c1061..b7239d2b 100644 --- a/docs/proposals/multi-platform-cms-architecture-implementation-plan.md +++ b/docs/proposals/multi-platform-cms-architecture-implementation-plan.md @@ -1,11 +1,12 @@ # Multi-Platform CMS Architecture - Implementation Plan -> **Status:** All Phases Complete (1-6) +> **Status:** All Phases Complete (1-7) > **Last Updated:** 2026-01-19 > **Commits:** > - `408019d` (Phase 1: Database & Models) > - `9680026` (Phases 2-5: Migration, Admin, Docs, Vendor Dashboard) > - `32bcbc8` (Phase 6: Loyalty Platform Setup) +> - `a2407ae` (Phase 7: Platform URL Routing Strategy) --- @@ -227,18 +228,79 @@ Inserts Loyalty platform with: --- -## Documentation Requirements ✅ PARTIAL +## Phase 7: Platform URL Routing Strategy ✅ COMPLETE + +### 7.1 URL Structure Changes + +**Previous approach (DEPRECATED):** +- Development: `/oms/`, `/loyalty/` (first path segment = platform) +- Ambiguity: `/faq` could be platform or page + +**New approach:** +- Development: `/platforms/oms/`, `/platforms/loyalty/` (explicit prefix) +- Main marketing site: `/` (no prefix) → `main` platform +- Clear separation: `/faq` = main site, `/platforms/oms/faq` = OMS + +### 7.2 Implementation Details + +| Task | File | Status | +|------|------|--------| +| Update middleware URL detection | `middleware/platform_context.py` | ✅ | +| Change DEFAULT_PLATFORM_CODE | `middleware/platform_context.py` | ✅ | +| Remove hardcoded /oms, /loyalty routes | `main.py` | ✅ | +| Update platform_pages.py homepage | `app/routes/platform_pages.py` | ✅ | +| Add 'main' platform migration | `alembic/versions/z6g7h8i9j0k1_...py` | ✅ | + +### 7.3 URL Routing Summary + +| Platform | Code | Dev URL | Prod URL | +|----------|------|---------|----------| +| Main Marketing | `main` | `localhost:9999/` | `wizamart.lu/` | +| OMS | `oms` | `localhost:9999/platforms/oms/` | `oms.lu/` | +| Loyalty | `loyalty` | `localhost:9999/platforms/loyalty/` | `loyalty.lu/` | + +### 7.4 Middleware Detection Logic + +``` +Request arrives + │ + ▼ +┌─────────────────────────────────────┐ +│ Production domain? (oms.lu, etc.) │ +└─────────────────────────────────────┘ + │ YES → Route to that platform + │ + ▼ NO (localhost) +┌─────────────────────────────────────┐ +│ Path starts with /platforms/{code}? │ +└─────────────────────────────────────┘ + │ YES → Strip prefix, route to platform + │ /platforms/oms/pricing → /pricing + │ + ▼ NO +┌─────────────────────────────────────┐ +│ Use 'main' platform (DEFAULT) │ +│ /faq → Main site FAQ page │ +└─────────────────────────────────────┘ +``` + +--- + +## Documentation Requirements ✅ COMPLETE ### Architecture Documentation ✅ COMPLETE -Created `docs/architecture/multi-platform-cms.md`: +Updated documentation for Phase 7: +- [x] `docs/architecture/url-routing/overview.md` - Multi-platform URL routing section +- [x] `docs/architecture/multi-platform-cms.md` - Request flow with path rewriting +- [x] `docs/architecture/middleware.md` - PlatformContextMiddleware documentation - [x] Three-tier content hierarchy explanation - [x] Platform vs Vendor Default vs Vendor Override - [x] Database schema diagrams - [x] Request flow diagrams - [x] API endpoints reference - [x] Key files reference -- [x] Adding new platform guide +- [x] Adding new platform guide with URL summary ### API Documentation @@ -253,6 +315,7 @@ Included in `docs/architecture/multi-platform-cms.md`: - [x] Step-by-step platform creation - [x] Required database records - [x] Key files reference +- [x] Platform URL summary table --- @@ -297,17 +360,34 @@ Customer visits: oms.lu/vendors/wizamart/about --- -## Next Session Checklist +## Verification Checklist -Start here when resuming work: +All phases are complete. Use these commands to verify: -1. [ ] Run `alembic upgrade head` (backup DB first!) -2. [ ] Verify migration: `SELECT * FROM platforms;` -3. [ ] Register PlatformContextMiddleware in `main.py` -4. [ ] Update VendorContextMiddleware to use `platform_clean_path` -5. [ ] Fix platform homepage to use CMS -6. [ ] Test: `localhost:9999/oms/` shows CMS homepage -7. [ ] Test: Three-tier resolution works +```bash +# 1. Check platforms in database +psql -d wizamart -c "SELECT code, name, domain FROM platforms;" +# Expected: main, oms, loyalty + +# 2. Test main marketing site +curl -s localhost:9999/ | grep -o ".*" +# Expected: Main marketing site title + +# 3. Test OMS platform +curl -s localhost:9999/platforms/oms/ | grep -o ".*" +# Expected: OMS platform title + +# 4. Test Loyalty platform +curl -s localhost:9999/platforms/loyalty/ | grep -o ".*" +# Expected: Loyalty platform title + +# 5. Verify middleware detection +python -c " +from middleware.platform_context import PlatformContextMiddleware, DEFAULT_PLATFORM_CODE +print(f'DEFAULT_PLATFORM_CODE: {DEFAULT_PLATFORM_CODE}') +# Expected: main +" +``` ---