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

@@ -25,7 +25,7 @@ from app.modules.marketplace.models import (
)
from app.modules.orders.models import Order, OrderItem
from app.modules.catalog.models import Product
from models.database.vendor import Vendor
from app.modules.tenancy.models import Vendor
logger = logging.getLogger(__name__)
@@ -627,7 +627,7 @@ class LetzshopOrderService:
vendor_lookup = {vendor_id: (vendor.name if vendor else None, vendor.vendor_code if vendor else None)}
else:
# Build lookup for all vendors when showing all jobs
from models.database.vendor import Vendor
from app.modules.tenancy.models import Vendor
vendors = self.db.query(Vendor.id, Vendor.name, Vendor.vendor_code).all()
vendor_lookup = {v.id: (v.name, v.vendor_code) for v in vendors}

View File

@@ -437,9 +437,9 @@ class LetzshopVendorSyncService:
from sqlalchemy import func
from app.modules.tenancy.services.admin_service import admin_service
from models.database.company import Company
from models.database.vendor import Vendor
from models.schema.vendor import VendorCreate
from app.modules.tenancy.models import Company
from app.modules.tenancy.models import Vendor
from app.modules.tenancy.schemas.vendor import VendorCreate
# Get cache entry
cache_entry = self.get_cached_vendor(letzshop_slug)

View File

@@ -12,8 +12,8 @@ from app.modules.marketplace.models import (
MarketplaceImportError,
MarketplaceImportJob,
)
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
from app.modules.marketplace.schemas import (
AdminMarketplaceImportJobResponse,
MarketplaceImportJobRequest,

View File

@@ -861,7 +861,7 @@ class MarketplaceProductService:
"""
from app.modules.catalog.models import Product
from app.modules.catalog.models import ProductTranslation
from models.database.vendor import Vendor
from app.modules.tenancy.models import Vendor
vendor = db.query(Vendor).filter(Vendor.id == vendor_id).first()
if not vendor:

View File

@@ -31,7 +31,7 @@ from app.modules.marketplace.models import (
OnboardingStep,
VendorOnboarding,
)
from models.database.vendor import Vendor
from app.modules.tenancy.models import Vendor
logger = logging.getLogger(__name__)

View File

@@ -26,15 +26,15 @@ from app.modules.messaging.services.email_service import EmailService
from app.modules.marketplace.services.onboarding_service import OnboardingService
from app.modules.billing.services.stripe_service import stripe_service
from middleware.auth import AuthManager
from models.database.company import Company
from app.modules.tenancy.models import Company
from app.modules.billing.models import (
SubscriptionStatus,
TierCode,
TIER_LIMITS,
VendorSubscription,
)
from models.database.user import User
from models.database.vendor import Vendor, VendorUser, VendorUserType
from app.modules.tenancy.models import User
from app.modules.tenancy.models import Vendor, VendorUser, VendorUserType
logger = logging.getLogger(__name__)