╔══════════════════════════════════════════════════════════════════════════════╗
║           WIZAMART MULTI-TENANT URL ROUTING - COMPLETE SUMMARY              ║
╚══════════════════════════════════════════════════════════════════════════════╝

TL;DR
═════════════════════════════════════════════════════════════════════════════

Q: What's the URL for a customer to connect to a vendor's shop in Wizamart?

A: It depends on the deployment mode:

   1. PRODUCTION (Subdomain):    https://vendor-name.wizamart.com/shop/products
   2. PRODUCTION (Custom Domain): https://vendor-domain.com/shop/products
   3. DEVELOPMENT (Path-Based):   http://localhost:8000/vendors/vendor-code/shop/products


THE COMPLETE PICTURE
═════════════════════════════════════════════════════════════════════════════

DEPLOYMENT MODES
────────────────

┌─ Mode 1: SUBDOMAIN ─────────────────────────────┐
│                                                  │
│ URL: https://acme.wizamart.com/shop/products   │
│                                                  │
│ How it works:                                   │
│ 1. Customer visits acme.wizamart.com           │
│ 2. Middleware detects subdomain "acme"         │
│ 3. Queries: vendors WHERE subdomain = 'acme'  │
│ 4. Finds Vendor(id=1, name="ACME Store")       │
│ 5. Loads ACME's theme                          │
│ 6. Renders HTML with ACME's branding           │
│                                                  │
│ Best for: Production, standard vendors          │
│ SSL: *.wizamart.com wildcard cert              │
│ DNS: Add subdomains as needed                  │
└─────────────────────────────────────────────────┘

┌─ Mode 2: CUSTOM DOMAIN ─────────────────────────┐
│                                                  │
│ URL: https://store.acmecorp.com/shop/products │
│                                                  │
│ How it works:                                   │
│ 1. Customer visits store.acmecorp.com          │
│ 2. Middleware detects custom domain            │
│ 3. Queries: vendor_domains WHERE domain = ... │
│ 4. Finds VendorDomain(vendor_id=1)             │
│ 5. Joins to Vendor(id=1)                       │
│ 6. Loads ACME's theme                          │
│ 7. Renders HTML with ACME's branding           │
│                                                  │
│ Best for: Production, premium vendors          │
│ SSL: Vendor's own SSL certificate              │
│ DNS: Vendor configures domain                  │
└─────────────────────────────────────────────────┘

┌─ Mode 3: PATH-BASED ────────────────────────────┐
│                                                  │
│ URL: http://localhost:8000/vendor/acme/shop... │
│                                                  │
│ How it works:                                   │
│ 1. Developer visits localhost:8000/vendor/..   │
│ 2. Middleware detects path-based routing       │
│ 3. Extracts "acme" from path                   │
│ 4. Queries: vendors WHERE subdomain = 'acme'  │
│ 5. Finds Vendor(id=1)                          │
│ 6. Loads ACME's theme                          │
│ 7. Renders HTML with ACME's branding           │
│                                                  │
│ Best for: Local development & testing          │
│ SSL: None needed (localhost)                   │
│ DNS: None needed                                │
└─────────────────────────────────────────────────┘


REQUEST PROCESSING FLOW
═══════════════════════

Customer Request
    ↓
    ├─ vendor_context_middleware
    │  ├─ Detects vendor from host/domain/path
    │  └─ Sets request.state.vendor = Vendor(...)
    ├─ context_middleware
    │  ├─ Detects RequestContext.SHOP
    │  └─ Sets request.state.context_type
    ├─ theme_context_middleware
    │  ├─ Loads vendor theme
    │  └─ Sets request.state.theme
    ↓
    ├─ Route Matching → /shop/products
    ├─ Handler Execution → shop_products_page()
    ├─ Template Rendering → shop/products.html
    │  ├─ Uses vendor.name → "ACME Store"
    │  ├─ Uses theme.colors → "#FF6B6B"
    │  └─ Uses theme.logo → "acme-logo.png"
    ├─ HTML Sent to Browser
    ├─ JavaScript Runs
    ├─ API Call → /api/v1/public/vendors/1/products
    ├─ Backend Returns Products
    ├─ JavaScript Renders with Theme
    ↓
    Response: Fully Branded Shop


VENDOR ISOLATION: 4 LAYERS
════════════════════════════

Layer 1: URL DETECTION
         │
         ├─ Subdomain → extract from host
         ├─ Custom Domain → lookup VendorDomain table
         └─ Path → extract from URL path
         ↓
         Result: Vendor identified

Layer 2: MIDDLEWARE
         │
         └─ request.state.vendor = Vendor(...)
         ↓
         Result: Vendor accessible throughout request

Layer 3: DATABASE QUERIES
         │
         └─ WHERE vendor_id = request.state.vendor.id
         ↓
         Result: ONLY that vendor's data returned

