Files
delphi-database/app/database/indexes.py
HotSwapp bac8cc4bd5 changes
2025-08-18 20:20:04 -05:00

147 lines
9.5 KiB
Python

"""
Database secondary indexes helper.
Creates small B-tree indexes for common equality filters to speed up searches.
Uses CREATE INDEX IF NOT EXISTS so it is safe to call repeatedly at startup
and works for existing databases without running a migration.
"""
from sqlalchemy.engine import Engine
from sqlalchemy import text
def ensure_secondary_indexes(engine: Engine) -> None:
statements = [
# Files - existing indexes
"CREATE INDEX IF NOT EXISTS idx_files_status ON files(status)",
"CREATE INDEX IF NOT EXISTS idx_files_file_type ON files(file_type)",
"CREATE INDEX IF NOT EXISTS idx_files_empl_num ON files(empl_num)",
# Files - new date indexes for performance
"CREATE INDEX IF NOT EXISTS idx_files_opened ON files(opened)",
"CREATE INDEX IF NOT EXISTS idx_files_closed ON files(closed)",
"CREATE INDEX IF NOT EXISTS idx_files_id ON files(id)", # Foreign key to rolodex
# Ledger - existing indexes
"CREATE INDEX IF NOT EXISTS idx_ledger_t_type ON ledger(t_type)",
"CREATE INDEX IF NOT EXISTS idx_ledger_empl_num ON ledger(empl_num)",
# Ledger - new indexes for performance
"CREATE INDEX IF NOT EXISTS idx_ledger_date ON ledger(date)", # Critical for date range queries
"CREATE INDEX IF NOT EXISTS idx_ledger_file_no ON ledger(file_no)", # Foreign key joins
"CREATE INDEX IF NOT EXISTS idx_ledger_billed ON ledger(billed)", # Billing status queries
# Ledger - composite indexes for common query patterns
"CREATE INDEX IF NOT EXISTS idx_ledger_date_type ON ledger(date, t_type)", # Date + transaction type
"CREATE INDEX IF NOT EXISTS idx_ledger_date_billed ON ledger(date, billed)", # Recent unbilled entries
"CREATE INDEX IF NOT EXISTS idx_ledger_file_date ON ledger(file_no, date)", # File-specific date ranges
"CREATE INDEX IF NOT EXISTS idx_ledger_empl_date ON ledger(empl_num, date)", # Employee activity by date
# Phone - foreign key index
"CREATE INDEX IF NOT EXISTS idx_phone_rolodex_id ON phone(rolodex_id)",
# Rolodex - additional indexes for search performance
"CREATE INDEX IF NOT EXISTS idx_rolodex_abrev ON rolodex(abrev)", # State filtering
"CREATE INDEX IF NOT EXISTS idx_rolodex_group ON rolodex(group)", # Group filtering
"CREATE INDEX IF NOT EXISTS idx_rolodex_dob ON rolodex(dob)", # Date of birth queries
# Timer system indexes - for time tracking performance
"CREATE INDEX IF NOT EXISTS idx_timers_user_id ON timers(user_id)",
"CREATE INDEX IF NOT EXISTS idx_timers_file_no ON timers(file_no)",
"CREATE INDEX IF NOT EXISTS idx_timers_customer_id ON timers(customer_id)",
"CREATE INDEX IF NOT EXISTS idx_timers_status ON timers(status)",
"CREATE INDEX IF NOT EXISTS idx_timers_started_at ON timers(started_at)",
"CREATE INDEX IF NOT EXISTS idx_timers_created_at ON timers(created_at)",
# Time entries indexes
"CREATE INDEX IF NOT EXISTS idx_time_entries_user_id ON time_entries(user_id)",
"CREATE INDEX IF NOT EXISTS idx_time_entries_file_no ON time_entries(file_no)",
"CREATE INDEX IF NOT EXISTS idx_time_entries_customer_id ON time_entries(customer_id)",
"CREATE INDEX IF NOT EXISTS idx_time_entries_timer_id ON time_entries(timer_id)",
"CREATE INDEX IF NOT EXISTS idx_time_entries_entry_date ON time_entries(entry_date)",
"CREATE INDEX IF NOT EXISTS idx_time_entries_billed ON time_entries(billed)",
"CREATE INDEX IF NOT EXISTS idx_time_entries_created_at ON time_entries(created_at)",
# Timer sessions indexes
"CREATE INDEX IF NOT EXISTS idx_timer_sessions_timer_id ON timer_sessions(timer_id)",
"CREATE INDEX IF NOT EXISTS idx_timer_sessions_started_at ON timer_sessions(started_at)",
"CREATE INDEX IF NOT EXISTS idx_timer_sessions_ended_at ON timer_sessions(ended_at)",
# Billing statement indexes - critical for financial reporting
"CREATE INDEX IF NOT EXISTS idx_billing_statements_file_no ON billing_statements(file_no)",
"CREATE INDEX IF NOT EXISTS idx_billing_statements_customer_id ON billing_statements(customer_id)",
"CREATE INDEX IF NOT EXISTS idx_billing_statements_template_id ON billing_statements(template_id)",
"CREATE INDEX IF NOT EXISTS idx_billing_statements_statement_date ON billing_statements(statement_date)",
"CREATE INDEX IF NOT EXISTS idx_billing_statements_due_date ON billing_statements(due_date)",
"CREATE INDEX IF NOT EXISTS idx_billing_statements_status ON billing_statements(status)",
"CREATE INDEX IF NOT EXISTS idx_billing_statements_period_start ON billing_statements(period_start)",
"CREATE INDEX IF NOT EXISTS idx_billing_statements_period_end ON billing_statements(period_end)",
# Billing statement items indexes
"CREATE INDEX IF NOT EXISTS idx_billing_statement_items_statement_id ON billing_statement_items(statement_id)",
"CREATE INDEX IF NOT EXISTS idx_billing_statement_items_ledger_id ON billing_statement_items(ledger_id)",
"CREATE INDEX IF NOT EXISTS idx_billing_statement_items_date ON billing_statement_items(date)",
# Statement payments indexes
"CREATE INDEX IF NOT EXISTS idx_statement_payments_statement_id ON statement_payments(statement_id)",
"CREATE INDEX IF NOT EXISTS idx_statement_payments_payment_date ON statement_payments(payment_date)",
# File management indexes - for file history and tracking
"CREATE INDEX IF NOT EXISTS idx_file_status_history_file_no ON file_status_history(file_no)",
"CREATE INDEX IF NOT EXISTS idx_file_status_history_change_date ON file_status_history(change_date)",
"CREATE INDEX IF NOT EXISTS idx_file_status_history_changed_by ON file_status_history(changed_by_user_id)",
# File transfer history indexes
"CREATE INDEX IF NOT EXISTS idx_file_transfer_history_file_no ON file_transfer_history(file_no)",
"CREATE INDEX IF NOT EXISTS idx_file_transfer_history_transfer_date ON file_transfer_history(transfer_date)",
"CREATE INDEX IF NOT EXISTS idx_file_transfer_history_old_attorney ON file_transfer_history(old_attorney_id)",
"CREATE INDEX IF NOT EXISTS idx_file_transfer_history_new_attorney ON file_transfer_history(new_attorney_id)",
# File archive indexes
"CREATE INDEX IF NOT EXISTS idx_file_archive_info_file_no ON file_archive_info(file_no)",
"CREATE INDEX IF NOT EXISTS idx_file_archive_info_archive_date ON file_archive_info(archive_date)",
"CREATE INDEX IF NOT EXISTS idx_file_archive_info_retention_date ON file_archive_info(retention_date)",
# File alerts indexes
"CREATE INDEX IF NOT EXISTS idx_file_alerts_file_no ON file_alerts(file_no)",
"CREATE INDEX IF NOT EXISTS idx_file_alerts_alert_date ON file_alerts(alert_date)",
"CREATE INDEX IF NOT EXISTS idx_file_alerts_alert_type ON file_alerts(alert_type)",
"CREATE INDEX IF NOT EXISTS idx_file_alerts_is_active ON file_alerts(is_active)",
# File relationship indexes
"CREATE INDEX IF NOT EXISTS idx_file_relationships_source ON file_relationships(source_file_no)",
"CREATE INDEX IF NOT EXISTS idx_file_relationships_target ON file_relationships(target_file_no)",
"CREATE INDEX IF NOT EXISTS idx_file_relationships_type ON file_relationships(relationship_type)",
# Deadline system indexes
"CREATE INDEX IF NOT EXISTS idx_deadlines_file_no ON deadlines(file_no)",
"CREATE INDEX IF NOT EXISTS idx_deadlines_client_id ON deadlines(client_id)",
"CREATE INDEX IF NOT EXISTS idx_deadlines_deadline_date ON deadlines(deadline_date)",
"CREATE INDEX IF NOT EXISTS idx_deadlines_assigned_to_user ON deadlines(assigned_to_user_id)",
"CREATE INDEX IF NOT EXISTS idx_deadlines_status ON deadlines(status)",
"CREATE INDEX IF NOT EXISTS idx_deadlines_priority ON deadlines(priority)",
# Enhanced audit log indexes (if table exists)
"CREATE INDEX IF NOT EXISTS idx_enhanced_audit_timestamp ON enhanced_audit_log(timestamp)",
"CREATE INDEX IF NOT EXISTS idx_enhanced_audit_user_id ON enhanced_audit_log(user_id)",
"CREATE INDEX IF NOT EXISTS idx_enhanced_audit_event_type ON enhanced_audit_log(event_type)",
"CREATE INDEX IF NOT EXISTS idx_enhanced_audit_severity ON enhanced_audit_log(severity)",
"CREATE INDEX IF NOT EXISTS idx_enhanced_audit_resource_type ON enhanced_audit_log(resource_type)",
"CREATE INDEX IF NOT EXISTS idx_enhanced_audit_source_ip ON enhanced_audit_log(source_ip)",
# Composite indexes for common query patterns
"CREATE INDEX IF NOT EXISTS idx_time_entries_user_date ON time_entries(user_id, entry_date)",
"CREATE INDEX IF NOT EXISTS idx_file_alerts_active_date ON file_alerts(is_active, alert_date)",
"CREATE INDEX IF NOT EXISTS idx_billing_statements_status_date ON billing_statements(status, statement_date)",
"CREATE INDEX IF NOT EXISTS idx_deadlines_date_status ON deadlines(deadline_date, status)",
]
with engine.begin() as conn:
for stmt in statements:
try:
conn.execute(text(stmt))
except Exception:
# Ignore failures (e.g., non-SQLite engines that still support IF NOT EXISTS;
# if not supported, users should manage indexes via migrations)
pass