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:
@@ -1,256 +1,30 @@
|
||||
# models/database/__init__.py
|
||||
"""
|
||||
Database models package.
|
||||
Database models package - Base classes and mixins only.
|
||||
|
||||
This package imports all SQLAlchemy models to ensure they are registered
|
||||
with Base.metadata. This includes:
|
||||
1. Core models (defined in this directory)
|
||||
2. Module models (discovered from app/modules/<module>/models/)
|
||||
This package provides the base infrastructure for SQLAlchemy models:
|
||||
- Base: SQLAlchemy declarative base
|
||||
- TimestampMixin: Mixin for created_at/updated_at timestamps
|
||||
|
||||
Module Model Discovery:
|
||||
- Modules can define their own models in app/modules/<module>/models/
|
||||
- These are automatically imported when this package loads
|
||||
- Module models must use `from app.core.database import Base`
|
||||
IMPORTANT: Domain models have been migrated to their respective modules:
|
||||
- Tenancy models: app.modules.tenancy.models
|
||||
- Catalog models: app.modules.catalog.models
|
||||
- Orders models: app.modules.orders.models
|
||||
- Inventory models: app.modules.inventory.models
|
||||
- Billing models: app.modules.billing.models
|
||||
- Messaging models: app.modules.messaging.models
|
||||
- CMS models: app.modules.cms.models
|
||||
- Marketplace models: app.modules.marketplace.models
|
||||
- Customers models: app.modules.customers.models
|
||||
- Dev Tools models: app.modules.dev_tools.models
|
||||
- Core models: app.modules.core.models
|
||||
|
||||
Import models from their canonical module locations instead of this package.
|
||||
"""
|
||||
|
||||
import importlib
|
||||
import logging
|
||||
from pathlib import Path
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# ============================================================================
|
||||
# CORE MODELS (always loaded)
|
||||
# ============================================================================
|
||||
|
||||
from .admin import (
|
||||
AdminAuditLog,
|
||||
AdminSession,
|
||||
AdminSetting,
|
||||
PlatformAlert,
|
||||
)
|
||||
from app.modules.messaging.models import AdminNotification
|
||||
from .admin_menu_config import AdminMenuConfig, FrontendType, MANDATORY_MENU_ITEMS
|
||||
from .admin_platform import AdminPlatform
|
||||
from app.modules.dev_tools.models import (
|
||||
ArchitectureScan,
|
||||
ArchitectureViolation,
|
||||
ViolationAssignment,
|
||||
ViolationComment,
|
||||
)
|
||||
from .base import Base
|
||||
from .company import Company
|
||||
from .platform import Platform
|
||||
from .platform_module import PlatformModule
|
||||
from .vendor_platform import VendorPlatform
|
||||
from app.modules.customers.models import Customer, CustomerAddress
|
||||
from app.modules.customers.models import PasswordResetToken
|
||||
from .email import EmailCategory, EmailLog, EmailStatus, EmailTemplate
|
||||
from .vendor_email_template import VendorEmailTemplate
|
||||
from .vendor_email_settings import EmailProvider, VendorEmailSettings, PREMIUM_EMAIL_PROVIDERS
|
||||
from app.modules.billing.models import Feature, FeatureCategory, FeatureCode, FeatureUILocation
|
||||
from app.modules.inventory.models import Inventory
|
||||
from app.modules.inventory.models import InventoryTransaction, TransactionType
|
||||
from app.modules.orders.models import (
|
||||
Invoice,
|
||||
InvoiceStatus,
|
||||
VATRegime,
|
||||
VendorInvoiceSettings,
|
||||
)
|
||||
from app.modules.marketplace.models import (
|
||||
LetzshopFulfillmentQueue,
|
||||
LetzshopHistoricalImportJob,
|
||||
LetzshopSyncLog,
|
||||
VendorLetzshopCredentials,
|
||||
MarketplaceImportError,
|
||||
MarketplaceImportJob,
|
||||
DigitalDeliveryMethod,
|
||||
MarketplaceProduct,
|
||||
ProductType,
|
||||
MarketplaceProductTranslation,
|
||||
)
|
||||
from app.modules.messaging.models import (
|
||||
Conversation,
|
||||
ConversationParticipant,
|
||||
ConversationType,
|
||||
Message,
|
||||
MessageAttachment,
|
||||
ParticipantType,
|
||||
)
|
||||
from .media import MediaFile
|
||||
from app.modules.catalog.models import ProductMedia
|
||||
from app.modules.marketplace.models import OnboardingStatus, OnboardingStep, VendorOnboarding
|
||||
from app.modules.orders.models import Order, OrderItem
|
||||
from app.modules.orders.models import OrderItemException
|
||||
from app.modules.catalog.models import Product, ProductTranslation
|
||||
from app.modules.billing.models import (
|
||||
AddOnCategory,
|
||||
AddOnProduct,
|
||||
BillingHistory,
|
||||
BillingPeriod,
|
||||
StripeWebhookEvent,
|
||||
SubscriptionStatus,
|
||||
SubscriptionTier,
|
||||
TierCode,
|
||||
TIER_LIMITS,
|
||||
VendorAddOn,
|
||||
VendorSubscription,
|
||||
)
|
||||
from app.modules.dev_tools.models import TestCollection, TestResult, TestRun
|
||||
from .user import User
|
||||
from .vendor import Role, Vendor, VendorUser
|
||||
from .vendor_domain import VendorDomain
|
||||
from .vendor_theme import VendorTheme
|
||||
|
||||
# ============================================================================
|
||||
# MODULE MODELS (dynamically discovered)
|
||||
# ============================================================================
|
||||
|
||||
|
||||
def _discover_module_models():
|
||||
"""
|
||||
Discover and import models from app/modules/<module>/models/ directories.
|
||||
|
||||
This ensures module models are registered with Base.metadata for:
|
||||
1. Alembic migrations
|
||||
2. SQLAlchemy queries
|
||||
|
||||
Module models must:
|
||||
- Be in app/modules/<module>/models/__init__.py or individual files
|
||||
- Import Base from app.core.database
|
||||
"""
|
||||
modules_dir = Path(__file__).parent.parent.parent / "app" / "modules"
|
||||
|
||||
if not modules_dir.exists():
|
||||
return
|
||||
|
||||
for module_dir in sorted(modules_dir.iterdir()):
|
||||
if not module_dir.is_dir():
|
||||
continue
|
||||
|
||||
models_init = module_dir / "models" / "__init__.py"
|
||||
if models_init.exists():
|
||||
module_name = f"app.modules.{module_dir.name}.models"
|
||||
try:
|
||||
importlib.import_module(module_name)
|
||||
logger.debug(f"[Models] Loaded module models: {module_name}")
|
||||
except ImportError as e:
|
||||
logger.warning(f"[Models] Failed to import {module_name}: {e}")
|
||||
|
||||
|
||||
# Run discovery at import time
|
||||
_discover_module_models()
|
||||
|
||||
# ============================================================================
|
||||
# EXPORTS
|
||||
# ============================================================================
|
||||
from .base import Base, TimestampMixin
|
||||
|
||||
__all__ = [
|
||||
# Admin-specific models
|
||||
"AdminAuditLog",
|
||||
"AdminMenuConfig",
|
||||
"FrontendType",
|
||||
"AdminNotification",
|
||||
"AdminPlatform",
|
||||
"AdminSetting",
|
||||
"MANDATORY_MENU_ITEMS",
|
||||
"PlatformAlert",
|
||||
"AdminSession",
|
||||
# Architecture/Code Quality
|
||||
"ArchitectureScan",
|
||||
"ArchitectureViolation",
|
||||
"ViolationAssignment",
|
||||
"ViolationComment",
|
||||
# Test Runs
|
||||
"TestRun",
|
||||
"TestResult",
|
||||
"TestCollection",
|
||||
# Base
|
||||
"Base",
|
||||
# User & Auth
|
||||
"User",
|
||||
# Company & Vendor
|
||||
"Company",
|
||||
"Vendor",
|
||||
"VendorUser",
|
||||
"Role",
|
||||
"VendorDomain",
|
||||
"VendorTheme",
|
||||
# Platform
|
||||
"Platform",
|
||||
"PlatformModule",
|
||||
"VendorPlatform",
|
||||
# Customer & Auth
|
||||
"Customer",
|
||||
"CustomerAddress",
|
||||
"PasswordResetToken",
|
||||
# Email
|
||||
"EmailCategory",
|
||||
"EmailLog",
|
||||
"EmailStatus",
|
||||
"EmailTemplate",
|
||||
"VendorEmailTemplate",
|
||||
"VendorEmailSettings",
|
||||
"EmailProvider",
|
||||
"PREMIUM_EMAIL_PROVIDERS",
|
||||
# Features
|
||||
"Feature",
|
||||
"FeatureCategory",
|
||||
"FeatureCode",
|
||||
"FeatureUILocation",
|
||||
# Product - Enums
|
||||
"ProductType",
|
||||
"DigitalDeliveryMethod",
|
||||
# Product - Models
|
||||
"MarketplaceProduct",
|
||||
"MarketplaceProductTranslation",
|
||||
"Product",
|
||||
"ProductTranslation",
|
||||
# Import
|
||||
"MarketplaceImportJob",
|
||||
"MarketplaceImportError",
|
||||
# Inventory
|
||||
"Inventory",
|
||||
"InventoryTransaction",
|
||||
"TransactionType",
|
||||
# Media
|
||||
"MediaFile",
|
||||
"ProductMedia",
|
||||
# Invoicing
|
||||
"Invoice",
|
||||
"InvoiceStatus",
|
||||
"VATRegime",
|
||||
"VendorInvoiceSettings",
|
||||
# Orders
|
||||
"Order",
|
||||
"OrderItem",
|
||||
"OrderItemException",
|
||||
# Letzshop Integration
|
||||
"VendorLetzshopCredentials",
|
||||
"LetzshopFulfillmentQueue",
|
||||
"LetzshopSyncLog",
|
||||
"LetzshopHistoricalImportJob",
|
||||
# Subscription & Billing
|
||||
"VendorSubscription",
|
||||
"SubscriptionStatus",
|
||||
"SubscriptionTier",
|
||||
"TierCode",
|
||||
"TIER_LIMITS",
|
||||
"AddOnProduct",
|
||||
"AddOnCategory",
|
||||
"BillingPeriod",
|
||||
"VendorAddOn",
|
||||
"BillingHistory",
|
||||
"StripeWebhookEvent",
|
||||
# Messaging
|
||||
"Conversation",
|
||||
"ConversationParticipant",
|
||||
"ConversationType",
|
||||
"Message",
|
||||
"MessageAttachment",
|
||||
"ParticipantType",
|
||||
# Onboarding
|
||||
"OnboardingStatus",
|
||||
"OnboardingStep",
|
||||
"VendorOnboarding",
|
||||
"TimestampMixin",
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user