"""Composite indexes for the three list screens. Each of these filters on one column and orders by another, and every index on the table was single-column — so SQLite used one of them and sorted the rest by hand. `engine_event` is the worst of the three: its filter is `type != 'audit'`, which no index on `type` can serve at all. Revision ID: e7d3b1a9c624 Revises: d4a71e9c2b58 Create Date: 2026-08-29 """ from alembic import op # revision identifiers, used by Alembic. revision = "e7d3b1a9c624" down_revision = "d4a71e9c2b58" branch_labels = None depends_on = None def upgrade() -> None: # `GET /runs` filters flow and/or status, newest first. op.create_index("ix_run_flow_created", "run", ["flow", "created_at"]) op.create_index("ix_run_status_created", "run", ["status", "created_at"]) # `GET /observability/runs` does the same over the execution history. op.create_index("ix_flow_run_flow_started", "flow_run", ["flow", "started_at"]) # `GET /observability/events` excludes audit rows, newest first. op.create_index("ix_engine_event_type_ts", "engine_event", ["type", "ts"]) def downgrade() -> None: op.drop_index("ix_engine_event_type_ts", table_name="engine_event") op.drop_index("ix_flow_run_flow_started", table_name="flow_run") op.drop_index("ix_run_status_created", table_name="run") op.drop_index("ix_run_flow_created", table_name="run")