"""Version Accounting Mirrors per Client + Financial Year. Revision ID: 20260918_accounting_mirror_ver Revises: 20260918_accounting_mirror_reg """ from alembic import op import sqlalchemy as sa revision = "20260918_accounting_mirror_ver" down_revision = "20260918_accounting_mirror_reg" branch_labels = None depends_on = None def upgrade() -> None: bind = op.get_bind() inspector = sa.inspect(bind) columns = {c["name"] for c in inspector.get_columns("accounting_mirror_registry")} if "version_no" not in columns: op.add_column("accounting_mirror_registry", sa.Column("version_no", sa.Integer(), nullable=False, server_default="1")) if "is_current" not in columns: op.add_column("accounting_mirror_registry", sa.Column("is_current", sa.Boolean(), nullable=False, server_default=sa.true())) if "supersedes_mirror_id" not in columns: op.add_column("accounting_mirror_registry", sa.Column("supersedes_mirror_id", sa.Integer(), nullable=True)) op.create_foreign_key( "fk_accounting_mirror_registry_supersedes", "accounting_mirror_registry", "accounting_mirror_registry", ["supersedes_mirror_id"], ["id"], ondelete="SET NULL", ) uniques = {u.get("name") for u in inspector.get_unique_constraints("accounting_mirror_registry")} if "uq_accounting_mirror_registry_client_fy" in uniques: op.drop_constraint("uq_accounting_mirror_registry_client_fy", "accounting_mirror_registry", type_="unique") if "uq_accounting_mirror_registry_client_fy_version" not in uniques: op.create_unique_constraint( "uq_accounting_mirror_registry_client_fy_version", "accounting_mirror_registry", ["tenant_id", "client_id", "financial_year", "version_no"], ) indexes = {i.get("name") for i in inspector.get_indexes("accounting_mirror_registry")} if "ix_accounting_mirror_registry_version_no" not in indexes: op.create_index("ix_accounting_mirror_registry_version_no", "accounting_mirror_registry", ["version_no"], unique=False) if "ix_accounting_mirror_registry_is_current" not in indexes: op.create_index("ix_accounting_mirror_registry_is_current", "accounting_mirror_registry", ["is_current"], unique=False) if "ix_accounting_mirror_registry_supersedes_mirror_id" not in indexes: op.create_index("ix_accounting_mirror_registry_supersedes_mirror_id", "accounting_mirror_registry", ["supersedes_mirror_id"], unique=False) # Existing registry rows become version 1/current without touching their # file path, company metadata, dates or status. op.execute(sa.text("UPDATE accounting_mirror_registry SET version_no = 1 WHERE version_no IS NULL")) op.execute(sa.text("UPDATE accounting_mirror_registry SET is_current = TRUE WHERE is_current IS NULL")) def downgrade() -> None: op.drop_index("ix_accounting_mirror_registry_supersedes_mirror_id", table_name="accounting_mirror_registry") op.drop_index("ix_accounting_mirror_registry_is_current", table_name="accounting_mirror_registry") op.drop_index("ix_accounting_mirror_registry_version_no", table_name="accounting_mirror_registry") op.drop_constraint("uq_accounting_mirror_registry_client_fy_version", "accounting_mirror_registry", type_="unique") op.create_unique_constraint( "uq_accounting_mirror_registry_client_fy", "accounting_mirror_registry", ["tenant_id", "client_id", "financial_year"], ) op.drop_constraint("fk_accounting_mirror_registry_supersedes", "accounting_mirror_registry", type_="foreignkey") op.drop_column("accounting_mirror_registry", "supersedes_mirror_id") op.drop_column("accounting_mirror_registry", "is_current") op.drop_column("accounting_mirror_registry", "version_no")