Files
orion/docs/architecture/api-consolidation-proposal.md
Samir Boulahtit e9253fbd84 refactor: rename Wizamart to Orion across entire codebase
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>
2026-02-14 16:46:56 +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/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

// ❌ 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:

# 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:

    // ✅ 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

# 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

app/api/v1/platform/stores/cart.py  →  app/api/v1/shop/cart.py

Day 4: Move Orders

app/api/v1/platform/stores/orders.py  →  app/api/v1/shop/orders.py

Day 5: Move Auth

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)

# 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()
    # ...
// Frontend
const storeId = 123;
fetch(`/api/v1/platform/stores/${storeId}/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),
):
    store = request.state.store  # Injected by middleware
    # ...
// 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

# 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