refactor(migrations): squash 75 migrations into 12 per-module initial migrations

The old migration chain was broken (downgrade path through vendor->merchant
rename made rollbacks impossible). This squashes everything into fresh
per-module migrations with zero schema drift, verified by autogenerate.

Changes:
- Replace 75 accumulated migrations with 12 per-module initial migrations
  (core, billing, catalog, marketplace, cms, customers, orders, inventory,
  cart, messaging, loyalty, dev_tools) in a linear chain
- Fix make db-reset to use SQL DROP SCHEMA instead of alembic downgrade base
- Enable migration autodiscovery for all modules (migrations_path in definitions)
- Rewrite alembic/env.py to import all 75 model tables across 13 modules
- Fix AdminNotification import (was incorrectly from tenancy, now from messaging)
- Update squash_migrations.py to handle all module migration directories

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-08 11:51:37 +01:00
parent dad02695f6
commit c3d26e9aa4
111 changed files with 2285 additions and 11723 deletions

View File

@@ -29,170 +29,251 @@ from models.database.base import Base
# ============================================================================
# CRITICAL: Every model must be imported here so Alembic can detect tables!
# If a model is not imported, Alembic will not create/update its table.
#
# Models list must match: models/database/__init__.py
# ============================================================================
print("[ALEMBIC] Importing database models...")
print("=" * 70)
_import_errors = []
# ----------------------------------------------------------------------------
# ADMIN MODELS
# CORE MODULE (1 model)
# ----------------------------------------------------------------------------
try:
from app.modules.tenancy.models import (
from app.modules.core.models import AdminMenuConfig # noqa: F401
print(" ✓ Core models (1)")
except ImportError as e:
_import_errors.append(f"core: {e}")
print(f" ✗ Core models failed: {e}")
# ----------------------------------------------------------------------------
# TENANCY MODULE (15 models)
# ----------------------------------------------------------------------------
try:
from app.modules.tenancy.models import ( # noqa: F401
AdminAuditLog,
AdminNotification,
AdminPlatform,
AdminSession,
AdminSetting,
ApplicationLog,
Merchant,
Platform,
PlatformAlert,
PlatformModule,
Role,
Store,
StoreDomain,
StorePlatform,
StoreUser,
User,
)
print("Admin models imported (5 models)")
print(" - AdminAuditLog")
print(" - AdminNotification")
print(" - AdminSetting")
print(" - PlatformAlert")
print(" - AdminSession")
print("Tenancy models (15)")
except ImportError as e:
print(f" ✗ Admin models failed: {e}")
_import_errors.append(f"tenancy: {e}")
print(f" ✗ Tenancy models failed: {e}")
# ----------------------------------------------------------------------------
# USER MODEL
# BILLING MODULE (9 models)
# ----------------------------------------------------------------------------
try:
from app.modules.tenancy.models import User
from app.modules.billing.models import ( # noqa: F401
AddOnProduct,
BillingHistory,
CapacitySnapshot,
MerchantFeatureOverride,
MerchantSubscription,
StoreAddOn,
StripeWebhookEvent,
SubscriptionTier,
TierFeatureLimit,
)
print("User model imported")
print("Billing models (9)")
except ImportError as e:
print(f" ✗ User model failed: {e}")
_import_errors.append(f"billing: {e}")
print(f" ✗ Billing models failed: {e}")
# ----------------------------------------------------------------------------
# STORE MODELS
# CATALOG MODULE (3 models)
# ----------------------------------------------------------------------------
try:
from app.modules.tenancy.models import Role, Store, StoreUser
from app.modules.catalog.models import ( # noqa: F401
Product,
ProductMedia,
ProductTranslation,
)
print("Store models imported (3 models)")
print(" - Store")
print(" - StoreUser")
print(" - Role")
print("Catalog models (3)")
except ImportError as e:
print(f" ✗ Store models failed: {e}")
try:
from app.modules.tenancy.models import StoreDomain
print(" ✓ StoreDomain model imported")
except ImportError as e:
print(f" ✗ StoreDomain model failed: {e}")
try:
from app.modules.cms.models import StoreTheme
print(" ✓ StoreTheme model imported")
except ImportError as e:
print(f" ✗ StoreTheme model failed: {e}")
_import_errors.append(f"catalog: {e}")
print(f" ✗ Catalog models failed: {e}")
# ----------------------------------------------------------------------------
# CONTENT PAGE MODEL (CMS Module)
# MARKETPLACE MODULE (10 models)
# ----------------------------------------------------------------------------
try:
from app.modules.cms.models import ContentPage
from app.modules.marketplace.models import ( # noqa: F401
LetzshopFulfillmentQueue,
LetzshopHistoricalImportJob,
LetzshopStoreCache,
LetzshopSyncLog,
MarketplaceImportError,
MarketplaceImportJob,
MarketplaceProduct,
MarketplaceProductTranslation,
StoreLetzshopCredentials,
StoreOnboarding,
)
print("ContentPage model imported (from CMS module)")
print("Marketplace models (10)")
except ImportError as e:
print(f" ✗ ContentPage model failed: {e}")
_import_errors.append(f"marketplace: {e}")
print(f" ✗ Marketplace models failed: {e}")
# ----------------------------------------------------------------------------
# PRODUCT MODELS
# CMS MODULE (3 models)
# ----------------------------------------------------------------------------
try:
from app.modules.catalog.models import Product
from app.modules.cms.models import ( # noqa: F401
ContentPage,
MediaFile,
StoreTheme,
)
print("Product model imported")
print("CMS models (3)")
except ImportError as e:
print(f" ✗ Product model failed: {e}")
try:
from app.modules.marketplace.models import MarketplaceProduct
print(" ✓ MarketplaceProduct model imported")
except ImportError as e:
print(f" ✗ MarketplaceProduct model failed: {e}")
_import_errors.append(f"cms: {e}")
print(f" ✗ CMS models failed: {e}")
# ----------------------------------------------------------------------------
# INVENTORY MODEL
# CUSTOMERS MODULE (3 models)
# ----------------------------------------------------------------------------
try:
from app.modules.inventory.models import Inventory
from app.modules.customers.models import ( # noqa: F401
Customer,
CustomerAddress,
PasswordResetToken,
)
print("Inventory model imported")
print("Customers models (3)")
except ImportError as e:
print(f" ✗ Inventory model failed: {e}")
_import_errors.append(f"customers: {e}")
print(f" ✗ Customers models failed: {e}")
# ----------------------------------------------------------------------------
# MARKETPLACE IMPORT
# ORDERS MODULE (5 models)
# ----------------------------------------------------------------------------
try:
from app.modules.marketplace.models import MarketplaceImportJob
from app.modules.orders.models import ( # noqa: F401
Invoice,
Order,
OrderItem,
OrderItemException,
StoreInvoiceSettings,
)
print("MarketplaceImportJob model imported")
print("Orders models (5)")
except ImportError as e:
print(f" ✗ MarketplaceImportJob model failed: {e}")
_import_errors.append(f"orders: {e}")
print(f" ✗ Orders models failed: {e}")
# ----------------------------------------------------------------------------
# CUSTOMER MODELS
# INVENTORY MODULE (2 models)
# ----------------------------------------------------------------------------
try:
from app.modules.customers.models.customer import Customer, CustomerAddress
from app.modules.inventory.models import ( # noqa: F401
Inventory,
InventoryTransaction,
)
print("Customer models imported (2 models)")
print(" - Customer")
print(" - CustomerAddress")
print("Inventory models (2)")
except ImportError as e:
print(f" ✗ Customer models failed: {e}")
_import_errors.append(f"inventory: {e}")
print(f" ✗ Inventory models failed: {e}")
# ----------------------------------------------------------------------------
# CART MODELS
# CART MODULE (1 model)
# ----------------------------------------------------------------------------
try:
from app.modules.cart.models import CartItem
from app.modules.cart.models import CartItem # noqa: F401
print(" ✓ Cart models imported (1 model)")
print(" - CartItem")
print(" ✓ Cart models (1)")
except ImportError as e:
_import_errors.append(f"cart: {e}")
print(f" ✗ Cart models failed: {e}")
# ----------------------------------------------------------------------------
# ORDER MODELS
# MESSAGING MODULE (9 models)
# ----------------------------------------------------------------------------
try:
from app.modules.orders.models import Order, OrderItem
from app.modules.messaging.models import ( # noqa: F401
AdminNotification,
Conversation,
ConversationParticipant,
EmailLog,
EmailTemplate,
Message,
MessageAttachment,
StoreEmailSettings,
StoreEmailTemplate,
)
print("Order models imported (2 models)")
print(" - Order")
print(" - OrderItem")
print("Messaging models (9)")
except ImportError as e:
print(f" ✗ Order models failed: {e}")
_import_errors.append(f"messaging: {e}")
print(f" ✗ Messaging models failed: {e}")
# ----------------------------------------------------------------------------
# LOYALTY MODULE (6 models)
# ----------------------------------------------------------------------------
try:
from app.modules.loyalty.models import ( # noqa: F401
AppleDeviceRegistration,
LoyaltyCard,
LoyaltyProgram,
LoyaltyTransaction,
MerchantLoyaltySettings,
StaffPin,
)
print(" ✓ Loyalty models (6)")
except ImportError as e:
_import_errors.append(f"loyalty: {e}")
print(f" ✗ Loyalty models failed: {e}")
# ----------------------------------------------------------------------------
# DEV_TOOLS MODULE (8 models)
# ----------------------------------------------------------------------------
try:
from app.modules.dev_tools.models import ( # noqa: F401
ArchitectureRule,
ArchitectureScan,
ArchitectureViolation,
TestCollection,
TestResult,
TestRun,
ViolationAssignment,
ViolationComment,
)
print(" ✓ Dev Tools models (8)")
except ImportError as e:
_import_errors.append(f"dev_tools: {e}")
print(f" ✗ Dev Tools models failed: {e}")
# ============================================================================
# SUMMARY
# ============================================================================
print("=" * 70)
print("[ALEMBIC] Model import completed")
print("[ALEMBIC] Tables detected in metadata:")
print("=" * 70)
if Base.metadata.tables:
for i, table_name in enumerate(sorted(Base.metadata.tables.keys()), 1):
print(f" {i:2d}. {table_name}")
if _import_errors:
print(f"[ALEMBIC] WARNING: {len(_import_errors)} import error(s):")
for err in _import_errors:
print(f" - {err}")
print("=" * 70)
print(f"[ALEMBIC] Total tables: {len(Base.metadata.tables)}")
else:
print(" ⚠️ WARNING: No tables found in metadata!")
print(" This usually means models are not being imported correctly.")
print(f"[ALEMBIC] Total tables in metadata: {len(Base.metadata.tables)}")
print("=" * 70)
print()