Replace all ~1,086 occurrences of Wizamart/wizamart/WIZAMART/WizaMart with Orion/orion/ORION across 184 files. This includes database identifiers, email addresses, domain references, R2 bucket names, DNS prefixes, encryption salt, Celery app name, config defaults, Docker configs, CI configs, documentation, seed data, and templates. Renames homepage-wizamart.html template to homepage-orion.html. Fixes duplicate file_pattern key in api.yaml architecture rule. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
443 lines
12 KiB
Markdown
443 lines
12 KiB
Markdown
# API Architecture Consolidation Proposal
|
|
|
|
**Date:** 2025-11-22
|
|
**Status:** DRAFT - Awaiting Review
|
|
**Priority:** HIGH
|
|
|
|
## Executive Summary
|
|
|
|
The platform currently has **two parallel API structures** for shop/customer-facing endpoints:
|
|
1. **Original:** `/api/v1/platform/stores/{store_id}/*`
|
|
2. **New:** `/api/v1/shop/*`
|
|
|
|
This divergence creates confusion, maintenance overhead, and potential bugs. This document analyzes the situation and proposes a consolidation strategy.
|
|
|
|
---
|
|
|
|
## Current State Analysis
|
|
|
|
### 1. Original Architecture (`/api/v1/platform/stores/`)
|
|
|
|
**Location:** `app/api/v1/platform/stores/`
|
|
|
|
**Endpoints:**
|
|
```
|
|
GET /api/v1/platform/stores → List active stores
|
|
GET /api/v1/platform/stores/{store_id}/products → Product catalog
|
|
GET /api/v1/platform/stores/{store_id}/products/{product_id} → Product detail
|
|
POST /api/v1/platform/stores/{store_id}/cart → Cart operations
|
|
GET /api/v1/platform/stores/{store_id}/orders → Customer orders
|
|
POST /api/v1/platform/stores/auth/login → Customer authentication
|
|
POST /api/v1/platform/stores/auth/register → Customer registration
|
|
```
|
|
|
|
**Characteristics:**
|
|
- ✅ **Store-scoped:** Requires explicit `store_id` in path
|
|
- ✅ **RESTful:** Clear resource hierarchy
|
|
- ✅ **Authentication:** Supports customer auth via `/auth/*` endpoints
|
|
- ✅ **Existing:** Already implemented with services and models
|
|
- ❌ **Verbose:** Requires store_id in every call
|
|
|
|
**Current Usage:**
|
|
- Product catalog: `products.py`
|
|
- Shopping cart: `cart.py`
|
|
- Orders: `orders.py`
|
|
- Customer auth: `auth.py`
|
|
- Store listing: `stores.py`
|
|
|
|
---
|
|
|
|
### 2. New Architecture (`/api/v1/shop/`)
|
|
|
|
**Location:** `app/api/v1/shop/`
|
|
|
|
**Endpoints:**
|
|
```
|
|
GET /api/v1/shop/content-pages/navigation → CMS navigation pages
|
|
GET /api/v1/shop/content-pages/{slug} → CMS page content
|
|
```
|
|
|
|
**Characteristics:**
|
|
- ✅ **Store-agnostic URLs:** Clean paths without store_id
|
|
- ✅ **Middleware-driven:** Relies on `StoreContextMiddleware` to inject store
|
|
- ✅ **Simpler URLs:** `/api/v1/shop/products` vs `/api/v1/platform/stores/123/products`
|
|
- ❌ **Incomplete:** Only CMS endpoints implemented
|
|
- ❌ **Divergent:** Not consistent with existing public API
|
|
|
|
**Current Usage:**
|
|
- CMS content pages only
|
|
- Called from shop templates (e.g., `shop/products.html`, `shop/home.html`)
|
|
|
|
---
|
|
|
|
## The Problem
|
|
|
|
### Inconsistency
|
|
|
|
```javascript
|
|
// ❌ INCONSISTENT - Two different patterns for same context
|
|
// CMS pages use new pattern
|
|
fetch('/api/v1/shop/content-pages/about')
|
|
|
|
// Products use old pattern
|
|
fetch('/api/v1/platform/stores/123/products')
|
|
```
|
|
|
|
### Confusion
|
|
|
|
Developers must remember:
|
|
- "Is this endpoint under `/shop` or `/public/stores`?"
|
|
- "Do I need to pass store_id or is it from middleware?"
|
|
- "Which authentication endpoints do I use?"
|
|
|
|
### Maintenance Overhead
|
|
|
|
- Two sets of documentation
|
|
- Two architectural patterns
|
|
- Duplicate functionality risk
|
|
- Testing complexity
|
|
|
|
### Broken Features
|
|
|
|
**Current Issue:** CMS pages not loading at `/stores/orion/about`
|
|
|
|
**Root Cause:**
|
|
- CMS API exists at `/api/v1/shop/content-pages/{slug}`
|
|
- No corresponding HTML route handler in `store_pages.py`
|
|
- JavaScript might be calling wrong endpoint
|
|
|
|
---
|
|
|
|
## Options Analysis
|
|
|
|
### Option 1: Move Everything to `/api/v1/shop/*` (Middleware-Driven)
|
|
|
|
**Approach:** Consolidate all customer-facing endpoints under `/api/v1/shop/*`
|
|
|
|
**Proposed Structure:**
|
|
```
|
|
/api/v1/shop/
|
|
├── auth/
|
|
│ ├── POST /login → Customer login
|
|
│ ├── POST /register → Customer registration
|
|
│ └── POST /logout → Customer logout
|
|
├── products/
|
|
│ ├── GET / → Product catalog
|
|
│ ├── GET /{product_id} → Product detail
|
|
│ └── GET /featured → Featured products
|
|
├── cart/
|
|
│ ├── GET / → View cart
|
|
│ ├── POST /items → Add to cart
|
|
│ └── PUT /items/{item_id} → Update quantity
|
|
├── orders/
|
|
│ ├── GET / → Order history
|
|
│ ├── GET /{order_id} → Order detail
|
|
│ └── POST / → Create order
|
|
├── content-pages/ → [EXISTING]
|
|
│ ├── GET /navigation → Navigation pages
|
|
│ └── GET /{slug} → Page content
|
|
└── stores/
|
|
└── GET / → List stores (marketplace)
|
|
```
|
|
|
|
**Implementation:**
|
|
- Store extracted by `StoreContextMiddleware` from request
|
|
- All endpoints use `request.state.store` instead of path parameter
|
|
- URLs are cleaner: `/api/v1/shop/products` instead of `/api/v1/platform/stores/123/products`
|
|
|
|
**Pros:**
|
|
- ✅ Clean, consistent API structure
|
|
- ✅ Simpler URLs for frontend
|
|
- ✅ Store is contextual (from domain/subdomain/path)
|
|
- ✅ Aligns with multi-tenant architecture
|
|
- ✅ Easier to document and understand
|
|
|
|
**Cons:**
|
|
- ❌ **Breaking change** for existing clients
|
|
- ❌ Requires moving ~8-10 endpoint files
|
|
- ❌ Need to update all frontend code
|
|
- ❌ Testing effort to verify all endpoints work
|
|
|
|
**Migration Effort:** HIGH (2-3 days)
|
|
|
|
---
|
|
|
|
### Option 2: Keep `/api/v1/platform/stores/*` and Deprecate `/api/v1/shop/*`
|
|
|
|
**Approach:** Move CMS endpoints to `/api/v1/platform/stores/{store_id}/content-pages/*`
|
|
|
|
**Proposed Changes:**
|
|
```
|
|
# Move CMS endpoints
|
|
FROM: /api/v1/shop/content-pages/navigation
|
|
TO: /api/v1/platform/stores/{store_id}/content-pages/navigation
|
|
|
|
FROM: /api/v1/shop/content-pages/{slug}
|
|
TO: /api/v1/platform/stores/{store_id}/content-pages/{slug}
|
|
```
|
|
|
|
**Pros:**
|
|
- ✅ Maintains existing architecture
|
|
- ✅ No breaking changes to existing endpoints
|
|
- ✅ RESTful store-scoped URLs
|
|
- ✅ Minimal code changes
|
|
|
|
**Cons:**
|
|
- ❌ Verbose URLs with store_id everywhere
|
|
- ❌ Doesn't leverage middleware architecture
|
|
- ❌ Less elegant than Option 1
|
|
- ❌ Frontend must always know store_id
|
|
|
|
**Migration Effort:** LOW (1 day)
|
|
|
|
---
|
|
|
|
### Option 3: Hybrid Approach with Alias Routes
|
|
|
|
**Approach:** Support both patterns during transition period
|
|
|
|
**Implementation:**
|
|
```python
|
|
# Primary (new pattern)
|
|
@router.get("/products")
|
|
async def get_products_new(request: Request, db: Session = Depends(get_db)):
|
|
store = request.state.store
|
|
# ...
|
|
|
|
# Alias (old pattern for backwards compatibility)
|
|
@router.get("/stores/{store_id}/products")
|
|
async def get_products_legacy(store_id: int, db: Session = Depends(get_db)):
|
|
# Redirect or proxy to new pattern
|
|
# ...
|
|
```
|
|
|
|
**Pros:**
|
|
- ✅ No breaking changes
|
|
- ✅ Gradual migration path
|
|
- ✅ Both patterns work simultaneously
|
|
|
|
**Cons:**
|
|
- ❌ Maintains complexity
|
|
- ❌ Doubles maintenance burden
|
|
- ❌ Confusing for developers
|
|
- ❌ Technical debt accumulates
|
|
|
|
**Migration Effort:** MEDIUM (1-2 days + ongoing maintenance)
|
|
|
|
---
|
|
|
|
## Recommendation
|
|
|
|
### **OPTION 1: Consolidate to `/api/v1/shop/*` (Middleware-Driven)**
|
|
|
|
**Rationale:**
|
|
|
|
1. **Architectural Alignment**: Platform uses middleware for store context injection. APIs should leverage this instead of requiring explicit store_id.
|
|
|
|
2. **User Experience**: Cleaner URLs are easier for frontend developers:
|
|
```javascript
|
|
// ✅ GOOD
|
|
fetch('/api/v1/shop/products')
|
|
|
|
// ❌ BAD
|
|
fetch('/api/v1/platform/stores/123/products')
|
|
```
|
|
|
|
3. **Multi-Tenant Best Practice**: Store context should be implicit (from domain/path), not explicit in every API call.
|
|
|
|
4. **Consistency**: All shop endpoints follow same pattern - no mixing `/shop` and `/public/stores`.
|
|
|
|
5. **Future-Proof**: Easier to add new shop features without worrying about store_id paths.
|
|
|
|
---
|
|
|
|
## Migration Plan
|
|
|
|
### Phase 1: Create New Endpoints (Week 1)
|
|
|
|
**Day 1-2: Move Products**
|
|
```bash
|
|
# Copy and adapt
|
|
app/api/v1/platform/stores/products.py → app/api/v1/shop/products.py
|
|
|
|
# Changes:
|
|
- Remove store_id path parameter
|
|
- Use request.state.store instead
|
|
- Update route paths
|
|
```
|
|
|
|
**Day 3: Move Cart**
|
|
```bash
|
|
app/api/v1/platform/stores/cart.py → app/api/v1/shop/cart.py
|
|
```
|
|
|
|
**Day 4: Move Orders**
|
|
```bash
|
|
app/api/v1/platform/stores/orders.py → app/api/v1/shop/orders.py
|
|
```
|
|
|
|
**Day 5: Move Auth**
|
|
```bash
|
|
app/api/v1/platform/stores/auth.py → app/api/v1/shop/auth.py
|
|
```
|
|
|
|
### Phase 2: Update Frontend (Week 1)
|
|
|
|
**Templates:**
|
|
- Update all `fetch()` calls in shop templates
|
|
- Change from `/api/v1/platform/stores/${storeId}/...` to `/api/v1/shop/...`
|
|
|
|
**JavaScript:**
|
|
- Update any shop-related API client code
|
|
- Remove hardcoded store_id references
|
|
|
|
### Phase 3: Testing (Week 2, Day 1-2)
|
|
|
|
- ✅ Test all shop pages load correctly
|
|
- ✅ Test product catalog
|
|
- ✅ Test cart operations
|
|
- ✅ Test order placement
|
|
- ✅ Test customer authentication
|
|
- ✅ Test CMS pages
|
|
|
|
### Phase 4: Deprecation Notice (Week 2, Day 3)
|
|
|
|
- Add deprecation warnings to old endpoints
|
|
- Update documentation
|
|
- Add logging to track old endpoint usage
|
|
|
|
### Phase 5: Removal (Week 3+)
|
|
|
|
- Monitor old endpoint usage
|
|
- After no usage for 2 weeks, remove old endpoints
|
|
- Clean up code
|
|
|
|
---
|
|
|
|
## Code Examples
|
|
|
|
### Before (Current - `/api/v1/platform/stores`)
|
|
|
|
```python
|
|
# app/api/v1/platform/stores/products.py
|
|
@router.get("/{store_id}/products")
|
|
def get_public_product_catalog(
|
|
store_id: int = Path(...),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
store = db.query(Store).filter(Store.id == store_id).first()
|
|
# ...
|
|
```
|
|
|
|
```javascript
|
|
// Frontend
|
|
const storeId = 123;
|
|
fetch(`/api/v1/platform/stores/${storeId}/products`)
|
|
```
|
|
|
|
### After (Proposed - `/api/v1/shop`)
|
|
|
|
```python
|
|
# app/api/v1/shop/products.py
|
|
@router.get("/products")
|
|
def get_product_catalog(
|
|
request: Request,
|
|
db: Session = Depends(get_db),
|
|
):
|
|
store = request.state.store # Injected by middleware
|
|
# ...
|
|
```
|
|
|
|
```javascript
|
|
// Frontend
|
|
fetch('/api/v1/shop/products') // Store context automatic
|
|
```
|
|
|
|
---
|
|
|
|
## Impact Assessment
|
|
|
|
### Breaking Changes
|
|
- All frontend code calling `/api/v1/platform/stores/*` must update
|
|
- Mobile apps (if any) must update
|
|
- Third-party integrations (if any) must update
|
|
|
|
### Non-Breaking
|
|
- Admin APIs: `/api/v1/admin/*` → No changes
|
|
- Store APIs: `/api/v1/store/*` → No changes
|
|
- Store listing: Keep `/api/v1/platform/stores` (list all stores for marketplace)
|
|
|
|
### Risk Mitigation
|
|
1. **Deprecation Period**: Keep old endpoints for 2-4 weeks
|
|
2. **Logging**: Track usage of old endpoints
|
|
3. **Documentation**: Clear migration guide for developers
|
|
4. **Testing**: Comprehensive E2E tests before deployment
|
|
|
|
---
|
|
|
|
## Alternative: Quick Fix for Current Issue
|
|
|
|
If full migration is not approved immediately, we can do a **minimal fix** for the CMS issue:
|
|
|
|
### Quick Fix: Just Move CMS to Public API
|
|
|
|
```python
|
|
# Move: app/api/v1/shop/content_pages.py
|
|
# To: app/api/v1/platform/stores/content_pages.py
|
|
|
|
# Update routes:
|
|
@router.get("/{store_id}/content-pages/navigation")
|
|
@router.get("/{store_id}/content-pages/{slug}")
|
|
```
|
|
|
|
**Effort:** 1-2 hours
|
|
**Impact:** Fixes immediate CMS issue
|
|
**Debt:** Maintains architectural divergence
|
|
|
|
---
|
|
|
|
## Decision Required
|
|
|
|
**Question for Team:**
|
|
|
|
Should we:
|
|
1. ✅ **Consolidate to `/api/v1/shop/*`** (Recommended)
|
|
2. ❌ **Keep `/api/v1/platform/stores/*`** and move CMS there
|
|
3. ❌ **Hybrid approach** with both patterns
|
|
4. ❌ **Quick fix only** - move CMS, address later
|
|
|
|
**Timeline:** Please decide by [DATE] so we can plan sprint accordingly.
|
|
|
|
---
|
|
|
|
## Appendix: Current Endpoint Inventory
|
|
|
|
### `/api/v1/platform/stores/*`
|
|
- ✅ `stores.py` - Store listing
|
|
- ✅ `auth.py` - Customer authentication
|
|
- ✅ `products.py` - Product catalog
|
|
- ✅ `cart.py` - Shopping cart
|
|
- ✅ `orders.py` - Order management
|
|
- 🚧 `payments.py` - Stub
|
|
- 🚧 `search.py` - Stub
|
|
- 🚧 `shop.py` - Stub
|
|
|
|
### `/api/v1/shop/*`
|
|
- ✅ `content_pages.py` - CMS pages
|
|
|
|
### To Be Created (if Option 1 chosen)
|
|
- 📝 `shop/products.py`
|
|
- 📝 `shop/cart.py`
|
|
- 📝 `shop/orders.py`
|
|
- 📝 `shop/auth.py`
|
|
- 📝 `shop/stores.py` (marketplace listing)
|
|
|
|
---
|
|
|
|
## References
|
|
|
|
- [Authentication Dependencies Guide](../development/auth-dependencies-guide.md)
|
|
- [Multi-Tenant Architecture](./multi-tenant.md)
|
|
- [Middleware Stack Documentation](./middleware.md)
|
|
- [URL Routing Overview](./url-routing/overview.md)
|