Layer 4: API AUTHORIZATION
         │
         └─ if vendor_id != request.state.vendor.id: raise Exception
         ↓
         Result: Cross-vendor access impossible


ALL SHOP ROUTES
════════════════

PUBLIC ROUTES (No authentication required)
───────────────────────────────────────────
/shop/                          → Homepage / product catalog
/shop/products                  → Product catalog
/shop/products/{id}             → Product detail page
/shop/categories/{slug}         → Category products
/shop/cart                      → Shopping cart
/shop/checkout                  → Checkout process
/shop/search                    → Search results
/shop/about                     → About us page
/shop/contact                   → Contact us page
/shop/faq                       → FAQ page
/shop/privacy                   → Privacy policy
/shop/terms                     → Terms of service

AUTHENTICATION ROUTES
──────────────────────
/shop/account/register          → Customer registration
/shop/account/login             → Customer login
/shop/account/forgot-password   → Password reset

PROTECTED ROUTES (Authentication required)
───────────────────────────────────────────
/shop/account/                  → Account home
/shop/account/dashboard         → Account dashboard
/shop/account/orders            → Order history
/shop/account/orders/{id}       → Order details
/shop/account/profile           → Profile page
/shop/account/addresses         → Address management
/shop/account/wishlist          → Wishlist
/shop/account/settings          → Account settings


COMPLETE REQUEST LIFECYCLE EXAMPLE
═══════════════════════════════════

Scenario: Customer visits https://acme.wizamart.com/shop/products

Step 1: Browser Request
   GET https://acme.wizamart.com/shop/products
   Headers: Host: acme.wizamart.com

Step 2: vendor_context_middleware
   Input: host = "acme.wizamart.com"
   Processing:
     1. Check if custom domain? NO
     2. Check if subdomain? YES
     3. Extract "acme"
     4. Query: vendors WHERE subdomain = 'acme'
   Output: request.state.vendor = Vendor(id=1, name="ACME Store")

