001_initial_doc_asset_audit_event.py
1 """Initial migration: doc_asset and audit_event tables 2 3 Revision ID: 001 4 Revises: 5 Create Date: 2026-01-18 6 7 """ 8 from alembic import op 9 import sqlalchemy as sa 10 from sqlalchemy.dialects import postgresql 11 12 # revision identifiers, used by Alembic. 13 revision = '001' 14 down_revision = None 15 branch_labels = None 16 depends_on = None 17 18 19 def upgrade() -> None: 20 # Create doc_asset table 21 op.create_table( 22 'doc_asset', 23 sa.Column('id', sa.Integer(), nullable=False), 24 sa.Column('filename', sa.String(length=512), nullable=False), 25 sa.Column('storage_uri', sa.String(length=1024), nullable=False), 26 sa.Column('uploaded_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False), 27 sa.Column('indexed_status', sa.Enum('PENDING', 'INDEXING', 'READY', 'FAILED', name='indexedstatus'), nullable=False, server_default='PENDING'), 28 sa.Column('datastore_ref', sa.String(length=512), nullable=True), 29 sa.Column('deleted_at', sa.DateTime(timezone=True), nullable=True), 30 sa.PrimaryKeyConstraint('id') 31 ) 32 op.create_index(op.f('ix_doc_asset_id'), 'doc_asset', ['id'], unique=False) 33 op.create_index(op.f('ix_doc_asset_filename'), 'doc_asset', ['filename'], unique=False) 34 op.create_index(op.f('ix_doc_asset_indexed_status'), 'doc_asset', ['indexed_status'], unique=False) 35 op.create_index(op.f('ix_doc_asset_deleted_at'), 'doc_asset', ['deleted_at'], unique=False) 36 37 # Create audit_event table 38 op.create_table( 39 'audit_event', 40 sa.Column('id', sa.Integer(), nullable=False), 41 sa.Column('ts', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False), 42 sa.Column('module', sa.Enum('MODULE_A', 'MODULE_B', 'MODULE_C', 'ADMIN', 'SYSTEM', name='auditmodule'), nullable=False), 43 sa.Column('user_id', sa.String(length=128), nullable=True), 44 sa.Column('session_id', sa.String(length=128), nullable=True), 45 sa.Column('request_id', sa.String(length=128), nullable=False), 46 sa.Column('prompt_hash', sa.String(length=64), nullable=True), 47 sa.Column('sources_json', postgresql.JSON(astext_type=sa.Text()), nullable=True), 48 sa.Column('tool_calls_json', postgresql.JSON(astext_type=sa.Text()), nullable=True), 49 sa.Column('decision_json', postgresql.JSON(astext_type=sa.Text()), nullable=True), 50 sa.Column('status', sa.Enum('SUCCESS', 'FAILURE', 'PENDING', name='auditstatus'), nullable=False, server_default='PENDING'), 51 sa.Column('error', sa.Text(), nullable=True), 52 sa.PrimaryKeyConstraint('id') 53 ) 54 op.create_index(op.f('ix_audit_event_id'), 'audit_event', ['id'], unique=False) 55 op.create_index(op.f('ix_audit_event_ts'), 'audit_event', ['ts'], unique=False) 56 op.create_index(op.f('ix_audit_event_module'), 'audit_event', ['module'], unique=False) 57 op.create_index(op.f('ix_audit_event_user_id'), 'audit_event', ['user_id'], unique=False) 58 op.create_index(op.f('ix_audit_event_session_id'), 'audit_event', ['session_id'], unique=False) 59 op.create_index(op.f('ix_audit_event_request_id'), 'audit_event', ['request_id'], unique=False) 60 op.create_index(op.f('ix_audit_event_prompt_hash'), 'audit_event', ['prompt_hash'], unique=False) 61 op.create_index(op.f('ix_audit_event_status'), 'audit_event', ['status'], unique=False) 62 63 64 def downgrade() -> None: 65 op.drop_index(op.f('ix_audit_event_status'), table_name='audit_event') 66 op.drop_index(op.f('ix_audit_event_prompt_hash'), table_name='audit_event') 67 op.drop_index(op.f('ix_audit_event_request_id'), table_name='audit_event') 68 op.drop_index(op.f('ix_audit_event_session_id'), table_name='audit_event') 69 op.drop_index(op.f('ix_audit_event_user_id'), table_name='audit_event') 70 op.drop_index(op.f('ix_audit_event_module'), table_name='audit_event') 71 op.drop_index(op.f('ix_audit_event_ts'), table_name='audit_event') 72 op.drop_index(op.f('ix_audit_event_id'), table_name='audit_event') 73 op.drop_table('audit_event') 74 75 op.drop_index(op.f('ix_doc_asset_deleted_at'), table_name='doc_asset') 76 op.drop_index(op.f('ix_doc_asset_indexed_status'), table_name='doc_asset') 77 op.drop_index(op.f('ix_doc_asset_filename'), table_name='doc_asset') 78 op.drop_index(op.f('ix_doc_asset_id'), table_name='doc_asset') 79 op.drop_table('doc_asset')