Files
orion/docs/proposals/PLAN_storefront-module-restructure.md
Samir Boulahtit 0845555413 feat(modules): create cart, catalog, and checkout e-commerce modules
Phase 3 of storefront restructure plan - create dedicated modules for
e-commerce functionality:

- cart: Shopping cart management with storefront API routes
  - CartItem model with cents-based pricing
  - CartService for cart operations
  - Storefront routes for cart CRUD operations

- catalog: Product catalog browsing for customers
  - CatalogService for public product queries
  - Storefront routes for product listing/search/details

- checkout: Order creation from cart (placeholder)
  - CheckoutService stub for future cart-to-order conversion
  - Schemas for checkout flow

These modules separate e-commerce concerns from core platform
concerns (customer auth), enabling non-commerce platforms.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 22:53:35 +01:00

10 KiB

Implementation Plan: Storefront Module Restructure

Overview

Restructure the platform to properly separate core platform concerns (customer auth/identity) from e-commerce concerns (cart, checkout, catalog), and rename "shop" to "storefront" throughout.

Current Issues

  1. API routes import database models directly - violates layered architecture
  2. No architecture rule enforces this - validator doesn't catch it
  3. "shop" naming is misleading - not all platforms sell items
  4. Customer auth is bundled with e-commerce - should be core/platform concern

Phase 1: Add Missing Architecture Rule

Task 1.1: Add API-007 rule to prevent direct model imports

File: .architecture-rules/api.yaml

Add new rule:

- id: "API-007"
  name: "API endpoints must NOT import database models directly"
  severity: "error"
  description: |
    API endpoints should import from services, not directly from database models.
    This enforces the layered architecture: Routes → Services → Models.

    The only exception is for type hints in FastAPI dependency injection,
    which should use schemas or services that return the appropriate types.

    WRONG:
      from models.database.customer import Customer
      from models.database.order import Order

    RIGHT:
      from app.modules.customers.services import customer_service
      from models.schema.customer import CustomerResponse
  pattern:
    file_pattern: "app/api/**/*.py"
    anti_patterns:
      - "from models\\.database\\."
      - "from app\\.modules\\..*\\.models\\."

Task 1.2: Update validator to check this rule

File: scripts/validate_architecture.py

Add validation for API-007.


Phase 2: Rename "shop" to "storefront"

Task 2.1: Rename API directory

app/api/v1/shop/  →  app/api/v1/storefront/

Task 2.2: Update all imports referencing shop

  • Update router registrations in app/api/v1/__init__.py
  • Update any references in middleware
  • Update documentation

Task 2.3: Rename routes/pages if applicable

app/routes/shop_pages.py  →  app/routes/storefront_pages.py

Phase 3: Create New E-commerce Modules

Task 3.1: Create cart module

app/modules/cart/
├── __init__.py
├── definition.py
├── config.py
├── exceptions.py
├── models/
│   ├── __init__.py
│   └── cart.py              # Cart, CartItem models (if persistent)
├── schemas/
│   ├── __init__.py
│   └── cart.py              # Move from models/schema/cart.py
├── services/
│   ├── __init__.py
│   └── cart_service.py      # Move from app/services/cart_service.py
└── routes/
    └── api/
        ├── __init__.py
        └── storefront.py    # Cart endpoints for customers

Task 3.2: Create checkout module

app/modules/checkout/
├── __init__.py
├── definition.py
├── config.py
├── exceptions.py
├── schemas/
│   ├── __init__.py
│   └── checkout.py          # CheckoutRequest, CheckoutResponse
├── services/
│   ├── __init__.py
│   └── checkout_service.py  # Orchestrates cart → order conversion
└── routes/
    └── api/
        ├── __init__.py
        └── storefront.py    # Place order endpoint

Task 3.3: Create catalog module

app/modules/catalog/
├── __init__.py
├── definition.py
├── config.py
├── schemas/
│   ├── __init__.py
│   └── catalog.py           # ProductListResponse, ProductDetailResponse
├── services/
│   ├── __init__.py
│   └── catalog_service.py   # Customer-facing product queries
└── routes/
    └── api/
        ├── __init__.py
        └── storefront.py    # Product browsing endpoints

Phase 4: Move Storefront Routes to Modules

Task 4.1: Move customer auth routes to customers module

From: app/api/v1/storefront/auth.py To: app/modules/customers/routes/api/storefront.py

Endpoints:

  • POST /auth/register - Customer registration
  • POST /auth/login - Customer login
  • POST /auth/logout - Customer logout
  • POST /auth/password-reset/request - Request password reset
  • POST /auth/password-reset/confirm - Confirm password reset

Task 4.2: Move customer profile routes to customers module

From: app/api/v1/storefront/profile.py To: app/modules/customers/routes/api/storefront.py (append)

Endpoints:

  • GET /profile - Get customer profile
  • PUT /profile - Update customer profile

