"""Add audit_logs table for comprehensive compliance audit logging. Revision ID: 028_add_audit_logs Revises: 027_ensure_shared_links_table Create Date: 2026-03-09 """ from typing import Union import sqlalchemy as sa from alembic import op revision: str = "028_add_audit_logs" down_revision: Union[str, None] = "027_ensure_shared_links_table" depends_on: Union[str, None] = None def upgrade() -> None: """Create audit_logs table.""" op.create_table( "audit_logs", sa.Column("id", sa.Integer(), nullable=False), sa.Column("timestamp", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False), sa.Column("user", sa.String(), nullable=False), sa.Column("action", sa.String(), nullable=False), sa.Column("resource_type", sa.String(), nullable=True), sa.Column("resource_id", sa.String(), nullable=True), sa.Column("ip_address", sa.String(), nullable=True), sa.Column("details", sa.Text(), nullable=True), sa.Column("severity", sa.String(16), nullable=False, server_default="info"), sa.PrimaryKeyConstraint("id"), ) op.create_index("ix_audit_logs_id", "audit_logs", ["id"]) op.create_index("ix_audit_logs_timestamp", "audit_logs", ["timestamp"]) op.create_index("ix_audit_logs_user", "audit_logs", ["user"]) op.create_index("ix_audit_logs_action", "audit_logs", ["action"]) op.create_index("ix_audit_logs_resource_type", "audit_logs", ["resource_type"]) def downgrade() -> None: """Drop audit_logs table.""" op.drop_index("ix_audit_logs_resource_type", "audit_logs") op.drop_index("ix_audit_logs_action", "audit_logs") op.drop_index("ix_audit_logs_user", "audit_logs") op.drop_index("ix_audit_logs_timestamp", "audit_logs") op.drop_index("ix_audit_logs_id", "audit_logs") op.drop_table("audit_logs")