"""Add project contracts and normalized cash flows. Revision ID: 202607120002 Revises: 202607120001 Create Date: 2026-07-12 """ from alembic import op import sqlalchemy as sa revision = "202607120002" down_revision = "202607120001" branch_labels = None depends_on = None def _index(table: str, column: str, unique: bool = False) -> None: op.create_index(op.f(f"ix_{table}_{column}"), table, [column], unique=unique) def upgrade() -> None: op.add_column( "projects", sa.Column("source_contract_amount", sa.Numeric(16, 2), nullable=True) ) op.add_column( "projects", sa.Column("source_project_investment_amount", sa.Numeric(16, 2), nullable=True), ) op.create_table( "project_contracts", sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), sa.Column("code", sa.String(64), nullable=False), sa.Column("project_code", sa.String(64), nullable=True), sa.Column("contract_type_code", sa.String(32), nullable=True), sa.Column("contract_type_label", sa.String(128), nullable=True), sa.Column("amount", sa.Numeric(16, 2), nullable=False), sa.Column("signed_date", sa.Date(), nullable=True), sa.Column("start_date", sa.Date(), nullable=True), sa.Column("end_date", sa.Date(), nullable=True), sa.Column("invoice_type_code", sa.String(32), nullable=True), sa.Column("data_quality_status", sa.String(32), nullable=False), sa.Column("source_system", sa.String(64), nullable=False), sa.Column("external_id", sa.String(128), nullable=False), sa.Column("source_created_at", sa.DateTime(), nullable=True), sa.Column("last_seen_at", sa.DateTime(), nullable=True), sa.Column("is_active", sa.Boolean(), nullable=False), sa.Column("created_at", sa.DateTime(), nullable=False), sa.Column("updated_at", sa.DateTime(), nullable=False), sa.PrimaryKeyConstraint("id"), ) for column, unique in ( ("code", True), ("project_code", False), ("contract_type_code", False), ("signed_date", False), ("data_quality_status", False), ("external_id", False), ("last_seen_at", False), ("is_active", False), ): _index("project_contracts", column, unique) op.create_table( "project_cash_flows", sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), sa.Column("code", sa.String(64), nullable=False), sa.Column("project_code", sa.String(64), nullable=True), sa.Column("contract_code", sa.String(64), nullable=True), sa.Column("flow_type", sa.String(32), nullable=False), sa.Column("direction", sa.String(16), nullable=False), sa.Column("category_code", sa.String(32), nullable=True), sa.Column("category_label", sa.String(128), nullable=True), sa.Column("planned_amount", sa.Numeric(16, 2), nullable=False), sa.Column("actual_amount", sa.Numeric(16, 2), nullable=True), sa.Column("planned_date", sa.Date(), nullable=True), sa.Column("actual_date", sa.Date(), nullable=True), sa.Column("payment_status", sa.String(32), nullable=True), sa.Column("invoice_status", sa.String(32), nullable=True), sa.Column("approval_status", sa.String(32), nullable=True), sa.Column("confirmation_status", sa.String(32), nullable=True), sa.Column("data_quality_status", sa.String(32), nullable=False), sa.Column("source_system", sa.String(64), nullable=False), sa.Column("external_id", sa.String(128), nullable=False), sa.Column("source_created_at", sa.DateTime(), nullable=True), sa.Column("source_updated_at", sa.DateTime(), nullable=True), sa.Column("last_seen_at", sa.DateTime(), nullable=True), sa.Column("is_active", sa.Boolean(), nullable=False), sa.Column("created_at", sa.DateTime(), nullable=False), sa.Column("updated_at", sa.DateTime(), nullable=False), sa.PrimaryKeyConstraint("id"), ) for column, unique in ( ("code", True), ("project_code", False), ("contract_code", False), ("flow_type", False), ("direction", False), ("category_code", False), ("planned_date", False), ("actual_date", False), ("payment_status", False), ("approval_status", False), ("data_quality_status", False), ("external_id", False), ("source_updated_at", False), ("last_seen_at", False), ("is_active", False), ): _index("project_cash_flows", column, unique) def downgrade() -> None: op.drop_table("project_cash_flows") op.drop_table("project_contracts") op.drop_column("projects", "source_project_investment_amount") op.drop_column("projects", "source_contract_amount")