"""consultant conversion and workspace limits phase 5a7 5a8 Revision ID: 20260512_consultant_conversion_limits_phase_5a7_5a8 Revises: 20260511_consultant_completion_phase_5a5_5a6 Create Date: 2026-05-12 """ from __future__ import annotations from alembic import op import sqlalchemy as sa revision = "20260512_consultant_conversion_limits_phase_5a7_5a8" down_revision = "20260511_consultant_completion_phase_5a5_5a6" branch_labels = None depends_on = None def _has_column(table_name: str, column_name: str) -> bool: bind = op.get_bind() inspector = sa.inspect(bind) return column_name in {col["name"] for col in inspector.get_columns(table_name)} def _has_index(table_name: str, index_name: str) -> bool: bind = op.get_bind() inspector = sa.inspect(bind) return index_name in {idx["name"] for idx in inspector.get_indexes(table_name)} def upgrade() -> None: table = "consultant_managed_clients" if not _has_column(table, "conversion_status"): op.add_column(table, sa.Column("conversion_status", sa.String(length=30), nullable=False, server_default="not_requested")) if not _has_column(table, "conversion_requested_at_utc"): op.add_column(table, sa.Column("conversion_requested_at_utc", sa.DateTime(timezone=True), nullable=True)) if not _has_column(table, "conversion_requested_by_user_id"): op.add_column(table, sa.Column("conversion_requested_by_user_id", sa.Integer(), nullable=True)) if not _has_column(table, "conversion_reviewed_at_utc"): op.add_column(table, sa.Column("conversion_reviewed_at_utc", sa.DateTime(timezone=True), nullable=True)) if not _has_column(table, "conversion_reviewed_by_user_id"): op.add_column(table, sa.Column("conversion_reviewed_by_user_id", sa.Integer(), nullable=True)) if not _has_column(table, "conversion_notes"): op.add_column(table, sa.Column("conversion_notes", sa.Text(), nullable=True)) if not _has_column(table, "conversion_firm_notes"): op.add_column(table, sa.Column("conversion_firm_notes", sa.Text(), nullable=True)) if not _has_index(table, "ix_consultant_managed_clients_conversion_status"): op.create_index("ix_consultant_managed_clients_conversion_status", table, ["conversion_status"]) if not _has_index(table, "ix_consultant_managed_clients_conversion_requested_by_user_id"): op.create_index("ix_consultant_managed_clients_conversion_requested_by_user_id", table, ["conversion_requested_by_user_id"]) if not _has_index(table, "ix_consultant_managed_clients_conversion_reviewed_by_user_id"): op.create_index("ix_consultant_managed_clients_conversion_reviewed_by_user_id", table, ["conversion_reviewed_by_user_id"]) # SQLite supports ALTER TABLE ADD COLUMN but does not always enforce server default cleanup safely. # Keeping the server default is intentional so existing local installs remain simple and stable. def downgrade() -> None: table = "consultant_managed_clients" for index_name in [ "ix_consultant_managed_clients_conversion_reviewed_by_user_id", "ix_consultant_managed_clients_conversion_requested_by_user_id", "ix_consultant_managed_clients_conversion_status", ]: if _has_index(table, index_name): op.drop_index(index_name, table_name=table) for column_name in [ "conversion_firm_notes", "conversion_notes", "conversion_reviewed_by_user_id", "conversion_reviewed_at_utc", "conversion_requested_by_user_id", "conversion_requested_at_utc", "conversion_status", ]: if _has_column(table, column_name): op.drop_column(table, column_name)