175 lines
9.5 KiB
Python
175 lines
9.5 KiB
Python
|
|
"""add automation tables (阶段5 自动化闭环): auto_sessions / auto_actions /
|
||
|
|
auto_approval_tickets / auto_scenario_configs / auto_rule_versions /
|
||
|
|
auto_action_logs / auto_mapping_cache
|
||
|
|
|
||
|
|
Revision ID: 044_automation
|
||
|
|
Revises: 043_knowledge_iteration
|
||
|
|
Create Date: 2026-07-10
|
||
|
|
|
||
|
|
"""
|
||
|
|
from typing import Sequence, Union
|
||
|
|
|
||
|
|
from alembic import op
|
||
|
|
import sqlalchemy as sa
|
||
|
|
|
||
|
|
|
||
|
|
# revision identifiers, used by Alembic.
|
||
|
|
revision: str = '044_automation'
|
||
|
|
down_revision: Union[str, None] = '043_knowledge_iteration'
|
||
|
|
branch_labels: Union[str, Sequence[str], None] = None
|
||
|
|
depends_on: Union[str, Sequence[str], None] = None
|
||
|
|
|
||
|
|
|
||
|
|
def upgrade() -> None:
|
||
|
|
# --------------------------------------------------------------------------
|
||
|
|
# 1. 自动化处置会话 auto_sessions
|
||
|
|
# --------------------------------------------------------------------------
|
||
|
|
op.create_table(
|
||
|
|
'auto_sessions',
|
||
|
|
sa.Column('id', sa.String(36), primary_key=True),
|
||
|
|
sa.Column('conversation_id', sa.String(36), nullable=True, index=True),
|
||
|
|
sa.Column('employee_id', sa.String(64), nullable=False, index=True),
|
||
|
|
sa.Column('agent_id', sa.String(64), nullable=True, index=True),
|
||
|
|
sa.Column('scenario_key', sa.String(64), nullable=True, index=True),
|
||
|
|
sa.Column('status', sa.String(20), nullable=False, server_default='created', index=True),
|
||
|
|
sa.Column('mode', sa.String(20), nullable=False, server_default='real_exec'),
|
||
|
|
sa.Column('confidence', sa.Float(), nullable=False, server_default='0.0'),
|
||
|
|
sa.Column('intent', sa.JSON(), nullable=True),
|
||
|
|
sa.Column('current_action_id', sa.String(36), nullable=True),
|
||
|
|
sa.Column('title', sa.String(256), nullable=False, server_default=''),
|
||
|
|
sa.Column('auto_close_at', sa.DateTime(timezone=True), nullable=True),
|
||
|
|
sa.Column('resolved_at', sa.DateTime(timezone=True), nullable=True),
|
||
|
|
sa.Column('closed_by', sa.String(64), nullable=True),
|
||
|
|
sa.Column('meta', sa.JSON(), nullable=True),
|
||
|
|
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
|
||
|
|
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False),
|
||
|
|
)
|
||
|
|
op.create_index('idx_auto_session_employee', 'auto_sessions', ['employee_id'])
|
||
|
|
op.create_index('idx_auto_session_status', 'auto_sessions', ['status'])
|
||
|
|
|
||
|
|
# --------------------------------------------------------------------------
|
||
|
|
# 2. 处置动作 auto_actions
|
||
|
|
# --------------------------------------------------------------------------
|
||
|
|
op.create_table(
|
||
|
|
'auto_actions',
|
||
|
|
sa.Column('id', sa.String(36), primary_key=True),
|
||
|
|
sa.Column('session_id', sa.String(36), nullable=False, index=True),
|
||
|
|
sa.Column('action_index', sa.Integer(), nullable=False, server_default='0'),
|
||
|
|
sa.Column('action_type', sa.String(64), nullable=False, server_default=''),
|
||
|
|
sa.Column('adapter', sa.String(32), nullable=False, server_default=''),
|
||
|
|
sa.Column('risk_level', sa.String(16), nullable=False, server_default='read'),
|
||
|
|
sa.Column('title', sa.String(256), nullable=False, server_default=''),
|
||
|
|
sa.Column('description', sa.Text(), nullable=False, server_default=''),
|
||
|
|
sa.Column('status', sa.String(20), nullable=False, server_default='pending', index=True),
|
||
|
|
sa.Column('payload', sa.JSON(), nullable=True),
|
||
|
|
sa.Column('result', sa.JSON(), nullable=True),
|
||
|
|
sa.Column('error', sa.Text(), nullable=True),
|
||
|
|
sa.Column('approved_by', sa.String(64), nullable=True),
|
||
|
|
sa.Column('approved_at', sa.DateTime(timezone=True), nullable=True),
|
||
|
|
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
|
||
|
|
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False),
|
||
|
|
)
|
||
|
|
op.create_index('idx_auto_action_session', 'auto_actions', ['session_id'])
|
||
|
|
op.create_index('idx_auto_action_status', 'auto_actions', ['status'])
|
||
|
|
|
||
|
|
# --------------------------------------------------------------------------
|
||
|
|
# 3. 审批单 auto_approval_tickets
|
||
|
|
# --------------------------------------------------------------------------
|
||
|
|
op.create_table(
|
||
|
|
'auto_approval_tickets',
|
||
|
|
sa.Column('id', sa.String(36), primary_key=True),
|
||
|
|
sa.Column('action_id', sa.String(36), nullable=False, index=True),
|
||
|
|
sa.Column('session_id', sa.String(36), nullable=False, index=True),
|
||
|
|
sa.Column('approver_id', sa.String(64), nullable=True),
|
||
|
|
sa.Column('channel', sa.String(16), nullable=False, server_default='agent'),
|
||
|
|
sa.Column('status', sa.String(20), nullable=False, server_default='pending', index=True),
|
||
|
|
sa.Column('reason', sa.Text(), nullable=True),
|
||
|
|
sa.Column('decision_note', sa.Text(), nullable=True),
|
||
|
|
sa.Column('decided_at', sa.DateTime(timezone=True), nullable=True),
|
||
|
|
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
|
||
|
|
)
|
||
|
|
op.create_index('idx_auto_approval_action', 'auto_approval_tickets', ['action_id'])
|
||
|
|
op.create_index('idx_auto_approval_session', 'auto_approval_tickets', ['session_id'])
|
||
|
|
|
||
|
|
# --------------------------------------------------------------------------
|
||
|
|
# 4. 场景配置 auto_scenario_configs
|
||
|
|
# --------------------------------------------------------------------------
|
||
|
|
op.create_table(
|
||
|
|
'auto_scenario_configs',
|
||
|
|
sa.Column('id', sa.String(36), primary_key=True),
|
||
|
|
sa.Column('scenario_key', sa.String(64), nullable=False, unique=True, index=True),
|
||
|
|
sa.Column('name', sa.String(128), nullable=False, server_default=''),
|
||
|
|
sa.Column('description', sa.Text(), nullable=False, server_default=''),
|
||
|
|
sa.Column('enabled', sa.Boolean(), nullable=False, server_default=sa.true()),
|
||
|
|
sa.Column('trigger_conditions', sa.JSON(), nullable=True),
|
||
|
|
sa.Column('actions', sa.JSON(), nullable=True),
|
||
|
|
sa.Column('approval_strategy', sa.JSON(), nullable=True),
|
||
|
|
sa.Column('current_version_id', sa.String(36), nullable=True),
|
||
|
|
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
|
||
|
|
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False),
|
||
|
|
)
|
||
|
|
op.create_index('idx_auto_scenario_key', 'auto_scenario_configs', ['scenario_key'])
|
||
|
|
|
||
|
|
# --------------------------------------------------------------------------
|
||
|
|
# 5. 规则版本 auto_rule_versions
|
||
|
|
# --------------------------------------------------------------------------
|
||
|
|
op.create_table(
|
||
|
|
'auto_rule_versions',
|
||
|
|
sa.Column('id', sa.String(36), primary_key=True),
|
||
|
|
sa.Column('scenario_key', sa.String(64), nullable=False, index=True),
|
||
|
|
sa.Column('version', sa.Integer(), nullable=False, server_default='1'),
|
||
|
|
sa.Column('content', sa.JSON(), nullable=True),
|
||
|
|
sa.Column('status', sa.String(20), nullable=False, server_default='draft', index=True),
|
||
|
|
sa.Column('canary_percent', sa.Integer(), nullable=False, server_default='100'),
|
||
|
|
sa.Column('created_by', sa.String(64), nullable=True),
|
||
|
|
sa.Column('remark', sa.Text(), nullable=False, server_default=''),
|
||
|
|
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
|
||
|
|
)
|
||
|
|
op.create_index('idx_auto_rule_version_scenario', 'auto_rule_versions', ['scenario_key'])
|
||
|
|
|
||
|
|
# --------------------------------------------------------------------------
|
||
|
|
# 6. 外部调用审计日志 auto_action_logs
|
||
|
|
# --------------------------------------------------------------------------
|
||
|
|
op.create_table(
|
||
|
|
'auto_action_logs',
|
||
|
|
sa.Column('id', sa.String(36), primary_key=True),
|
||
|
|
sa.Column('session_id', sa.String(36), nullable=True, index=True),
|
||
|
|
sa.Column('action_id', sa.String(36), nullable=True, index=True),
|
||
|
|
sa.Column('employee_id', sa.String(64), nullable=True),
|
||
|
|
sa.Column('event', sa.String(128), nullable=False, server_default=''),
|
||
|
|
sa.Column('direction', sa.String(8), nullable=False, server_default='out'),
|
||
|
|
sa.Column('system', sa.String(32), nullable=False, server_default='internal'),
|
||
|
|
sa.Column('request', sa.JSON(), nullable=True),
|
||
|
|
sa.Column('response', sa.JSON(), nullable=True),
|
||
|
|
sa.Column('status', sa.String(32), nullable=False, server_default=''),
|
||
|
|
sa.Column('latency_ms', sa.Integer(), nullable=True),
|
||
|
|
sa.Column('error', sa.Text(), nullable=True),
|
||
|
|
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
|
||
|
|
)
|
||
|
|
op.create_index('idx_auto_action_log_session', 'auto_action_logs', ['session_id'])
|
||
|
|
op.create_index('idx_auto_action_log_action', 'auto_action_logs', ['action_id'])
|
||
|
|
|
||
|
|
# --------------------------------------------------------------------------
|
||
|
|
# 7. 映射缓存 auto_mapping_cache
|
||
|
|
# --------------------------------------------------------------------------
|
||
|
|
op.create_table(
|
||
|
|
'auto_mapping_cache',
|
||
|
|
sa.Column('id', sa.String(36), primary_key=True),
|
||
|
|
sa.Column('employee_id', sa.String(64), nullable=False, index=True),
|
||
|
|
sa.Column('source', sa.String(32), nullable=False, server_default='lianruan'),
|
||
|
|
sa.Column('mapped_data', sa.JSON(), nullable=True),
|
||
|
|
sa.Column('expires_at', sa.DateTime(timezone=True), nullable=True),
|
||
|
|
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
|
||
|
|
)
|
||
|
|
op.create_index('idx_auto_mapping_employee', 'auto_mapping_cache', ['employee_id'])
|
||
|
|
|
||
|
|
|
||
|
|
def downgrade() -> None:
|
||
|
|
op.drop_table('auto_mapping_cache')
|
||
|
|
op.drop_table('auto_action_logs')
|
||
|
|
op.drop_table('auto_rule_versions')
|
||
|
|
op.drop_table('auto_scenario_configs')
|
||
|
|
op.drop_table('auto_approval_tickets')
|
||
|
|
op.drop_table('auto_actions')
|
||
|
|
op.drop_table('auto_sessions')
|