"""Phase 12: Add performance indexes on high-filter columns Revision ID: phase12_performance_indexes Revises: phase11_director_role Create Date: 2026-04-25 Rationale --------- The following columns are filtered or ordered on every page load but had no DB index, causing full table scans as row counts grow: inspections - status — filtered on list/dashboard/SLA queries - facility_id — filtered for customer-scoped views and reports - inspector_id — filtered for inspector-scoped views - inspection_date — used in all trend/score queries (ORDER BY, range filter) issues - status — filtered on every issues list/dashboard load - severity — filtered in dashboard breakdown and issues list - assigned_to — filtered for inspector-scoped views - reported_at — used for ordering Existence checks use information_schema so the migration is safe to re-run on any MySQL version (compatible back to 5.7). """ from alembic import op from sqlalchemy import text def _index_exists(conn, table: str, index_name: str) -> bool: """Return True if the named index already exists on the given table.""" result = conn.execute(text( "SELECT COUNT(*) FROM information_schema.statistics " "WHERE table_schema = DATABASE() " " AND table_name = :table " " AND index_name = :index" ), {'table': table, 'index': index_name}) return result.scalar() > 0 revision = 'phase12_performance_indexes' down_revision = 'phase11_director_role' branch_labels = None depends_on = None # (table, index_name, column) INDEXES = [ ('inspections', 'ix_inspections_status', 'status'), ('inspections', 'ix_inspections_facility_id', 'facility_id'), ('inspections', 'ix_inspections_inspector_id', 'inspector_id'), ('inspections', 'ix_inspections_inspection_date', 'inspection_date'), ('issues', 'ix_issues_status', 'status'), ('issues', 'ix_issues_severity', 'severity'), ('issues', 'ix_issues_assigned_to', 'assigned_to'), ('issues', 'ix_issues_reported_at', 'reported_at'), ] def upgrade(): conn = op.get_bind() for table, index_name, column in INDEXES: if not _index_exists(conn, table, index_name): op.execute(text( f'CREATE INDEX {index_name} ON {table} ({column})' )) def downgrade(): conn = op.get_bind() for table, index_name, _column in INDEXES: if _index_exists(conn, table, index_name): op.execute(text( f'DROP INDEX {index_name} ON {table}' ))