Task 4.3: Move customer address routes to customers module

From: app/api/v1/storefront/addresses.py To: app/modules/customers/routes/api/storefront.py (append)

Endpoints:

  • GET /addresses - List customer addresses
  • POST /addresses - Create address
  • PUT /addresses/{id} - Update address
  • DELETE /addresses/{id} - Delete address

Task 4.4: Move cart routes to cart module

From: app/api/v1/storefront/carts.py To: app/modules/cart/routes/api/storefront.py

Task 4.5: Move order placement to checkout module

From: app/api/v1/storefront/orders.py (POST /orders only) To: app/modules/checkout/routes/api/storefront.py

Task 4.6: Move order viewing to orders module

From: app/api/v1/storefront/orders.py (GET endpoints) To: app/modules/orders/routes/api/storefront.py

Task 4.7: Move product browsing to catalog module

From: app/api/v1/storefront/products.py To: app/modules/catalog/routes/api/storefront.py

Task 4.8: Move messaging routes to messaging module

From: app/api/v1/storefront/messages.py To: app/modules/messaging/routes/api/storefront.py


Phase 5: Fix Direct Model Imports

Task 5.1: Update dependency injection pattern

Current pattern (violates layered architecture):

from models.database.customer import Customer

@router.get("/orders")
def get_orders(customer: Customer = Depends(get_current_customer_api)):
    ...

New pattern (proper layered architecture):

from app.modules.customers.schemas import CustomerContext

@router.get("/orders")
def get_orders(customer: CustomerContext = Depends(get_current_customer_api)):
    ...

Task 5.2: Create CustomerContext schema

File: app/modules/customers/schemas/context.py

class CustomerContext(BaseModel):
    """Customer context for dependency injection in storefront routes."""
    id: int
    vendor_id: int
    email: str
    first_name: str | None
    last_name: str | None

    model_config = ConfigDict(from_attributes=True)

Task 5.3: Update get_current_customer_api dependency

File: app/api/deps.py

Change return type from Customer (database model) to CustomerContext (schema).

Task 5.4: Update all storefront routes

Replace all Customer type hints with CustomerContext.


Phase 6: Delete Legacy Files

Task 6.1: Delete models/database/customer.py

After all imports are updated to use app.modules.customers.models.customer.

Task 6.2: Delete app/api/v1/storefront/ directory

After all routes are moved to their respective modules.

Task 6.3: Delete app/services/cart_service.py

After migrated to app/modules/cart/services/cart_service.py.


Phase 7: Update Documentation

Task 7.1: Update API documentation

  • Rename all "shop" references to "storefront"
  • Update endpoint paths

Task 7.2: Update architecture documentation

  • Document the layered architecture rule
  • Document module structure

Module Dependency Graph (Final State)

                    ┌─────────────┐
                    │    core     │
                    │  (tenancy)  │
                    └──────┬──────┘
                           │
              ┌────────────┼────────────┐
              │            │            │
              ▼            ▼            ▼
       ┌──────────┐  ┌──────────┐  ┌──────────┐
       │customers │  │ payments │  │messaging │
       │  (auth)  │  │          │  │          │
       └────┬─────┘  └────┬─────┘  └──────────┘
            │             │
            │    ┌────────┴────────┐
            │    │                 │
            ▼    ▼                 ▼
       ┌──────────┐          ┌──────────┐
       │   cart   │          │  orders  │
       │          │          │          │
       └────┬─────┘          └────┬─────┘
            │                     │
            └──────────┬──────────┘
                       │
                       ▼
                 ┌──────────┐
                 │ checkout │
                 │          │
                 └──────────┘

Execution Order

  1. Phase 1 - Add architecture rule (enables detection) COMPLETE
  2. Phase 2 - Rename shop → storefront (terminology) COMPLETE
  3. Phase 3 - Create new modules (cart, checkout, catalog) COMPLETE
  4. Phase 4 - Move routes to modules
  5. Phase 5 - Fix direct model imports
  6. Phase 6 - Delete legacy files
  7. Phase 7 - Update documentation

Files Modified Summary

New Files

  • .architecture-rules/api.yaml (modified - add API-007)
  • app/modules/cart/** (new module)
  • app/modules/checkout/** (new module)
  • app/modules/catalog/** (new module)
  • app/modules/customers/routes/api/storefront.py
  • app/modules/customers/schemas/context.py
  • app/modules/orders/routes/api/storefront.py
  • app/modules/messaging/routes/api/storefront.py

Deleted Files

  • app/api/v1/shop/ (entire directory)
  • app/routes/shop_pages.py
  • models/database/customer.py
  • app/services/cart_service.py

Modified Files

  • app/api/deps.py (CustomerContext return type)
  • scripts/validate_architecture.py (add API-007 check)
  • All files currently importing from legacy locations