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