90 lines
3.3 KiB
Python
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)
|