# Session Note: Modular Platform Architecture Implementation **Date:** 2026-01-25 **Plan Reference:** `docs/proposals/humble-orbiting-otter.md` --- ## Summary Implemented a complete modular platform architecture allowing platforms (OMS, Loyalty, etc.) to enable/disable feature modules. This creates a flexible system where different business products can have different feature sets. --- ## Completed Phases ### Phase 1: Module Foundation (Commit: `5be42c5`) Created the core module system: | File | Purpose | |------|---------| | `app/modules/__init__.py` | Package init | | `app/modules/base.py` | `ModuleDefinition` dataclass | | `app/modules/registry.py` | `MODULES` dict with 12 module definitions | | `app/modules/service.py` | `ModuleService` class for enablement checks | **Key concepts:** - Modules stored in `Platform.settings["enabled_modules"]` (JSON) - Core modules (`core`, `platform-admin`) cannot be disabled - Dependencies auto-resolved (e.g., marketplace requires inventory) ### Phase 2: Menu Integration & Route Protection (Commit: `cd65a59`) Added access control: | File | Changes | |------|---------| | `app/api/deps.py` | Added `require_module_access()` dependency | | `app/services/menu_service.py` | Filter menu items by enabled modules | | `app/routes/admin_pages.py` | Updated routes to use `require_menu_access()` | **31 unit tests** in `tests/unit/services/test_module_service.py` ### Phase 3: Billing Module Extraction (Commit: `c614b7d`) First module extraction as template: ``` app/modules/billing/ ├── __init__.py ├── definition.py # ModuleDefinition with lazy router loading └── routes/ ├── __init__.py ├── admin.py # Router with require_module_access("billing") └── store.py ``` ### Phase 4: Additional Module Extractions (Commit: `9d0dc51`) Extracted three more modules following the billing pattern: - `app/modules/inventory/` - Stock management - `app/modules/orders/` - Order management - `app/modules/marketplace/` - Letzshop integration (depends on inventory) Updated `app/api/v1/admin/__init__.py` to use module routers. ### Phase 5: Admin UI for Module Management (Commit: `7ecd554`) Created complete Admin UI: | File | Purpose | |------|---------| | `app/api/v1/admin/modules.py` | API endpoints for module CRUD | | `app/templates/admin/platform-modules.html` | Module configuration page | | `static/admin/js/platform-modules.js` | Alpine.js component | | `app/routes/admin_pages.py` | Added `/admin/platforms/{code}/modules` route | | `app/templates/admin/platform-detail.html` | Added link in Super Admin section | **API Endpoints:** - `GET /api/v1/admin/modules` - List all modules - `GET /api/v1/admin/modules/platforms/{id}` - Get platform modules - `PUT /api/v1/admin/modules/platforms/{id}` - Update modules - `POST /api/v1/admin/modules/platforms/{id}/enable` - Enable module - `POST /api/v1/admin/modules/platforms/{id}/disable` - Disable module - `POST /api/v1/admin/modules/platforms/{id}/enable-all` - Enable all - `POST /api/v1/admin/modules/platforms/{id}/disable-optional` - Core only --- ## Current Module Registry | Module | Type | Description | Dependencies | |--------|------|-------------|--------------| | `core` | Core | Dashboard, settings, profile | - | | `platform-admin` | Core | Merchants, stores, admin users | - | | `billing` | Optional | Subscriptions, tiers, billing | - | | `inventory` | Optional | Stock management, locations | - | | `orders` | Optional | Order management, fulfillment | - | | `marketplace` | Optional | Letzshop integration | inventory | | `customers` | Optional | Customer management, CRM | - | | `cms` | Optional | Content pages, media library | - | | `analytics` | Optional | Dashboard, reports, exports | - | | `messaging` | Optional | Messages, notifications | - | | `dev-tools` | Optional | Components, icons | - | | `monitoring` | Optional | Logs, background tasks | - | --- ## How It Works ### Module Enablement Flow 1. Super admin visits `/admin/platforms/{code}/modules` 2. Toggles modules on/off 3. API calls `module_service.enable_module()` or `disable_module()` 4. Dependencies auto-resolved 5. `Platform.settings["enabled_modules"]` updated ### Access Control Flow 1. User accesses route (e.g., `/api/v1/admin/billing/subscriptions`) 2. `require_module_access("billing")` dependency checks: - Gets platform from request context - Calls `module_service.is_module_enabled()` - Returns 403 if disabled 3. Menu items filtered by `module_service.filter_menu_items_by_modules()` --- ## Pending/Optional Next Steps ### 1. Store Router Integration Wire up store module routers to `app/api/v1/store/__init__.py`: ```python from app.modules.billing.routes import store_router as billing_store_router # ... etc ``` ### 2. Extract Remaining Modules Move inline modules to their own directories: - `customers` → `app/modules/customers/` - `cms` → `app/modules/cms/` - `analytics` → `app/modules/analytics/` - `messaging` → `app/modules/messaging/` - `dev-tools` → `app/modules/dev-tools/` - `monitoring` → `app/modules/monitoring/` ### 3. Database Table Migration (Optional) Create `PlatformModule` junction table for better auditability: ```python class PlatformModule(Base): platform_id = Column(Integer, ForeignKey("platforms.id")) module_code = Column(String(50)) is_enabled = Column(Boolean) enabled_at = Column(DateTime) enabled_by_user_id = Column(Integer, ForeignKey("users.id")) ``` ### 4. Module-Specific Configuration UI Add per-module config (stored in `Platform.settings["module_config"]`): ```json { "billing": {"stripe_mode": "live"}, "inventory": {"low_stock_threshold": 10} } ``` ### 5. Integration Tests Add tests for `/api/v1/admin/modules/*` endpoints. --- ## Key Files Reference ### Core Module System - `app/modules/base.py` - ModuleDefinition class - `app/modules/registry.py` - MODULES dict - `app/modules/service.py` - ModuleService ### Extracted Modules - `app/modules/billing/` - Billing module - `app/modules/inventory/` - Inventory module - `app/modules/orders/` - Orders module - `app/modules/marketplace/` - Marketplace module ### Access Control - `app/api/deps.py` - `require_module_access()` dependency - `app/services/menu_service.py` - Menu filtering ### Admin UI - `app/api/v1/admin/modules.py` - API endpoints - `app/templates/admin/platform-modules.html` - Template - `static/admin/js/platform-modules.js` - JavaScript ### Tests - `tests/unit/services/test_module_service.py` - 31 tests --- ## Git Commits (in order) ``` 5be42c5 feat: implement modular platform architecture (Phase 1) cd65a59 feat: implement module-based access control (Phase 2) c614b7d feat: extract billing module with routes (Phase 3) 9d0dc51 feat: extract inventory, orders, and marketplace modules (Phase 4) 7ecd554 feat: add Admin UI for platform module management (Phase 5) ``` --- ## Testing Run module service tests: ```bash python -m pytest tests/unit/services/test_module_service.py -v ``` Verify app starts: ```bash python -c "from main import app; print('OK')" ``` --- ## Access the Module UI 1. Login as super admin 2. Go to `/admin/platforms` 3. Click on a platform (e.g., OMS) 4. In "Super Admin" section, click "Module Configuration" 5. Toggle modules on/off Or directly: `/admin/platforms/oms/modules`