"""Add pipeline_stats table and User.pipeline_tuning Revision ID: 003 Revises: 002 Create Date: 2026-05-11 """ from typing import Sequence, Union from alembic import op import sqlalchemy as sa from sqlalchemy.dialects import postgresql revision: str = "003" down_revision: Union[str, None] = "002" branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: # ── users: add pipeline_tuning ── op.add_column("users", sa.Column( "pipeline_tuning", postgresql.JSONB(), nullable=True )) # ── pipeline_stats ── op.create_table( "pipeline_stats", sa.Column("id", sa.String(36), primary_key=True), sa.Column("user_id", postgresql.UUID(), sa.ForeignKey("users.id", ondelete="CASCADE"), nullable=True, index=True), sa.Column("stage", sa.String(50), nullable=False, index=True), sa.Column("passed", sa.Boolean(), nullable=False), sa.Column("reason", sa.String(255), nullable=True), sa.Column("duration_ms", sa.Integer(), nullable=True), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), ) # composite index for stats aggregation op.create_index( "ix_pipeline_stats_user_stage", "pipeline_stats", ["user_id", "stage"], ) def downgrade() -> None: op.drop_index("ix_pipeline_stats_user_stage", table_name="pipeline_stats") op.drop_table("pipeline_stats") op.drop_column("users", "pipeline_tuning")