"""Add missing deleted_at columns to TenantMixin tables. Several models inherit TenantMixin (which includes SoftDeleteMixin) but their DB tables were never migrated to include the deleted_at column. This causes 500 errors when SQLAlchemy tries to SELECT deleted_at. Revision ID: 0083 Revises: 0082 """ from alembic import op import sqlalchemy as sa revision = "0083" down_revision = "0082" branch_labels = None depends_on = None # Tables that use TenantMixin (and therefore SoftDeleteMixin) in their models # but are missing the deleted_at column in the database. TABLES_NEEDING_DELETED_AT = [ "contact_folder_permissions", "permission_delegations", "guest_users", "entity_policies", "notification_types", "password_reset_tokens", "api_tokens", "permission_templates", "user_groups", ] def upgrade() -> None: conn = op.get_bind() for table_name in TABLES_NEEDING_DELETED_AT: # Check if column already exists before adding result = conn.execute(sa.text( "SELECT 1 FROM information_schema.columns " "WHERE table_name = :t AND column_name = 'deleted_at'" ), {"t": table_name}) if result.scalar() is None: op.add_column( table_name, sa.Column("deleted_at", sa.DateTime(timezone=True), nullable=True), ) print(f" Added deleted_at to {table_name}") else: print(f" Skipped {table_name} (already has deleted_at)") def downgrade() -> None: for table_name in reversed(TABLES_NEEDING_DELETED_AT): op.drop_column(table_name, "deleted_at")