MIGRATION:
- Delete app/api/v1/vendor/analytics.py (duplicate - analytics module already auto-discovered)
- Move usage routes from app/api/v1/vendor/usage.py to billing module
- Move onboarding routes from app/api/v1/vendor/onboarding.py to marketplace module
- Move features routes to billing module (admin + vendor)
- Move inventory routes to inventory module (admin + vendor)
- Move marketplace/letzshop routes to marketplace module
- Move orders routes to orders module
- Delete legacy letzshop service files (moved to marketplace module)
DOCUMENTATION:
- Add docs/development/migration/module-autodiscovery-migration.md with full migration history
- Update docs/architecture/module-system.md with Entity Auto-Discovery Reference section
- Add detailed sections for each entity type: routes, services, models, schemas, tasks,
exceptions, templates, static files, locales, configuration
ARCHITECTURE VALIDATION:
- Add MOD-016: Routes must be in modules, not app/api/v1/
- Add MOD-017: Services must be in modules, not app/services/
- Add MOD-018: Tasks must be in modules, not app/tasks/
- Add MOD-019: Schemas must be in modules, not models/schema/
- Update scripts/validate_architecture.py with _validate_legacy_locations method
- Update .architecture-rules/module.yaml with legacy location rules
These rules enforce that all entities must be in self-contained modules.
Legacy locations now trigger ERROR severity violations.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move admin/products.py to marketplace module as admin_products.py
(marketplace product catalog browsing)
- Move admin/vendor_products.py to catalog module as admin.py
(vendor catalog management)
- Move vendor/products.py to catalog module as vendor.py
(vendor's own product catalog)
- Update marketplace admin router to include products routes
- Update catalog module routes/api/__init__.py with lazy imports
- Remove legacy imports from admin and vendor API init files
All product routes now auto-discovered via module system.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Enhanced route discovery system with ROUTE_CONFIG support for custom
prefix, tags, and priority
- Added get_admin_api_routes() and get_vendor_api_routes() helpers that
return routes sorted by priority
- Added fallback discovery for routes/{frontend}.py when routes/api/
doesn't exist
- Updated CMS module with ROUTE_CONFIG (prefix: /content-pages,
priority: 100) to register last for catch-all routes
- Moved customers routes from routes/ to routes/api/ directory
- Updated orders module to aggregate exception routers into main routers
- Removed manual module router imports from admin and vendor API init
files, replaced with auto-discovery loop
Modules now auto-discovered: billing, inventory, orders, marketplace,
cms, customers, analytics, loyalty, messaging, monitoring, dev-tools
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Delete app/api/v1/admin/customers.py (no backward compatibility)
- Delete app/api/v1/vendor/customers.py (no backward compatibility)
- Remove legacy router aliases from module routes
- Routes now fully self-contained in app/modules/customers/routes/
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move customer route implementations to app/modules/customers/routes/
- Convert legacy app/api/v1/{admin,vendor}/customers.py to re-exports
- Update router registrations to use module routers with access control
- Fix CustomerListResponse pagination (page/per_page/total_pages)
- Update URL routing docs to use storefront consistently
- Fix mkdocs.yml nav references (shop -> storefront)
- Fix broken doc links in logging.md and cdn-fallback-strategy.md
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Media library management is part of content management (CMS).
This matches the Python pattern where:
- Core media service (upload, storage) stays in platform
- Media library UI (browsing, organizing) goes to CMS module
- Media picker component stays shared (used by products, CMS, etc.)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
components.js is a UI components library reference for developers,
so it belongs in dev_tools alongside icons-page.js, testing-*.js,
and code-quality-*.js.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
icons-page.js is a dev tool for browsing available icons, so it
belongs in dev_tools alongside testing-*.js and code-quality-*.js.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
users.js, user-detail.js, user-edit.js, user-create.js are for
managing platform/vendor users, not shop customers. Move them
back to static/admin/js/ where other platform admin files reside.
The customers module retains customers.js which manages actual
shop customers (people who buy from vendors).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move Feature model from models/database/ to app/modules/billing/models/
(tightly coupled to SubscriptionTier for tier-based access control)
- Move ProductMedia from models/database/media.py to app/modules/catalog/models/
(product-specific media associations belong with catalog)
- Keep MediaFile as CORE in models/database/media.py (cross-cutting file storage)
- Convert legacy feature.py to re-export for backwards compatibility
- Update all imports to use canonical module locations
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix cart to import from app.modules.base instead of non-existent
app.modules.core.module_registry
- Change 'dependencies' to 'requires' (correct attribute name)
- Remove invalid 'provides_*' attributes that don't exist in
ModuleDefinition dataclass
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update models/database/__init__.py to import from module locations
- Update models/schema/__init__.py to remove deleted modules
- Update models/__init__.py to import Inventory from module
- Remove duplicate AdminNotification from models/database/admin.py
- Fix monitoring module to import AdminNotification from messaging
- Update stats schema imports in admin/vendor API
- Update notification schema imports
- Add order_item_exception.py schema to orders module
- Fix app/api/v1/__init__.py to use storefront instead of shop
- Add cms_admin_pages import to main.py
- Fix password_reset_token imports
- Fix AdminNotification test imports
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update all module files to import from canonical module locations
instead of legacy re-export files:
- checkout, orders, customers routes: use module schemas
- catalog, marketplace schemas: use inventory module schemas
- marketplace, customers, inventory, analytics services: use module models
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 5 of storefront restructure plan - fix direct model imports in
API routes by using schemas for dependency injection.
Created CustomerContext schema:
- Lightweight Pydantic model for customer data in API routes
- Populated from Customer DB model in auth dependency
- Contains all fields needed by storefront routes
- Includes from_db_model() factory method
Updated app/api/deps.py:
- _validate_customer_token now returns CustomerContext instead of Customer
- Updated docstrings for all customer auth functions
Updated module storefront routes:
- customers: Uses CustomerContext for profile/address endpoints
- orders: Uses CustomerContext for order history endpoints
- checkout: Uses CustomerContext for order placement
- messaging: Uses CustomerContext for messaging endpoints
This enforces the layered architecture (Routes → Services → Models)
by ensuring API routes never import database models directly.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 4 of storefront restructure plan - move API routes from legacy
app/api/v1/storefront/ to their respective modules:
- customers: auth, profile, addresses routes combined into storefront.py
- orders: order history viewing routes
- checkout: order placement (place_order endpoint)
- messaging: customer messaging routes
Updated app/api/v1/storefront/__init__.py to import from modules:
- cart_router from app.modules.cart
- catalog_router from app.modules.catalog
- checkout_router from app.modules.checkout
- customers_router from app.modules.customers
- orders_router from app.modules.orders
- messaging_router from app.modules.messaging
Legacy route files in app/api/v1/storefront/ can now be deleted
in Phase 6.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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>
Rename "shop" to "storefront" as not all platforms sell items -
storefront is a more accurate term for the customer-facing interface.
Changes:
- Rename app/api/v1/shop/ → app/api/v1/storefront/
- Rename app/routes/shop_pages.py → app/routes/storefront_pages.py
- Rename app/modules/cms/routes/api/shop.py → storefront.py
- Rename tests/integration/api/v1/shop/ → storefront/
- Update API prefix from /api/v1/shop to /api/v1/storefront
- Update route tags from shop-* to storefront-*
- Rename get_shop_context() → get_storefront_context()
- Update architecture rules to reference storefront paths
- Update all test API endpoint paths
This is Phase 2 of the storefront module restructure plan.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add architecture rule that detects when API routes import database
models directly, enforcing Routes → Services → Models pattern.
Changes:
- Add API-007 rule to .architecture-rules/api.yaml
- Add _check_no_model_imports() validation to validator script
- Update customer imports to use canonical module location
- Add storefront module restructure implementation plan
The validator now detects 81 violations across 67 API files where
database models are imported directly instead of going through
services. This is Phase 1 of the storefront restructure plan.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- app/modules/registry.py: Use auto-discovery from discovery.py
- main.py: Integrate module route auto-discovery
- app/routes/vendor_pages.py: Remove routes now handled by modules
The registry now dynamically discovers modules from definition.py
files instead of hardcoded imports.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add self-contained configuration and migrations support for modules:
Config auto-discovery (app/modules/config.py):
- Modules can have config.py with Pydantic Settings
- Environment variables prefixed with MODULE_NAME_
- Auto-discovered via get_module_config()
Migrations auto-discovery:
- Each module has migrations/versions/ directory
- Alembic discovers module migrations automatically
- Naming convention: {module}_{seq}_{description}.py
New architecture rules (MOD-013 to MOD-015):
- MOD-013: config.py should export config/config_class
- MOD-014: Migrations must follow naming convention
- MOD-015: Migrations directory must have __init__.py
Created for all 11 self-contained modules:
- config.py placeholder files
- migrations/ directories with __init__.py files
Added core and tenancy module definitions for completeness.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 4 of module migration plan:
- Add ScheduledTask dataclass for declaring Celery Beat tasks
- Add tasks_path and scheduled_tasks fields to ModuleDefinition
- Create ModuleTask base class with database session management
- Create task discovery utilities (discover_module_tasks, build_beat_schedule)
- Update celery_config.py to discover and register module tasks
- Maintain backward compatibility with legacy task modules
Modules can now define tasks in their tasks/ directory and scheduled
tasks in their definition. The infrastructure supports gradual migration
of existing tasks from app/tasks/ to their respective modules.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Transform CMS from a thin wrapper into a fully self-contained module with
all code living within app/modules/cms/:
Module Structure:
- models/: ContentPage model (canonical location with dynamic discovery)
- schemas/: Pydantic schemas for API validation
- services/: ContentPageService business logic
- exceptions/: Module-specific exceptions
- routes/api/: REST API endpoints (admin, vendor, shop)
- routes/pages/: HTML page routes (admin, vendor)
- templates/cms/: Jinja2 templates (namespaced)
- static/: JavaScript files (admin/vendor)
- locales/: i18n translations (en, fr, de, lb)
Key Changes:
- Move ContentPage model to module with dynamic model discovery
- Create Pydantic schemas package for request/response validation
- Extract API routes from app/api/v1/*/ to module
- Extract page routes from admin_pages.py/vendor_pages.py to module
- Move static JS files to module with dedicated mount point
- Update templates to use cms_static for module assets
- Add module static file mounting in main.py
- Delete old scattered files (no shims - hard errors on old imports)
This establishes the pattern for migrating other modules to be
fully autonomous and independently deployable.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 1 - Foundation:
- Add app/modules/contracts/ with Protocol definitions for cross-module
communication (ServiceProtocol, ContentServiceProtocol, MediaServiceProtocol)
- Enhance app/modules/base.py ModuleDefinition with self-contained module
support (is_self_contained, services_path, models_path, etc.)
- Update app/templates_config.py with multi-directory template loading
using Jinja2 ChoiceLoader for module templates
Phase 2 - CMS Pilot Module:
- Migrate CMS service to app/modules/cms/services/content_page_service.py
- Create app/modules/cms/exceptions.py with CMS-specific exceptions
- Configure app/modules/cms/models/ to re-export ContentPage from canonical
location (models.database) to avoid circular imports
- Update cms_module definition with is_self_contained=True and paths
- Add backwards compatibility shims with deprecation warnings:
- app/services/content_page_service.py -> app.modules.cms.services
- app/exceptions/content_page.py -> app.modules.cms.exceptions
Note: SQLAlchemy models remain in models/database/ as the canonical location
to avoid circular imports at startup time. Module model packages re-export
from the canonical location.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Extract three additional modules following the billing module pattern:
Inventory Module (app/modules/inventory/):
- Stock management and tracking
- Inventory locations
- Low stock alerts
- Admin and vendor routes with module access control
Orders Module (app/modules/orders/):
- Order management and fulfillment
- Order item exceptions
- Bulk operations and export
- Admin and vendor routes with module access control
Marketplace Module (app/modules/marketplace/):
- Letzshop integration
- Product sync
- Marketplace import
- Depends on inventory module
- Admin and vendor routes with module access control
Admin router updated:
- Uses module routers with require_module_access dependency
- Legacy router includes commented out
- Routes verified: 15 inventory, 16 orders, 42 marketplace
All 31 module tests passing.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>