"""AI 处理可视化日志模型。""" from __future__ import annotations from typing import Optional from sqlalchemy import BigInteger, Float, ForeignKey, Integer, JSON, TEXT, VARCHAR from sqlalchemy.orm import Mapped, mapped_column from .base import Base class AIProcessingLog(Base): __tablename__ = "ai_processing_logs" id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) feishu_message_id: Mapped[Optional[str]] = mapped_column(VARCHAR(128), nullable=True, index=True) feishu_item_id: Mapped[Optional[int]] = mapped_column( BigInteger, ForeignKey("feishu_items.id"), nullable=True, index=True ) raw_message: Mapped[Optional[str]] = mapped_column(TEXT, nullable=True) ai_raw_output: Mapped[Optional[str]] = mapped_column(TEXT, nullable=True) project_score: Mapped[Optional[float]] = mapped_column(Float, nullable=True) signal_confidence: Mapped[Optional[float]] = mapped_column(Float, nullable=True) level: Mapped[Optional[str]] = mapped_column(VARCHAR(20), nullable=True) normalized_text: Mapped[Optional[str]] = mapped_column(TEXT, nullable=True) route: Mapped[Optional[str]] = mapped_column(VARCHAR(80), nullable=True, index=True) intent: Mapped[Optional[str]] = mapped_column(VARCHAR(40), nullable=True, index=True) executor: Mapped[Optional[str]] = mapped_column(VARCHAR(40), nullable=True) operation_code: Mapped[Optional[str]] = mapped_column(VARCHAR(80), nullable=True, index=True) operation_result: Mapped[Optional[dict]] = mapped_column(JSON, nullable=True) reply_source: Mapped[Optional[str]] = mapped_column(VARCHAR(40), nullable=True) routing_decision: Mapped[str] = mapped_column(VARCHAR(64), nullable=False, index=True) routing_reason: Mapped[Optional[str]] = mapped_column(TEXT, nullable=True) reasoning_bullets: Mapped[Optional[list[str]]] = mapped_column(JSON, nullable=True) processing_status: Mapped[str] = mapped_column(VARCHAR(20), nullable=False, default="processing", index=True) error_message: Mapped[Optional[str]] = mapped_column(TEXT, nullable=True) duration_ms: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)