"""Add crossswitch_routes table Revision ID: 20251209_crossswitch Revises: 20251208_initial_schema Create Date: 2025-12-09 12:00:00.000000 """ from alembic import op import sqlalchemy as sa from sqlalchemy.dialects.postgresql import UUID, JSONB # revision identifiers, used by Alembic. revision = '20251209_crossswitch' down_revision = '20251208_initial_schema' branch_labels = None depends_on = None def upgrade() -> None: """Create crossswitch_routes table""" # Create crossswitch_routes table op.create_table( 'crossswitch_routes', sa.Column('id', UUID(as_uuid=True), primary_key=True, nullable=False), sa.Column('camera_id', sa.Integer(), nullable=False, comment='Camera ID (source)'), sa.Column('monitor_id', sa.Integer(), nullable=False, comment='Monitor ID (destination)'), sa.Column('mode', sa.Integer(), nullable=True, default=0, comment='Cross-switch mode (0=normal)'), sa.Column('executed_at', sa.DateTime(), nullable=False), sa.Column('executed_by', UUID(as_uuid=True), nullable=True), sa.Column('is_active', sa.Integer(), nullable=False, default=1, comment='1=active route, 0=cleared/historical'), sa.Column('cleared_at', sa.DateTime(), nullable=True, comment='When this route was cleared'), sa.Column('cleared_by', UUID(as_uuid=True), nullable=True), sa.Column('details', JSONB, nullable=True, comment='Additional route details'), sa.Column('sdk_success', sa.Integer(), nullable=False, default=1, comment='1=SDK success, 0=SDK failure'), sa.Column('sdk_error', sa.String(500), nullable=True, comment='SDK error message if failed'), # Foreign keys sa.ForeignKeyConstraint(['executed_by'], ['users.id'], ondelete='SET NULL'), sa.ForeignKeyConstraint(['cleared_by'], ['users.id'], ondelete='SET NULL'), ) # Create indexes for common queries op.create_index('idx_active_routes', 'crossswitch_routes', ['is_active', 'monitor_id']) op.create_index('idx_camera_history', 'crossswitch_routes', ['camera_id', 'executed_at']) op.create_index('idx_monitor_history', 'crossswitch_routes', ['monitor_id', 'executed_at']) op.create_index('idx_user_routes', 'crossswitch_routes', ['executed_by', 'executed_at']) # Create index for single-column lookups op.create_index('idx_camera_id', 'crossswitch_routes', ['camera_id']) op.create_index('idx_monitor_id', 'crossswitch_routes', ['monitor_id']) op.create_index('idx_executed_at', 'crossswitch_routes', ['executed_at']) def downgrade() -> None: """Drop crossswitch_routes table""" # Drop indexes op.drop_index('idx_executed_at', table_name='crossswitch_routes') op.drop_index('idx_monitor_id', table_name='crossswitch_routes') op.drop_index('idx_camera_id', table_name='crossswitch_routes') op.drop_index('idx_user_routes', table_name='crossswitch_routes') op.drop_index('idx_monitor_history', table_name='crossswitch_routes') op.drop_index('idx_camera_history', table_name='crossswitch_routes') op.drop_index('idx_active_routes', table_name='crossswitch_routes') # Drop table op.drop_table('crossswitch_routes')