diff --git a/docs/api/authentication.md b/docs/api/authentication.md index afae3130..ac852e61 100644 --- a/docs/api/authentication.md +++ b/docs/api/authentication.md @@ -211,6 +211,14 @@ Set-Cookie: vendor_token=; Path=/vendor; HttpOnly; Secure; SameSite=Lax **Purpose:** Product browsing (public), customer accounts, orders, profile management. +**Important - URL Pattern Context:** +The `/shop/*` routes work differently depending on deployment mode: +- **Subdomain Mode** (Production): `https://vendor.platform.com/shop/products` +- **Custom Domain** (Production): `https://customdomain.com/shop/products` +- **Path-Based** (Development): `http://localhost:8000/vendors/{vendor_code}/shop/products` + +In path-based development mode, the full URL includes the vendor code (e.g., `/vendors/acme/shop/products`), but the routes are still defined as `/shop/*` internally. See [URL Routing Guide](../architecture/url-routing/overview.md) for details. + **Access Control:** - **Public Routes** (`/shop/products`, `/shop/cart`, etc.): - ✅ Anyone can access (no authentication) diff --git a/docs/architecture/middleware.md b/docs/architecture/middleware.md index a1ad83f3..dc8d9fa5 100644 --- a/docs/architecture/middleware.md +++ b/docs/architecture/middleware.md @@ -73,9 +73,9 @@ Injects: request.state.vendor = - Rewrites `request.scope['path']` to remove vendor prefix - Allows FastAPI routes to match correctly -**Example**: +**Example** (Path-Based Development Mode): ``` -Original path: /vendor/WIZAMART/shop/products +Original path: /vendors/WIZAMART/shop/products Clean path: /shop/products (set by VendorContextMiddleware) ↓ Path Rewrite Middleware changes request path to: /shop/products diff --git a/docs/architecture/multi-tenant.md b/docs/architecture/multi-tenant.md index 49d587d7..e8b4243a 100644 --- a/docs/architecture/multi-tenant.md +++ b/docs/architecture/multi-tenant.md @@ -8,6 +8,11 @@ The Wizamart platform supports **three deployment modes** for multi-tenancy, all **Key Concept**: One application, multiple isolated vendor shops, each accessible via different URLs. +**Important Distinction:** +- **Vendor Dashboard** (all modes): `/vendor/{code}/*` (singular) - Management interface for vendors +- **Shop Storefront** (path-based only): `/vendors/{code}/shop/*` (plural) - Customer-facing shop +- This naming distinction helps separate administrative routes from public-facing shop routes + ## The Three Routing Modes ### 1. Custom Domain Mode @@ -75,9 +80,9 @@ id | code | name **Example**: ``` -platform.com/vendor/vendor1/shop → Vendor 1 Shop -platform.com/vendor/vendor2/shop → Vendor 2 Shop -platform.com/vendors/vendor3/shop → Vendor 3 Shop (alternative) +platform.com/vendors/vendor1/shop → Vendor 1 Shop +platform.com/vendors/vendor2/shop → Vendor 2 Shop +platform.com/vendors/vendor3/shop → Vendor 3 Shop ``` **How it works**: @@ -86,12 +91,11 @@ platform.com/vendors/vendor3/shop → Vendor 3 Shop (alternative) 3. Path is rewritten for routing 4. All vendors on same domain -**Use Case**: Simplest deployment, single domain certificate +**Use Case**: Development and testing environments only **Path Patterns**: -- `/vendor/{code}/shop/*` - Storefront pages -- `/vendor/{code}/api/*` - API endpoints (if needed) -- `/vendors/{code}/shop/*` - Alternative pattern +- `/vendors/{code}/shop/*` - Storefront pages (correct pattern) +- `/vendor/{code}/*` - Vendor dashboard pages (different context) ## Routing Mode Comparison @@ -142,20 +146,22 @@ def detect_vendor(request): For path-based routing, clean paths are extracted: -**Example 1**: Single vendor prefix -``` -Original: /vendor/WIZAMART/shop/products -Extracted: vendor_code = "WIZAMART" -Clean: /shop/products -``` - -**Example 2**: Plural vendors prefix +**Path-Based Shop Routes** (Development): ``` Original: /vendors/WIZAMART/shop/products Extracted: vendor_code = "WIZAMART" Clean: /shop/products ``` +**Vendor Dashboard Routes** (All environments): +``` +Original: /vendor/WIZAMART/dashboard +Extracted: vendor_code = "WIZAMART" +Clean: /dashboard +``` + +**Note**: The shop storefront uses `/vendors/` (plural) while the vendor dashboard uses `/vendor/` (singular). This distinction helps separate customer-facing shop routes from vendor management routes. + **Why Clean Path?** - FastAPI routes don't include vendor prefix - Routes defined as: `@app.get("/shop/products")` @@ -214,9 +220,9 @@ INSERT INTO vendor_domains (vendor_id, domain) VALUES **URLs**: ``` myplatform.com/admin -myplatform.com/vendor/shop1/shop -myplatform.com/vendor/shop2/shop -myplatform.com/vendor/shop3/shop +myplatform.com/vendors/shop1/shop +myplatform.com/vendors/shop2/shop +myplatform.com/vendors/shop3/shop ``` **Infrastructure**: @@ -266,8 +272,8 @@ shop3.myplatform.com → Vendor 3 shop4.myplatform.com → Vendor 4 # Path-based (free tier) -myplatform.com/vendor/shop5/shop → Vendor 5 -myplatform.com/vendor/shop6/shop → Vendor 6 +myplatform.com/vendors/shop5/shop → Vendor 5 +myplatform.com/vendors/shop6/shop → Vendor 6 ``` **Infrastructure**: @@ -433,7 +439,7 @@ Host: wizamart.myplatform.com **Request**: ```http -GET /vendor/WIZAMART/shop/products HTTP/1.1 +GET /vendors/WIZAMART/shop/products HTTP/1.1 Host: myplatform.com ``` diff --git a/docs/architecture/overview.md b/docs/architecture/overview.md index 103ab1ba..2168a884 100644 --- a/docs/architecture/overview.md +++ b/docs/architecture/overview.md @@ -47,11 +47,11 @@ vendor2.platform.com → Vendor 2 Shop admin.platform.com → Admin Interface ``` -#### Path-Based Mode +#### Path-Based Mode (Development Only) ``` -platform.com/vendor/vendor1/shop → Vendor 1 Shop -platform.com/vendor/vendor2/shop → Vendor 2 Shop -platform.com/admin → Admin Interface +platform.com/vendors/vendor1/shop → Vendor 1 Shop +platform.com/vendors/vendor2/shop → Vendor 2 Shop +platform.com/admin → Admin Interface ``` **See:** [Multi-Tenant System](multi-tenant.md) for detailed implementation diff --git a/docs/architecture/request-flow.md b/docs/architecture/request-flow.md index ff7c6d78..081c5113 100644 --- a/docs/architecture/request-flow.md +++ b/docs/architecture/request-flow.md @@ -121,8 +121,8 @@ request.state.clean_path = "/shop/products" **Example** (Path-Based Mode): ```python -# Input (path-based mode) -original_path = "/vendor/WIZAMART/shop/products" +# Input (path-based development mode) +original_path = "/vendors/WIZAMART/shop/products" clean_path = "/shop/products" # From VendorContextMiddleware # Path rewrite diff --git a/docs/architecture/url-routing/overview.md b/docs/architecture/url-routing/overview.md index d4b0a600..68e91d22 100644 --- a/docs/architecture/url-routing/overview.md +++ b/docs/architecture/url-routing/overview.md @@ -6,6 +6,8 @@ There are three ways depending on the deployment mode: +**⚠️ Important:** This guide describes **customer-facing shop routes**. For vendor dashboard/management routes, see [Vendor Dashboard Documentation](../../vendor/). The shop uses `/vendors/{code}/shop/*` (plural) in path-based mode, while the vendor dashboard uses `/vendor/{code}/*` (singular). + ### 1. **SUBDOMAIN MODE** (Production - Recommended) ``` https://VENDOR_SUBDOMAIN.platform.com/shop/products @@ -26,11 +28,11 @@ https://shop.techpro.io/shop/cart ### 3. **PATH-BASED MODE** (Development Only) ``` -http://localhost:PORT/vendor/VENDOR_CODE/shop/products +http://localhost:PORT/vendors/VENDOR_CODE/shop/products Example: -http://localhost:8000/vendor/acme/shop/products -http://localhost:8000/vendor/techpro/shop/checkout +http://localhost:8000/vendors/acme/shop/products +http://localhost:8000/vendors/techpro/shop/checkout ``` --- @@ -107,15 +109,15 @@ id | vendor_id | domain | is_active | is_verified ### 3. PATH-BASED MODE (Development Only) -**URL Pattern:** `http://localhost:PORT/vendor/VENDOR_CODE/shop/...` +**URL Pattern:** `http://localhost:PORT/vendors/VENDOR_CODE/shop/...` **Example:** -- Development: `http://localhost:8000/vendor/acme/shop/products` -- With port: `http://localhost:8000/vendor/acme/shop/products/123` +- Development: `http://localhost:8000/vendors/acme/shop/products` +- With port: `http://localhost:8000/vendors/acme/shop/products/123` **How It Works:** -1. Developer visits `http://localhost:8000/vendor/acme/shop/products` -2. `vendor_context_middleware` detects path-based routing pattern `/vendor/acme/...` +1. Developer visits `http://localhost:8000/vendors/acme/shop/products` +2. `vendor_context_middleware` detects path-based routing pattern `/vendors/acme/...` 3. Extracts vendor code `"acme"` from the path 4. Looks up Vendor: `SELECT * FROM vendors WHERE subdomain = 'acme'` 5. Sets `request.state.vendor = Vendor(acme)` @@ -151,12 +153,12 @@ https://acme.wizamart.com/shop/account/profile → Profile (Auth Require ### Path-Based (DEVELOPMENT) ``` -http://localhost:8000/vendor/acme/shop/ → Homepage -http://localhost:8000/vendor/acme/shop/products → Products -http://localhost:8000/vendor/acme/shop/products/123 → Product Detail -http://localhost:8000/vendor/acme/shop/cart → Cart -http://localhost:8000/vendor/acme/shop/checkout → Checkout -http://localhost:8000/vendor/acme/shop/account/login → Login +http://localhost:8000/vendors/acme/shop/ → Homepage +http://localhost:8000/vendors/acme/shop/products → Products +http://localhost:8000/vendors/acme/shop/products/123 → Product Detail +http://localhost:8000/vendors/acme/shop/cart → Cart +http://localhost:8000/vendors/acme/shop/checkout → Checkout +http://localhost:8000/vendors/acme/shop/account/login → Login ``` ### API Endpoints (Same for All Modes) @@ -350,9 +352,9 @@ In Jinja2 template: The `vendor_context_middleware` sets `clean_path` for path-based URLs, but this isn't used for FastAPI routing. **Problem:** -- Incoming: `GET http://localhost:8000/vendor/acme/shop/products` +- Incoming: `GET http://localhost:8000/vendors/acme/shop/products` - Routes registered: `@router.get("/shop/products")` -- FastAPI tries to match `/vendor/acme/shop/products` against `/shop/products` +- FastAPI tries to match `/vendors/acme/shop/products` against `/shop/products` - Result: ❌ 404 Not Found **Solution (Recommended):** @@ -374,7 +376,7 @@ app.middleware("http")(path_rewrite_middleware) Or alternatively, mount the router twice: ```python app.include_router(shop_pages.router, prefix="/shop") -app.include_router(shop_pages.router, prefix="/vendor") # Allows /vendor/* paths +app.include_router(shop_pages.router, prefix="/vendors/{vendor_code}/shop") # Path-based development mode ``` --- @@ -401,7 +403,7 @@ Set-Cookie: customer_token=eyJ...; Path=/shop; HttpOnly; SameSite=Lax |------|-----|----------|-----|-----| | Subdomain | `vendor.platform.com/shop` | Production (standard) | *.platform.com | Add subdomains | | Custom Domain | `vendor-domain.com/shop` | Production (premium) | Per vendor | Vendor configures | -| Path-Based | `localhost:8000/vendor/v/shop` | Development only | None | None | +| Path-Based | `localhost:8000/vendors/v/shop` | Development only | None | None | --- diff --git a/docs/backend/middleware-reference.md b/docs/backend/middleware-reference.md index 5aca459f..b837251d 100644 --- a/docs/backend/middleware-reference.md +++ b/docs/backend/middleware-reference.md @@ -207,7 +207,7 @@ Middleware for request/response logging and performance monitoring. Middleware function that rewrites request paths for path-based vendor routing. **Purpose:** -Allows `/vendor/VENDORCODE/shop/products` to be internally routed as `/shop/products` for proper FastAPI route matching. +Allows `/vendors/VENDORCODE/shop/products` (path-based development mode) to be internally routed as `/shop/products` for proper FastAPI route matching. **Execution Order:** Must run AFTER VendorContextMiddleware and BEFORE ContextDetectionMiddleware. diff --git a/docs/index.md b/docs/index.md index a56bdf6a..f4fba206 100644 --- a/docs/index.md +++ b/docs/index.md @@ -66,11 +66,11 @@ vendor2.platform.com → Vendor 2 Shop admin.platform.com → Admin Interface ``` -**3. Path-Based Mode** +**3. Path-Based Mode** (Development Only) ``` -platform.com/vendor/vendor1/shop → Vendor 1 Shop -platform.com/vendor/vendor2/shop → Vendor 2 Shop -platform.com/admin → Admin Interface +platform.com/vendors/vendor1/shop → Vendor 1 Shop +platform.com/vendors/vendor2/shop → Vendor 2 Shop +platform.com/admin → Admin Interface ``` **Learn more**: [Multi-Tenant System](architecture/multi-tenant.md)