Files
orion/docs/architecture/api-consolidation-proposal.md
Samir Boulahtit d648c921b7
Some checks failed
CI / ruff (push) Successful in 10s
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / pytest (push) Has been cancelled
docs: add consolidated dev URL reference and migrate /shop to /storefront
- Add Development URL Quick Reference section to url-routing overview
  with all login URLs, entry points, and full examples
- Replace /shop/ path segments with /storefront/ across 50 docs files
- Update file references: shop_pages.py → storefront_pages.py,
  templates/shop/ → templates/storefront/, api/v1/shop/ → api/v1/storefront/
- Preserve domain references (orion.shop) and /store/ staff dashboard paths
- Archive docs left unchanged (historical)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 13:23:44 +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 storefront/customer-facing endpoints:

  1. Original: /api/v1/platform/stores/{store_id}/*
  2. New: /api/v1/storefront/*

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/storefront/)

Location: app/api/v1/storefront/

Endpoints:

GET /api/v1/storefront/content-pages/navigation        → CMS navigation pages
GET /api/v1/storefront/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/storefront/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 storefront templates (e.g., storefront/products.html, storefront/home.html)

The Problem

Inconsistency

// ❌ INCONSISTENT - Two different patterns for same context
// CMS pages use new pattern
fetch('/api/v1/storefront/content-pages/about')

// Products use old pattern
fetch('/api/v1/platform/stores/123/products')

Confusion

Developers must remember:

  • "Is this endpoint under /storefront 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/storefront/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/storefront/* (Middleware-Driven)

Approach: Consolidate all customer-facing endpoints under /api/v1/storefront/*

Proposed Structure:

/api/v1/storefront/
  ├── 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/storefront/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/storefront/*

Approach: Move CMS endpoints to /api/v1/platform/stores/{store_id}/content-pages/*

Proposed Changes:

# Move CMS endpoints
FROM: /api/v1/storefront/content-pages/navigation
TO:   /api/v1/platform/stores/{store_id}/content-pages/navigation

FROM: /api/v1/storefront/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/storefront/* (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/storefront/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 storefront endpoints follow same pattern - no mixing /storefront 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/storefront/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/storefront/cart.py

Day 4: Move Orders

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

Day 5: Move Auth

app/api/v1/platform/stores/auth.py  →  app/api/v1/storefront/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/storefront/...

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/storefront)

# app/api/v1/storefront/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/storefront/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/storefront/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/storefront/* (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/storefront/*

  • content_pages.py - CMS pages

To Be Created (if Option 1 chosen)

  • 📝 storefront/products.py
  • 📝 storefront/cart.py
  • 📝 storefront/orders.py
  • 📝 storefront/auth.py
  • 📝 storefront/stores.py (marketplace listing)

References