Files
orion/docs/architecture/api-consolidation-proposal.md
Samir Boulahtit 3c7af0ccdf refactor: standardize markdown file naming to kebab-case convention
Renamed all documentation files to follow kebab-case naming standard:
- UPPERCASE files → lowercase (e.g., RBAC.md → rbac.md)
- snake_case files → kebab-case (e.g., icons_guide.md → icons-guide.md)
- SCREAMING_SNAKE_CASE → kebab-case (e.g., DATABASE_SETUP_GUIDE.md → database-setup-guide.md)

Files renamed (15 total):
API Documentation:
  - api/RBAC.md → api/rbac.md

Architecture:
  - architecture/API_CONSOLIDATION_PROPOSAL.md → api-consolidation-proposal.md
  - architecture/API_MIGRATION_STATUS.md → api-migration-status.md

Development:
  - development/AUTH_DEPENDENCIES_GUIDE.md → auth-dependencies-guide.md
  - development/CUSTOMER_AUTHENTICATION_IMPLEMENTATION.md → customer-authentication-implementation.md
  - development/CUSTOMER_AUTH_SUMMARY.md → customer-auth-summary.md
  - development/icons_guide.md → icons-guide.md

Database Seeder:
  - database-seeder/DATABASE_INIT_GUIDE.md → database-init-guide.md
  - database-seeder/DATABASE_QUICK_REFERENCE_GUIDE.md → database-quick-reference-guide.md
  - database-seeder/DATABASE_SEEDER_DOCUMENTATION.md → database-seeder-documentation.md
  - database-seeder/MAKEFILE_DATABASE_SEEDER.md → makefile-database-seeder.md

Error Rendering:
  - error-rendering/ERROR_RENDERING_DEVELOPER_DOCUMENTATION.md → error-rendering-developer-documentation.md
  - error-rendering/HTML_ERROR_RENDERING_FLOW_DIAGRAM.md → html-error-rendering-flow-diagram.md

Getting Started:
  - getting-started/DATABASE_QUICK_REFERENCE.md → database-quick-reference.md
  - getting-started/DATABASE_SETUP_GUIDE.md → database-setup-guide.md

Updates:
- Updated all references in mkdocs.yml
- Updated all cross-references in markdown files
- Verified mkdocs builds without warnings or errors

Standard: Use kebab-case (lowercase-with-hyphens) for all markdown files

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 07:58:33 +01:00

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:

  1. Original: /api/v1/public/vendors/{vendor_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/public/vendors/)

Location: app/api/v1/public/vendors/

Endpoints:

GET  /api/v1/public/vendors                     → List active vendors
GET  /api/v1/public/vendors/{vendor_id}/products → Product catalog
GET  /api/v1/public/vendors/{vendor_id}/products/{product_id} → Product detail
POST /api/v1/public/vendors/{vendor_id}/cart     → Cart operations
GET  /api/v1/public/vendors/{vendor_id}/orders   → Customer orders
POST /api/v1/public/vendors/auth/login           → Customer authentication
POST /api/v1/public/vendors/auth/register        → Customer registration

Characteristics:

  • Vendor-scoped: Requires explicit vendor_id in 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 VendorContextMiddleware to inject vendor
  • Simpler URLs: /api/v1/shop/products vs /api/v1/public/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/public/vendors/123/products')

Confusion

Developers must remember:

  • "Is this endpoint under /shop or /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 VendorContextMiddleware from request
  • All endpoints use request.state.vendor instead of path parameter
  • URLs are cleaner: /api/v1/shop/products instead of /api/v1/public/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/public/vendors/* and Deprecate /api/v1/shop/*

Approach: Move CMS endpoints to /api/v1/public/vendors/{vendor_id}/content-pages/*

Proposed Changes:

# Move CMS endpoints
FROM: /api/v1/shop/content-pages/navigation
TO:   /api/v1/public/vendors/{vendor_id}/content-pages/navigation

FROM: /api/v1/shop/content-pages/{slug}
TO:   /api/v1/public/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:

  1. Architectural Alignment: Platform uses middleware for vendor context injection. APIs should leverage this instead of requiring explicit vendor_id.

  2. User Experience: Cleaner URLs are easier for frontend developers:

    // ✅ GOOD
    fetch('/api/v1/shop/products')
    
    // ❌ BAD
    fetch('/api/v1/public/vendors/123/products')
    
  3. Multi-Tenant Best Practice: Vendor 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/vendors.

  5. 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/public/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/public/vendors/cart.py  →  app/api/v1/shop/cart.py

Day 4: Move Orders

app/api/v1/public/vendors/orders.py  →  app/api/v1/shop/orders.py

Day 5: Move Auth

app/api/v1/public/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/public/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/public/vendors)

# app/api/v1/public/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/public/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/public/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/public/vendors (list all vendors 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

# Move: app/api/v1/shop/content_pages.py
# To:   app/api/v1/public/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:

  1. Consolidate to /api/v1/shop/* (Recommended)
  2. Keep /api/v1/public/vendors/* 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/public/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)

References