Complete the public -> platform naming migration across the codebase. This aligns with the naming convention where "platform" refers to the marketing/public-facing pages of the platform itself. Changes: - Update all imports from public to platform modules - Update template references from public/ to platform/ - Update route registrations to use platform prefix - Update documentation to reflect new naming - Update test files for platform API endpoints Files affected: - app/api/main.py - router imports - app/modules/*/routes/*/platform.py - route definitions - app/modules/*/templates/*/platform/ - template files - app/modules/routes.py - route discovery - docs/* - documentation updates - tests/integration/api/v1/platform/ - test files Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
12 KiB
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:
- Original:
/api/v1/platform/vendors/{vendor_id}/* - 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/vendors/)
Location: app/api/v1/platform/vendors/
Endpoints:
GET /api/v1/platform/vendors → List active vendors
GET /api/v1/platform/vendors/{vendor_id}/products → Product catalog
GET /api/v1/platform/vendors/{vendor_id}/products/{product_id} → Product detail
POST /api/v1/platform/vendors/{vendor_id}/cart → Cart operations
GET /api/v1/platform/vendors/{vendor_id}/orders → Customer orders
POST /api/v1/platform/vendors/auth/login → Customer authentication
POST /api/v1/platform/vendors/auth/register → Customer registration
Characteristics:
- ✅ Vendor-scoped: Requires explicit
vendor_idin path - ✅ RESTful: Clear resource hierarchy
- ✅ Authentication: Supports customer auth via
/auth/*endpoints - ✅ Existing: Already implemented with services and models
- ❌ Verbose: Requires vendor_id in every call
Current Usage:
- Product catalog:
products.py - Shopping cart:
cart.py - Orders:
orders.py - Customer auth:
auth.py - Vendor listing:
vendors.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:
- ✅ Vendor-agnostic URLs: Clean paths without vendor_id
- ✅ Middleware-driven: Relies on
VendorContextMiddlewareto inject vendor - ✅ Simpler URLs:
/api/v1/shop/productsvs/api/v1/platform/vendors/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
// ❌ 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/vendors/123/products')
Confusion
Developers must remember:
- "Is this endpoint under
/shopor/public/vendors?" - "Do I need to pass vendor_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 /vendors/wizamart/about
Root Cause:
- CMS API exists at
/api/v1/shop/content-pages/{slug} - No corresponding HTML route handler in
vendor_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
└── vendors/
└── GET / → List vendors (marketplace)
Implementation:
- Vendor extracted by
VendorContextMiddlewarefrom request - All endpoints use
request.state.vendorinstead of path parameter - URLs are cleaner:
/api/v1/shop/productsinstead of/api/v1/platform/vendors/123/products
Pros:
- ✅ Clean, consistent API structure
- ✅ Simpler URLs for frontend
- ✅ Vendor 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/vendors/* and Deprecate /api/v1/shop/*
Approach: Move CMS endpoints to /api/v1/platform/vendors/{vendor_id}/content-pages/*
Proposed Changes:
# Move CMS endpoints
FROM: /api/v1/shop/content-pages/navigation
TO: /api/v1/platform/vendors/{vendor_id}/content-pages/navigation
FROM: /api/v1/shop/content-pages/{slug}
TO: /api/v1/platform/vendors/{vendor_id}/content-pages/{slug}
Pros:
- ✅ Maintains existing architecture
- ✅ No breaking changes to existing endpoints
- ✅ RESTful vendor-scoped URLs
- ✅ Minimal code changes
Cons:
- ❌ Verbose URLs with vendor_id everywhere
- ❌ Doesn't leverage middleware architecture
- ❌ Less elegant than Option 1
- ❌ Frontend must always know vendor_id
Migration Effort: LOW (1 day)
Option 3: Hybrid Approach with Alias Routes
Approach: Support both patterns during transition period
Implementation:
# Primary (new pattern)
@router.get("/products")
async def get_products_new(request: Request, db: Session = Depends(get_db)):
vendor = request.state.vendor
# ...
# Alias (old pattern for backwards compatibility)
@router.get("/vendors/{vendor_id}/products")
async def get_products_legacy(vendor_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:
-
Architectural Alignment: Platform uses middleware for vendor context injection. APIs should leverage this instead of requiring explicit vendor_id.
-
User Experience: Cleaner URLs are easier for frontend developers:
// ✅ GOOD fetch('/api/v1/shop/products') // ❌ BAD fetch('/api/v1/platform/vendors/123/products') -
Multi-Tenant Best Practice: Vendor context should be implicit (from domain/path), not explicit in every API call.
-
Consistency: All shop endpoints follow same pattern - no mixing
/shopand/public/vendors. -
Future-Proof: Easier to add new shop features without worrying about vendor_id paths.
Migration Plan
Phase 1: Create New Endpoints (Week 1)
Day 1-2: Move Products
# Copy and adapt
app/api/v1/platform/vendors/products.py → app/api/v1/shop/products.py
# Changes:
- Remove vendor_id path parameter
- Use request.state.vendor instead
- Update route paths
Day 3: Move Cart
app/api/v1/platform/vendors/cart.py → app/api/v1/shop/cart.py
Day 4: Move Orders
app/api/v1/platform/vendors/orders.py → app/api/v1/shop/orders.py
Day 5: Move Auth
app/api/v1/platform/vendors/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/vendors/${vendorId}/...to/api/v1/shop/...
JavaScript:
- Update any shop-related API client code
- Remove hardcoded vendor_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/vendors)
# app/api/v1/platform/vendors/products.py
@router.get("/{vendor_id}/products")
def get_public_product_catalog(
vendor_id: int = Path(...),
db: Session = Depends(get_db),
):
vendor = db.query(Vendor).filter(Vendor.id == vendor_id).first()
# ...
// Frontend
const vendorId = 123;
fetch(`/api/v1/platform/vendors/${vendorId}/products`)
After (Proposed - /api/v1/shop)
# app/api/v1/shop/products.py
@router.get("/products")
def get_product_catalog(
request: Request,
db: Session = Depends(get_db),
):
vendor = request.state.vendor # Injected by middleware
# ...
// Frontend
fetch('/api/v1/shop/products') // Vendor context automatic
Impact Assessment
Breaking Changes
- All frontend code calling
/api/v1/platform/vendors/*must update - Mobile apps (if any) must update
- Third-party integrations (if any) must update
Non-Breaking
- Admin APIs:
/api/v1/admin/*→ No changes - Vendor APIs:
/api/v1/vendor/*→ No changes - Vendor listing: Keep
/api/v1/platform/vendors(list all vendors for marketplace)
Risk Mitigation
- Deprecation Period: Keep old endpoints for 2-4 weeks
- Logging: Track usage of old endpoints
- Documentation: Clear migration guide for developers
- 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
# Move: app/api/v1/shop/content_pages.py
# To: app/api/v1/platform/vendors/content_pages.py
# Update routes:
@router.get("/{vendor_id}/content-pages/navigation")
@router.get("/{vendor_id}/content-pages/{slug}")
Effort: 1-2 hours Impact: Fixes immediate CMS issue Debt: Maintains architectural divergence
Decision Required
Question for Team:
Should we:
- ✅ Consolidate to
/api/v1/shop/*(Recommended) - ❌ Keep
/api/v1/platform/vendors/*and move CMS there - ❌ Hybrid approach with both patterns
- ❌ 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/vendors/*
- ✅
vendors.py- Vendor 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/vendors.py(marketplace listing)