"""Indexes the large-library read paths need (US07-06). Revision ID: 0016_performance_indexes Revises: 0015_exif_projections Create Date: 2026-08-17 Measured, not guessed. At 100k assets the workflow home and the safety queue both resolve "the current decision per asset" with a window function over ``safety_reviews``; a plain ``asset_id`` index makes SQLite sort every partition by hand. Ordering the index by ``(asset_id, created_at DESC)`` halves that query. ``duplicate_members(cluster_id, asset_id)`` serves the paged member list of a cluster with thousands of members, which is the other page that stopped being cheap. """ from alembic import op revision = "0016_performance_indexes" down_revision = "0015_exif_projections" branch_labels = None depends_on = None def upgrade() -> None: op.create_index( "ix_safety_reviews_asset_created", "safety_reviews", ["asset_id", "created_at"], ) op.create_index( "ix_duplicate_members_cluster_asset", "duplicate_members", ["cluster_id", "asset_id"], ) op.create_index( "ix_analysis_results_approx_year", "analysis_results", ["approx_year"], ) def downgrade() -> None: op.drop_index("ix_analysis_results_approx_year", table_name="analysis_results") op.drop_index("ix_duplicate_members_cluster_asset", table_name="duplicate_members") op.drop_index("ix_safety_reviews_asset_created", table_name="safety_reviews")