"""Expediente (crm.cases) + case_id en el ciclo comercial Revision ID: d4e5f6a7b8c9 Revises: f0a1b2c3d4e5 Create Date: 2026-08-07 02:00:00.000000 Crea crm.cases (expediente, hilo maestro con folio EXP...) y agrega case_id a crm.opportunities/service_requests/quotes, ops.shipments y fin.invoices. """ from typing import Sequence, Union import sqlalchemy as sa from alembic import op revision: str = "d4e5f6a7b8c9" down_revision: Union[str, None] = "f0a1b2c3d4e5" branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None # (schema, tabla) donde se agrega case_id _CASE_FK_TABLES = [ ("crm", "opportunities"), ("crm", "service_requests"), ("crm", "quotes"), ("ops", "shipments"), ("fin", "invoices"), ] def upgrade() -> None: op.create_table( "cases", sa.Column("id", sa.Integer(), nullable=False), sa.Column("reference", sa.String(length=40), nullable=True), sa.Column("account_id", sa.Integer(), nullable=True), sa.Column("title", sa.String(length=255), nullable=True), sa.Column("stage", sa.String(length=20), nullable=False, server_default=sa.text("'oportunidad'")), sa.Column("status", sa.String(length=20), nullable=False, server_default=sa.text("'abierto'")), sa.Column("created_by", sa.String(length=64), nullable=True), sa.Column("updated_by", sa.String(length=64), nullable=True), sa.Column("tenant_id", sa.Integer(), nullable=False), sa.Column("company_id", sa.Integer(), nullable=False), sa.Column("created_at", sa.DateTime(), nullable=False, server_default=sa.text("now()")), sa.Column("updated_at", sa.DateTime(), nullable=False, server_default=sa.text("now()")), sa.Column("deleted_at", sa.DateTime(), nullable=True), sa.PrimaryKeyConstraint("id"), sa.ForeignKeyConstraint(["tenant_id"], ["core.tenants.id"]), sa.ForeignKeyConstraint(["account_id"], ["crm.accounts.id"]), schema="crm", ) op.create_index("ix_crm_cases_id", "cases", ["id"], schema="crm") op.create_index("ix_crm_cases_reference", "cases", ["reference"], schema="crm") op.create_index("ix_crm_cases_tenant_id", "cases", ["tenant_id"], schema="crm") op.create_index("ix_crm_cases_company_id", "cases", ["company_id"], schema="crm") op.create_index("ix_crm_cases_account_id", "cases", ["account_id"], schema="crm") op.create_index("ix_crm_cases_status", "cases", ["status"], schema="crm") for schema, table in _CASE_FK_TABLES: op.add_column(table, sa.Column("case_id", sa.Integer(), nullable=True), schema=schema) op.create_index(f"ix_{schema}_{table}_case_id", table, ["case_id"], schema=schema) op.create_foreign_key( f"fk_{schema}_{table}_case_id", table, "cases", ["case_id"], ["id"], source_schema=schema, referent_schema="crm", ) def downgrade() -> None: for schema, table in _CASE_FK_TABLES: op.drop_constraint(f"fk_{schema}_{table}_case_id", table, schema=schema, type_="foreignkey") op.drop_index(f"ix_{schema}_{table}_case_id", table_name=table, schema=schema) op.drop_column(table, "case_id", schema=schema) for idx in ("status", "account_id", "company_id", "tenant_id", "reference", "id"): op.drop_index(f"ix_crm_cases_{idx}", table_name="cases", schema="crm") op.drop_table("cases", schema="crm")