docs: add session note for modular platform architecture
Documents the complete implementation of Phases 1-5: - Module foundation and registry - Menu integration and route protection - Billing, inventory, orders, marketplace module extractions - Admin UI for module management - Pending optional next steps Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,235 @@
|
|||||||
|
# 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")
|
||||||
|
└── vendor.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 | Companies, vendors, 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. Vendor Router Integration
|
||||||
|
Wire up vendor module routers to `app/api/v1/vendor/__init__.py`:
|
||||||
|
```python
|
||||||
|
from app.modules.billing.routes import vendor_router as billing_vendor_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`
|
||||||
Reference in New Issue
Block a user