This commit completes the migration to a fully module-driven architecture: ## Models Migration - Moved all domain models from models/database/ to their respective modules: - tenancy: User, Admin, Vendor, Company, Platform, VendorDomain, etc. - cms: MediaFile, VendorTheme - messaging: Email, VendorEmailSettings, VendorEmailTemplate - core: AdminMenuConfig - models/database/ now only contains Base and TimestampMixin (infrastructure) ## Schemas Migration - Moved all domain schemas from models/schema/ to their respective modules: - tenancy: company, vendor, admin, team, vendor_domain - cms: media, image, vendor_theme - messaging: email - models/schema/ now only contains base.py and auth.py (infrastructure) ## Routes Migration - Moved admin routes from app/api/v1/admin/ to modules: - menu_config.py -> core module - modules.py -> tenancy module - module_config.py -> tenancy module - app/api/v1/admin/ now only aggregates auto-discovered module routes ## Menu System - Implemented module-driven menu system with MenuDiscoveryService - Extended FrontendType enum: PLATFORM, ADMIN, VENDOR, STOREFRONT - Added MenuItemDefinition and MenuSectionDefinition dataclasses - Each module now defines its own menu items in definition.py - MenuService integrates with MenuDiscoveryService for template rendering ## Documentation - Updated docs/architecture/models-structure.md - Updated docs/architecture/menu-management.md - Updated architecture validation rules for new exceptions ## Architecture Validation - Updated MOD-019 rule to allow base.py in models/schema/ - Created core module exceptions.py and schemas/ directory - All validation errors resolved (only warnings remain) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Middleware Integration Tests
Overview
These tests verify that the middleware stack (VendorContextMiddleware, ThemeContextMiddleware, ContextMiddleware) works correctly through real HTTP requests.
Test Status
| Test File | Status | Tests |
|---|---|---|
test_vendor_context_flow.py |
✅ Passing | 9 tests |
test_theme_loading_flow.py |
✅ Passing | 14 tests |
test_middleware_stack.py |
✅ Passing | 10 tests |
test_context_detection_flow.py |
✅ Passing | 12 tests |
Total: 45 passing integration tests
Architecture
Pre-registered Test Routes
All test routes are defined in middleware_test_routes.py and registered at module load time. This avoids conflicts with catch-all routes in main.py.
Routes are organized by prefix:
/middleware-test/*- General middleware testing/api/middleware-test/*- API context testing/admin/middleware-test/*- Admin context testing/shop/middleware-test/*- Shop context testing
Test Fixtures (conftest.py)
The client fixture patches middleware dependencies for proper test isolation:
@pytest.fixture
def client(db):
with patch("middleware.vendor_context.get_db", override_get_db):
with patch("middleware.theme_context.get_db", override_get_db):
with patch("middleware.vendor_context.settings") as mock_settings:
mock_settings.platform_domain = "platform.com"
client = TestClient(app)
yield client
This ensures:
- Database isolation: Middleware uses the test database session
- Subdomain detection:
platform.comis used so hosts liketestvendor.platform.comwork correctly
Vendor Dashboard Context Testing
Vendor dashboard context detection (/vendor/* paths → VENDOR_DASHBOARD context) is tested via unit tests rather than integration tests because:
- The
/vendor/{vendor_code}/{slug}catch-all route inmain.pyintercepts/vendor/middleware-test/*paths - Unit tests in
tests/unit/middleware/test_context.pyprovide comprehensive coverage:test_detect_vendor_dashboard_contexttest_detect_vendor_dashboard_context_direct_pathtest_vendor_dashboard_priority_over_shoptest_middleware_sets_vendor_dashboard_context
Testing Patterns
Subdomain Detection
Use hosts ending in .platform.com:
response = client.get(
"/middleware-test/subdomain-detection",
headers={"host": "myvendor.platform.com"}
)
Custom Domain Detection
Custom domains require is_verified=True in the VendorDomain fixture:
domain = VendorDomain(
vendor_id=vendor.id,
domain="customdomain.com",
is_active=True,
is_primary=True,
is_verified=True # Required for detection
)
Context Type Verification
Routes return context information for assertions:
response = client.get("/api/middleware-test/context")
data = response.json()
assert data["context_type"] == "api"
assert data["context_enum"] == "API"
Theme Structure
Theme data uses nested structure:
theme["colors"]["primary"]- Primary colortheme["branding"]["logo"]- Logo URLtheme["custom_css"]- Custom CSS
Test routes flatten this for easier assertions:
data = response.json()
assert data["primary_color"] == "#FF5733" # Flattened from colors.primary