Step 3: context_middleware
   Input: path = "/shop/products", request.state.vendor exists
   Processing:
     1. Is /api/*? NO
     2. Is /admin/*? NO
     3. Has vendor? YES
   Output: request.state.context_type = RequestContext.SHOP

Step 4: theme_context_middleware
   Input: request.state.vendor.id = 1
   Processing:
     1. Query: vendor_themes WHERE vendor_id = 1
   Output: request.state.theme = {colors, branding, fonts}

Step 5: Route Matching
   Path: /shop/products
   Matches: GET /shop/products
   Handler: shop_products_page(request)

Step 6: Template Rendering (shop/products.html)
   Variables available:
   - request.state.vendor.name → "ACME Store"
   - request.state.theme.colors.primary → "#FF6B6B"
   - request.state.theme.branding.logo → "acme-logo.png"

Step 7: HTML Response
   <!DOCTYPE html>
   <html>
   <head>
     <style>
       :root {
         --color-primary: #FF6B6B;
         --color-secondary: #FF8787;
       }
     </style>
   </head>
   <body>
     <img src="acme-logo.png" />
     <h1>ACME Store</h1>
     <div id="products"></div>
     <script>
       fetch('/api/v1/public/vendors/1/products')
         .then(r => r.json())
         .then(data => renderProducts(data))
     </script>
   </body>
   </html>

Step 8: Browser Renders
   - JavaScript fetches products via API
   - Products rendered with theme colors
   - User sees fully branded ACME store


KEY DIFFERENCES BETWEEN MODES
═══════════════════════════════

SUBDOMAIN:
  ✓ Easy to manage
  ✓ Single SSL certificate
  ✓ Customers need no setup
  ✗ All on same domain
  ✗ Less professional branding

CUSTOM DOMAIN:
  ✓ Professional branding
  ✓ Vendor's own domain
  ✓ Better for premium vendors
  ✗ Each vendor needs SSL
  ✗ Vendor must configure domain

PATH-BASED:
  ✓ Perfect for development
  ✓ No DNS setup needed
  ✓ Test multiple vendors
  ✗ Not suitable for production
  ✗ All vendors share localhost


AUTHENTICATION
════════════════

Customer Authentication:
  - JWT token in Authorization header (API calls)
  - customer_token cookie (page navigation)
  - Cookie path scoped to /shop (vendor isolation)
  - HttpOnly flag prevents JavaScript access

Example:
  Set-Cookie: customer_token=eyJ...; Path=/shop; HttpOnly; SameSite=Lax


API ENDPOINTS
════════════════

All public endpoints follow this pattern:

GET  /api/v1/public/vendors/{vendor_id}/products
GET  /api/v1/public/vendors/{vendor_id}/products/{product_id}
GET  /api/v1/public/vendors/{vendor_id}/products/search
POST /api/v1/public/vendors/{vendor_id}/cart
...

These work from ANY domain because vendor_id is explicit in the URL.


DATABASE MULTI-TENANT KEYS
════════════════════════════

Every business table has vendor_id:

products
  ├─ id
  ├─ vendor_id  ← Required
  ├─ name
  └─ ...

orders
  ├─ id
  ├─ vendor_id  ← Required
  ├─ customer_id
  └─ ...

reviews
  ├─ id
  ├─ vendor_id  ← Required
  ├─ product_id
  └─ ...

This ensures query filtering at database level.


MIDDLEWARE DETAILS
═══════════════════

File: middleware/vendor_context.py
Purpose: Detect vendor from host/domain/path

Methods:
  - detect_vendor_context()      → Identifies vendor
  - get_vendor_from_context()    → Looks up vendor
  - extract_clean_path()         → Extracts path (dev mode)
  - is_admin_request()           → Checks if admin
  - is_api_request()             → Checks if API
  - is_static_file_request()     → Checks if static

File: middleware/theme_context.py
Purpose: Load vendor-specific theme

Methods:
  - get_vendor_theme()           → Loads theme from DB
  - get_default_theme()          → Returns fallback theme

File: middleware/context_middleware.py
Purpose: Determine request context type

Types:
  - RequestContext.API           → /api/* endpoints
  - RequestContext.ADMIN         → /admin/* endpoints
  - RequestContext.VENDOR_DASHBOARD → /vendor/* endpoints
  - RequestContext.SHOP          → Customer shop
  - RequestContext.FALLBACK      → Unknown

File: middleware/logging_middleware.py
Purpose: Log all requests and responses


DEBUGGING TIPS
═════════════

Check Vendor Detection:
  {{ request.state.vendor.name }}
  {{ request.state.vendor.subdomain }}

Check Theme Loading:
  {{ request.state.theme.colors.primary }}
  {{ request.state.theme.branding.logo }}

Check Context Type:
  {{ request.state.context_type }}

Server Logs:
  [OK] Vendor found via subdomain: acme -> ACME Store
  [WARNING] Vendor not found for context: {...}

Test with curl:
  curl -H "Host: acme.wizamart.com" http://localhost:8000/shop/products


POTENTIAL ISSUES
═════════════════

Issue 1: Path-Based Routing Not Working
  Problem: /vendor/acme/shop/products → 404
  Cause: clean_path set but not used for routing
  Solution: Add path rewriting middleware or dual route registration

Issue 2: Theme Not Loading
  Problem: Products show without vendor theme
  Cause: VendorTheme not created for vendor
  Solution: Create VendorTheme in database or create default

Issue 3: Cross-Vendor Data Leakage
  Problem: Customers can see other vendors' products
  Cause: Missing vendor_id WHERE clause
  Solution: Ensure all queries include vendor_id filter

Issue 4: Authentication Confusion
  Problem: Tokens work across vendors
  Cause: No cookie path isolation
  Solution: Ensure cookie path is /shop per deployment


SECURITY BEST PRACTICES
═════════════════════════

✓ DO:
  - Filter every database query by vendor_id
  - Validate vendor_id in all API endpoints
  - Use vendor-scoped authentication cookies
  - Implement multi-layer authorization checks
  - Log all vendor context switches

✗ DON'T:
  - Trust vendor_id from request body alone
  - Skip vendor checks in nested calls
  - Mix vendors in single query
  - Cache data without vendor isolation
  - Assume middleware always runs


DEPLOYMENT CHECKLIST
════════════════════

For Production:
  ☐ Set up DNS with wildcard subdomain (*.wizamart.com)
  ☐ Or allow vendors to add custom domains
  ☐ Configure SSL certificates
  ☐ Set platform_domain in config
  ☐ Create vendors with unique subdomains
  ☐ Create VendorTheme for each vendor
  ☐ Test multi-vendor setup
  ☐ Verify no data leakage
  ☐ Enable logging

For Development:
  ☐ Use localhost:8000 with path-based routing
  ☐ Create test vendors
  ☐ Create test themes
  ☐ Test with multiple vendors
  ☐ Verify middleware detection
  ☐ Check database filters


METRICS TO MONITOR
═══════════════════

  - Request/vendor distribution
  - API latency by vendor
  - Database query performance
  - Middleware execution time
  - Theme loading time
  - Error rates by vendor
  - Authentication failures
  - Cross-vendor access attempts


SCALING CONSIDERATIONS
═══════════════════════

  - Database: Partition by vendor_id if > 10k vendors
  - Cache: Cache themes by vendor_id
  - CDN: Serve static assets globally
  - API Gateway: Route by vendor subdomain
  - Monitoring: Alert on cross-vendor attempts
  - Rate limiting: Per-vendor rate limits


═══════════════════════════════════════════════════════════════════════════════

For more details, see:
  - WIZAMART_MULTITENANT_URL_GUIDE.md    (Complete guide)
  - QUICK_REFERENCE.md                    (Quick reference)
  - ARCHITECTURE_DIAGRAMS.txt             (Visual diagrams)

Generated: November 7, 2025
Version: Current Development
