UMBRA/backend/alembic/versions/035_add_performance_indexes.py
Kyle Pope 619e220622 Fix QA review #2: W-03/W-04, S-01 through S-04
W-03: Unify split transactions — _create_db_session() now uses flush()
      instead of commit(), callers own the final commit.
W-04: Time-bound dedup key fetch to 7-day purge window.
S-01: Type admin dashboard response with RecentLoginItem/RecentAuditItem.
S-02: Convert starred events index to partial index WHERE is_starred = true.
S-03: EventTemplate.created_at default changed to func.now() for consistency.
S-04: Add single-worker scaling note to weather cache.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 05:41:16 +08:00

67 lines
2.1 KiB
Python

"""Add performance indexes for hot query paths.
Covers:
- calendar_events range queries scoped by calendar (dashboard, notifications)
- calendar_events starred query (dashboard widget)
- calendar_events parent_event_id (recurring series DELETE)
- user_sessions lookup (auth middleware, every request)
- ntfy_sent purge query (background job, every 60s)
Revision ID: 035
Revises: 034
Create Date: 2026-02-27
"""
from alembic import op
revision = "035"
down_revision = "034"
branch_labels = None
depends_on = None
def upgrade() -> None:
# Composite index for event range queries scoped by calendar
op.create_index(
"ix_calendar_events_calendar_start_end",
"calendar_events",
["calendar_id", "start_datetime", "end_datetime"],
)
# Partial index for starred events dashboard query — only rows where
# is_starred = true are ever queried, so a partial index is smaller and faster.
op.create_index(
"ix_calendar_events_calendar_starred",
"calendar_events",
["calendar_id", "start_datetime"],
postgresql_where="is_starred = true",
)
# FK lookup index for recurring children DELETE
op.create_index(
"ix_calendar_events_parent_id",
"calendar_events",
["parent_event_id"],
)
# Composite index for session validation (runs on every authenticated request)
op.create_index(
"ix_user_sessions_lookup",
"user_sessions",
["user_id", "revoked", "expires_at"],
)
# Index for ntfy_sent purge query (DELETE WHERE sent_at < cutoff)
op.create_index(
"ix_ntfy_sent_sent_at",
"ntfy_sent",
["sent_at"],
)
def downgrade() -> None:
op.drop_index("ix_ntfy_sent_sent_at", table_name="ntfy_sent")
op.drop_index("ix_user_sessions_lookup", table_name="user_sessions")
op.drop_index("ix_calendar_events_parent_id", table_name="calendar_events")
op.drop_index("ix_calendar_events_calendar_starred", table_name="calendar_events")
op.drop_index("ix_calendar_events_calendar_start_end", table_name="calendar_events")