Move 9 init/seed scripts into scripts/seed/ and 7 validation scripts (+ validators/ subfolder) into scripts/validate/ to reduce clutter in the root scripts/ directory. Update all references across Makefile, CI/CD configs, pre-commit hooks, docs (~40 files), and Python imports. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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
- API routes import database models directly - violates layered architecture
- No architecture rule enforces this - validator doesn't catch it
- "shop" naming is misleading - not all platforms sell items
- 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/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 registrationPOST /auth/login- Customer loginPOST /auth/logout- Customer logoutPOST /auth/password-reset/request- Request password resetPOST /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 profilePUT /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 addressesPOST /addresses- Create addressPUT /addresses/{id}- Update addressDELETE /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
store_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
- Phase 1 - Add architecture rule (enables detection) ✅ COMPLETE
- Phase 2 - Rename shop → storefront (terminology) ✅ COMPLETE
- Phase 3 - Create new modules (cart, checkout, catalog) ✅ COMPLETE
- Phase 4 - Move routes to modules ✅ COMPLETE
- Phase 5 - Fix direct model imports ✅ COMPLETE
- Phase 6 - Delete legacy files ✅ COMPLETE
- Phase 7 - Update documentation ✅ COMPLETE
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.pyapp/modules/customers/schemas/context.pyapp/modules/orders/routes/api/storefront.pyapp/modules/messaging/routes/api/storefront.py
Deleted Files
app/api/v1/shop/(entire directory)app/routes/shop_pages.pymodels/database/customer.pyapp/services/cart_service.py
Modified Files
app/api/deps.py(CustomerContext return type)scripts/validate/validate_architecture.py(add API-007 check)- All files currently importing from legacy locations