PMFlow/backend/alembic/versions/20260308_add_ai_processing_...

90 lines
3.3 KiB
Python

"""add ai processing audit fields
Revision ID: add_ai_processing_audit_fields
Revises: add_inbox_structured_fields
Create Date: 2026-03-08
"""
from __future__ import annotations
from alembic import op
import sqlalchemy as sa
revision = "add_ai_processing_audit_fields"
down_revision = "add_inbox_structured_fields"
branch_labels = None
depends_on = None
def _table_exists(bind, table_name: str) -> bool:
return sa.inspect(bind).has_table(table_name)
def _column_exists(bind, table_name: str, column_name: str) -> bool:
inspector = sa.inspect(bind)
if not inspector.has_table(table_name):
return False
columns = inspector.get_columns(table_name)
return any(col.get("name") == column_name for col in columns)
def _index_exists(bind, table_name: str, index_name: str) -> bool:
inspector = sa.inspect(bind)
if not inspector.has_table(table_name):
return False
return any(idx.get("name") == index_name for idx in inspector.get_indexes(table_name))
def _add_column_if_missing(bind, table_name: str, column: sa.Column) -> None:
if not _column_exists(bind, table_name, str(column.name)):
op.add_column(table_name, column)
def _create_index_if_missing(bind, table_name: str, index_name: str, columns: list[str]) -> None:
if not _index_exists(bind, table_name, index_name):
op.create_index(index_name, table_name, columns)
def upgrade() -> None:
bind = op.get_bind()
if not _table_exists(bind, "ai_processing_logs"):
return
_add_column_if_missing(bind, "ai_processing_logs", sa.Column("normalized_text", sa.Text(), nullable=True))
_add_column_if_missing(bind, "ai_processing_logs", sa.Column("route", sa.String(length=80), nullable=True))
_add_column_if_missing(bind, "ai_processing_logs", sa.Column("intent", sa.String(length=40), nullable=True))
_add_column_if_missing(bind, "ai_processing_logs", sa.Column("executor", sa.String(length=40), nullable=True))
_add_column_if_missing(bind, "ai_processing_logs", sa.Column("operation_code", sa.String(length=80), nullable=True))
_add_column_if_missing(bind, "ai_processing_logs", sa.Column("operation_result", sa.JSON(), nullable=True))
_add_column_if_missing(bind, "ai_processing_logs", sa.Column("reply_source", sa.String(length=40), nullable=True))
_create_index_if_missing(bind, "ai_processing_logs", "ix_ai_processing_logs_route", ["route"])
_create_index_if_missing(bind, "ai_processing_logs", "ix_ai_processing_logs_intent", ["intent"])
_create_index_if_missing(bind, "ai_processing_logs", "ix_ai_processing_logs_operation_code", ["operation_code"])
def downgrade() -> None:
bind = op.get_bind()
if not _table_exists(bind, "ai_processing_logs"):
return
for index_name in (
"ix_ai_processing_logs_operation_code",
"ix_ai_processing_logs_intent",
"ix_ai_processing_logs_route",
):
if _index_exists(bind, "ai_processing_logs", index_name):
op.drop_index(index_name, table_name="ai_processing_logs")
for column_name in (
"reply_source",
"operation_result",
"operation_code",
"executor",
"intent",
"route",
"normalized_text",
):
if _column_exists(bind, "ai_processing_logs", column_name):
op.drop_column("ai_processing_logs", column_name)