refactor: complete module-driven architecture migration

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>
This commit is contained in:
2026-02-01 21:02:56 +01:00
parent 09d7d282c6
commit d7a0ff8818
307 changed files with 5536 additions and 3826 deletions

View File

@@ -147,7 +147,7 @@ class TestAdminUsersPlatformAssignmentAPI:
self, client, super_admin_headers, db, test_platform_admin, test_platform, test_super_admin
):
"""Test removing an admin from a platform."""
from models.database.admin_platform import AdminPlatform
from app.modules.tenancy.models import AdminPlatform
# First create an assignment
assignment = AdminPlatform(
@@ -172,7 +172,7 @@ class TestAdminUsersPlatformAssignmentAPI:
self, client, super_admin_headers, db, test_platform_admin, test_platform, test_super_admin
):
"""Test getting platforms for an admin."""
from models.database.admin_platform import AdminPlatform
from app.modules.tenancy.models import AdminPlatform
# Create assignment
assignment = AdminPlatform(
@@ -220,7 +220,7 @@ class TestAdminUsersSuperAdminToggleAPI:
self, client, super_admin_headers, db, auth_manager
):
"""Test demoting a super admin to platform admin."""
from models.database.user import User
from app.modules.tenancy.models import User
# Create another super admin to demote
another_super = User(
@@ -270,7 +270,7 @@ class TestAdminAuthPlatformSelectionAPI:
self, client, db, test_platform_admin, test_platform, test_super_admin, auth_manager
):
"""Test getting accessible platforms as platform admin."""
from models.database.admin_platform import AdminPlatform
from app.modules.tenancy.models import AdminPlatform
# Create assignment
assignment = AdminPlatform(
@@ -310,7 +310,7 @@ class TestAdminAuthPlatformSelectionAPI:
self, client, db, test_platform_admin, test_platform, test_super_admin
):
"""Test selecting a platform as platform admin."""
from models.database.admin_platform import AdminPlatform
from app.modules.tenancy.models import AdminPlatform
# Create assignment
assignment = AdminPlatform(

View File

@@ -3,7 +3,7 @@
import pytest
from models.database.admin import AdminSetting
from app.modules.tenancy.models import AdminSetting
# =============================================================================

View File

@@ -11,7 +11,7 @@ Tests verify that:
import pytest
from models.database.platform import Platform
from app.modules.tenancy.models import Platform
@pytest.mark.integration

View File

@@ -6,14 +6,14 @@ Tests the /api/v1/public/letzshop-vendors/* endpoints.
import pytest
from models.database.vendor import Vendor
from models.database.company import Company
from app.modules.tenancy.models import Vendor
from app.modules.tenancy.models import Company
@pytest.fixture
def test_owner_user(db, auth_manager):
"""Create a test owner user for the company."""
from models.database.user import User
from app.modules.tenancy.models import User
user = User(
email="owner@test.com",

View File

@@ -8,10 +8,10 @@ from unittest.mock import MagicMock, patch
import pytest
from models.database.company import Company
from app.modules.tenancy.models import Company
from app.modules.billing.models import TierCode
from models.database.user import User
from models.database.vendor import Vendor
from app.modules.tenancy.models import User
from app.modules.tenancy.models import Vendor
@pytest.fixture

View File

@@ -105,7 +105,7 @@ class TestVendorDashboardAPI:
"""Test dashboard stats for user not associated with any vendor"""
import uuid
from models.database.user import User
from app.modules.tenancy.models import User
# Create vendor user without vendor association
hashed_password = auth_manager.hash_password("testpass123")
@@ -136,7 +136,7 @@ class TestVendorDashboardAPI:
"""Test dashboard stats for inactive vendor"""
import uuid
from models.database.vendor import Vendor, VendorUser
from app.modules.tenancy.models import Vendor, VendorUser
# Create inactive vendor
unique_code = f"INACTIVE_{uuid.uuid4().hex[:8].upper()}"

View File

@@ -4,7 +4,7 @@
import pytest
from datetime import datetime, timezone
from models.database import VendorEmailSettings
from app.modules.messaging.models import VendorEmailSettings
# =============================================================================