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:
@@ -85,6 +85,7 @@ dev_tools_module = ModuleDefinition(
|
||||
schemas_path="app.modules.dev_tools.schemas",
|
||||
exceptions_path="app.modules.dev_tools.exceptions",
|
||||
tasks_path="app.modules.dev_tools.tasks",
|
||||
migrations_path="migrations",
|
||||
# Note: Code quality and test tasks are on-demand, not scheduled.
|
||||
# If scheduled scans are desired, add ScheduledTask entries here.
|
||||
)
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
"""dev_tools initial - test runs, architecture scans, violations
|
||||
|
||||
Revision ID: dev_tools_001
|
||||
Revises: loyalty_001
|
||||
Create Date: 2026-02-07
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
revision = "dev_tools_001"
|
||||
down_revision = "loyalty_001"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# --- test_runs ---
|
||||
op.create_table(
|
||||
"test_runs",
|
||||
sa.Column("id", sa.Integer(), primary_key=True, index=True),
|
||||
sa.Column("timestamp", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False, index=True),
|
||||
sa.Column("total_tests", sa.Integer(), nullable=True),
|
||||
sa.Column("passed", sa.Integer(), nullable=True),
|
||||
sa.Column("failed", sa.Integer(), nullable=True),
|
||||
sa.Column("errors", sa.Integer(), nullable=True),
|
||||
sa.Column("skipped", sa.Integer(), nullable=True),
|
||||
sa.Column("xfailed", sa.Integer(), nullable=True),
|
||||
sa.Column("xpassed", sa.Integer(), nullable=True),
|
||||
sa.Column("coverage_percent", sa.Float(), nullable=True),
|
||||
sa.Column("duration_seconds", sa.Float(), nullable=True),
|
||||
sa.Column("triggered_by", sa.String(100), nullable=True),
|
||||
sa.Column("git_commit_hash", sa.String(40), nullable=True),
|
||||
sa.Column("git_branch", sa.String(100), nullable=True),
|
||||
sa.Column("test_path", sa.String(500), nullable=True),
|
||||
sa.Column("pytest_args", sa.String(500), nullable=True),
|
||||
sa.Column("status", sa.String(20), nullable=True, server_default="running", index=True),
|
||||
sa.Column("celery_task_id", sa.String(255), nullable=True, index=True),
|
||||
)
|
||||
|
||||
# --- test_results ---
|
||||
op.create_table(
|
||||
"test_results",
|
||||
sa.Column("id", sa.Integer(), primary_key=True, index=True),
|
||||
sa.Column("run_id", sa.Integer(), sa.ForeignKey("test_runs.id"), nullable=False, index=True),
|
||||
sa.Column("node_id", sa.String(500), nullable=False, index=True),
|
||||
sa.Column("test_name", sa.String(200), nullable=False),
|
||||
sa.Column("test_file", sa.String(300), nullable=False),
|
||||
sa.Column("test_class", sa.String(200), nullable=True),
|
||||
sa.Column("outcome", sa.String(20), nullable=False, index=True),
|
||||
sa.Column("duration_seconds", sa.Float(), nullable=True),
|
||||
sa.Column("error_message", sa.Text(), nullable=True),
|
||||
sa.Column("traceback", sa.Text(), nullable=True),
|
||||
sa.Column("markers", sa.JSON(), nullable=True),
|
||||
sa.Column("parameters", sa.JSON(), nullable=True),
|
||||
sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
|
||||
)
|
||||
|
||||
# --- test_collections ---
|
||||
op.create_table(
|
||||
"test_collections",
|
||||
sa.Column("id", sa.Integer(), primary_key=True, index=True),
|
||||
sa.Column("total_tests", sa.Integer(), nullable=True),
|
||||
sa.Column("total_files", sa.Integer(), nullable=True),
|
||||
sa.Column("total_classes", sa.Integer(), nullable=True),
|
||||
sa.Column("unit_tests", sa.Integer(), nullable=True),
|
||||
sa.Column("integration_tests", sa.Integer(), nullable=True),
|
||||
sa.Column("performance_tests", sa.Integer(), nullable=True),
|
||||
sa.Column("system_tests", sa.Integer(), nullable=True),
|
||||
sa.Column("test_files", sa.JSON(), nullable=True),
|
||||
sa.Column("collected_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
|
||||
)
|
||||
|
||||
# --- architecture_scans ---
|
||||
op.create_table(
|
||||
"architecture_scans",
|
||||
sa.Column("id", sa.Integer(), primary_key=True, index=True),
|
||||
sa.Column("timestamp", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False, index=True),
|
||||
sa.Column("validator_type", sa.String(20), nullable=False, server_default="architecture", index=True),
|
||||
sa.Column("status", sa.String(30), nullable=False, server_default="pending", index=True),
|
||||
sa.Column("started_at", sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column("completed_at", sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column("error_message", sa.Text(), nullable=True),
|
||||
sa.Column("progress_message", sa.String(255), nullable=True),
|
||||
sa.Column("total_files", sa.Integer(), nullable=True),
|
||||
sa.Column("total_violations", sa.Integer(), nullable=True),
|
||||
sa.Column("errors", sa.Integer(), nullable=True),
|
||||
sa.Column("warnings", sa.Integer(), nullable=True),
|
||||
sa.Column("duration_seconds", sa.Float(), nullable=True),
|
||||
sa.Column("triggered_by", sa.String(100), nullable=True),
|
||||
sa.Column("git_commit_hash", sa.String(40), nullable=True),
|
||||
sa.Column("celery_task_id", sa.String(255), nullable=True, index=True),
|
||||
)
|
||||
|
||||
# --- architecture_violations ---
|
||||
op.create_table(
|
||||
"architecture_violations",
|
||||
sa.Column("id", sa.Integer(), primary_key=True, index=True),
|
||||
sa.Column("scan_id", sa.Integer(), sa.ForeignKey("architecture_scans.id"), nullable=False, index=True),
|
||||
sa.Column("validator_type", sa.String(20), nullable=False, server_default="architecture", index=True),
|
||||
sa.Column("rule_id", sa.String(20), nullable=False, index=True),
|
||||
sa.Column("rule_name", sa.String(200), nullable=False),
|
||||
sa.Column("severity", sa.String(10), nullable=False, index=True),
|
||||
sa.Column("file_path", sa.String(500), nullable=False, index=True),
|
||||
sa.Column("line_number", sa.Integer(), nullable=False),
|
||||
sa.Column("message", sa.Text(), nullable=False),
|
||||
sa.Column("context", sa.Text(), nullable=True),
|
||||
sa.Column("suggestion", sa.Text(), nullable=True),
|
||||
sa.Column("status", sa.String(20), nullable=True, server_default="open", index=True),
|
||||
sa.Column("assigned_to", sa.Integer(), sa.ForeignKey("users.id"), nullable=True),
|
||||
sa.Column("resolved_at", sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column("resolved_by", sa.Integer(), sa.ForeignKey("users.id"), nullable=True),
|
||||
sa.Column("resolution_note", sa.Text(), nullable=True),
|
||||
sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
|
||||
)
|
||||
|
||||
# --- architecture_rules ---
|
||||
op.create_table(
|
||||
"architecture_rules",
|
||||
sa.Column("id", sa.Integer(), primary_key=True, index=True),
|
||||
sa.Column("rule_id", sa.String(20), unique=True, nullable=False, index=True),
|
||||
sa.Column("validator_type", sa.String(20), nullable=False, server_default="architecture", index=True),
|
||||
sa.Column("category", sa.String(50), nullable=False),
|
||||
sa.Column("name", sa.String(200), nullable=False),
|
||||
sa.Column("description", sa.Text(), nullable=True),
|
||||
sa.Column("severity", sa.String(10), nullable=False),
|
||||
sa.Column("enabled", sa.Boolean(), nullable=False, server_default="true"),
|
||||
sa.Column("custom_config", sa.JSON(), nullable=True),
|
||||
sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
|
||||
sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
|
||||
)
|
||||
|
||||
# --- violation_assignments ---
|
||||
op.create_table(
|
||||
"violation_assignments",
|
||||
sa.Column("id", sa.Integer(), primary_key=True, index=True),
|
||||
sa.Column("violation_id", sa.Integer(), sa.ForeignKey("architecture_violations.id"), nullable=False, index=True),
|
||||
sa.Column("user_id", sa.Integer(), sa.ForeignKey("users.id"), nullable=False),
|
||||
sa.Column("assigned_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
|
||||
sa.Column("assigned_by", sa.Integer(), sa.ForeignKey("users.id"), nullable=True),
|
||||
sa.Column("due_date", sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column("priority", sa.String(10), nullable=True),
|
||||
)
|
||||
|
||||
# --- violation_comments ---
|
||||
op.create_table(
|
||||
"violation_comments",
|
||||
sa.Column("id", sa.Integer(), primary_key=True, index=True),
|
||||
sa.Column("violation_id", sa.Integer(), sa.ForeignKey("architecture_violations.id"), nullable=False, index=True),
|
||||
sa.Column("user_id", sa.Integer(), sa.ForeignKey("users.id"), nullable=False),
|
||||
sa.Column("comment", sa.Text(), nullable=False),
|
||||
sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_table("violation_comments")
|
||||
op.drop_table("violation_assignments")
|
||||
op.drop_table("architecture_rules")
|
||||
op.drop_table("architecture_violations")
|
||||
op.drop_table("architecture_scans")
|
||||
op.drop_table("test_collections")
|
||||
op.drop_table("test_results")
|
||||
op.drop_table("test_runs")
|
||||
Reference in New Issue
Block a user