# models/database/__init__.py """ Database models package. 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//models/) Module Model Discovery: - Modules can define their own models in app/modules//models/ - These are automatically imported when this package loads - Module models must use `from app.core.database import Base` """ 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//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//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 # ============================================================================ __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", ]