"""System default task inheritance and firm update review. Revision ID: 20260919_task_inheritance Revises: 20260918_accounting_mirror_ver """ from alembic import op import sqlalchemy as sa revision = "20260919_task_inheritance" down_revision = "20260918_accounting_mirror_ver" 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("firm_service_task_templates")} fks = {fk.get("name") for fk in inspector.get_foreign_keys("firm_service_task_templates")} # batch_alter_table keeps this migration compatible with both production # PostgreSQL and the project's supported SQLite development database. with op.batch_alter_table("firm_service_task_templates") as batch: if "source_system_task_id" not in columns: batch.add_column(sa.Column("source_system_task_id", sa.Integer(), nullable=True)) if "is_customized" not in columns: batch.add_column(sa.Column("is_customized", sa.Boolean(), nullable=False, server_default=sa.false())) if "last_synced_system_hash" not in columns: batch.add_column(sa.Column("last_synced_system_hash", sa.String(length=64), nullable=True)) if "last_reviewed_system_hash" not in columns: batch.add_column(sa.Column("last_reviewed_system_hash", sa.String(length=64), nullable=True)) if "system_update_available" not in columns: batch.add_column(sa.Column("system_update_available", sa.Boolean(), nullable=False, server_default=sa.false())) if "system_update_detected_at_utc" not in columns: batch.add_column(sa.Column("system_update_detected_at_utc", sa.DateTime(timezone=True), nullable=True)) if "fk_firm_task_source_system_task" not in fks: batch.create_foreign_key( "fk_firm_task_source_system_task", "service_default_task_templates", ["source_system_task_id"], ["id"], ondelete="SET NULL", ) inspector = sa.inspect(bind) indexes = {i.get("name") for i in inspector.get_indexes("firm_service_task_templates")} if "ix_firm_service_task_templates_source_system_task_id" not in indexes: op.create_index("ix_firm_service_task_templates_source_system_task_id", "firm_service_task_templates", ["source_system_task_id"], unique=False) if "ix_firm_service_task_templates_is_customized" not in indexes: op.create_index("ix_firm_service_task_templates_is_customized", "firm_service_task_templates", ["is_customized"], unique=False) if "ix_firm_service_task_templates_system_update_available" not in indexes: op.create_index("ix_firm_service_task_templates_system_update_available", "firm_service_task_templates", ["system_update_available"], unique=False) def downgrade() -> None: bind = op.get_bind() inspector = sa.inspect(bind) indexes = {i.get("name") for i in inspector.get_indexes("firm_service_task_templates")} if "ix_firm_service_task_templates_system_update_available" in indexes: op.drop_index("ix_firm_service_task_templates_system_update_available", table_name="firm_service_task_templates") if "ix_firm_service_task_templates_is_customized" in indexes: op.drop_index("ix_firm_service_task_templates_is_customized", table_name="firm_service_task_templates") if "ix_firm_service_task_templates_source_system_task_id" in indexes: op.drop_index("ix_firm_service_task_templates_source_system_task_id", table_name="firm_service_task_templates") columns = {c["name"] for c in sa.inspect(bind).get_columns("firm_service_task_templates")} fks = {fk.get("name") for fk in sa.inspect(bind).get_foreign_keys("firm_service_task_templates")} with op.batch_alter_table("firm_service_task_templates") as batch: if "fk_firm_task_source_system_task" in fks: batch.drop_constraint("fk_firm_task_source_system_task", type_="foreignkey") for name in ( "system_update_detected_at_utc", "system_update_available", "last_reviewed_system_hash", "last_synced_system_hash", "is_customized", "source_system_task_id", ): if name in columns: batch.drop_column(name)