"""SUPER candidates and immutable component evidence; retain all existing Alpha rows.""" import sqlalchemy as sa from alembic import op revision = "0021" down_revision = "0020" branch_labels = None depends_on = None def upgrade(): op.add_column("backtest_items", sa.Column("alpha_type", sa.String(20), nullable=False, server_default="REGULAR")) op.add_column("backtest_items", sa.Column("selection", sa.Text(), nullable=True)) op.add_column("backtest_items", sa.Column("combo", sa.Text(), nullable=True)) op.create_index("ix_backtest_items_alpha_type", "backtest_items", ["alpha_type"]) op.create_table("super_selection_snapshots", sa.Column("id", sa.String(36), primary_key=True), sa.Column("job_id", sa.String(36), sa.ForeignKey("sync_jobs.id"), unique=True), sa.Column("item_id", sa.String(36), sa.ForeignKey("backtest_items.id"), unique=True), sa.Column("source", sa.String(20), nullable=False), sa.Column("request", sa.JSON(), nullable=False), sa.Column("request_hash", sa.String(64), nullable=False), sa.Column("component_hash", sa.String(64)), sa.Column("components", sa.JSON(), nullable=False), sa.Column("raw", sa.JSON(), nullable=False), sa.Column("complete", sa.Boolean(), nullable=False), sa.Column("total", sa.Integer()), sa.Column("warnings", sa.JSON(), nullable=False), sa.Column("observed_at", sa.DateTime(timezone=True), nullable=False)) for key in ("request_hash", "component_hash"): op.create_index(f"ix_super_selection_snapshots_{key}", "super_selection_snapshots", [key]) def downgrade(): op.drop_table("super_selection_snapshots") op.drop_index("ix_backtest_items_alpha_type", table_name="backtest_items") for key in ("combo", "selection", "alpha_type"): op.drop_column("backtest_items", key)