"""聊天会话与消息模型。""" from datetime import datetime from sqlalchemy import DateTime, ForeignKey, Integer, String, Text from sqlalchemy.orm import Mapped, mapped_column from app.core.ids import new_message_id, new_session_id from app.core.time import utc_now from app.db.base import Base class ChatSession(Base): __tablename__ = "chat_sessions" id: Mapped[str] = mapped_column(String(80), primary_key=True, default=new_session_id) character_id: Mapped[str] = mapped_column(String(80), ForeignKey("characters.id"), index=True) title: Mapped[str | None] = mapped_column(String(200)) status: Mapped[str] = mapped_column(String(40), nullable=False, default="active", index=True) owner_scope: Mapped[str] = mapped_column(String(80), nullable=False, default="", index=True) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now) updated_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), default=utc_now, onupdate=utc_now ) class ChatMessage(Base): __tablename__ = "chat_messages" id: Mapped[str] = mapped_column(String(80), primary_key=True, default=new_message_id) character_id: Mapped[str] = mapped_column(String(80), ForeignKey("characters.id"), index=True) session_id: Mapped[str] = mapped_column(String(80), ForeignKey("chat_sessions.id"), index=True) role: Mapped[str] = mapped_column(String(40), nullable=False) content: Mapped[str] = mapped_column(Text, nullable=False) modality: Mapped[str] = mapped_column(String(40), nullable=False, default="text") run_id: Mapped[str | None] = mapped_column(String(80), ForeignKey("runs.id"), index=True) metadata_json: Mapped[str] = mapped_column(Text, nullable=False, default="{}") sensitivity: Mapped[str] = mapped_column(String(40), nullable=False, default="low") versions_json: Mapped[str] = mapped_column( Text, nullable=False, default="[]", comment="版本历史 JSON 数组:[{content, created_at}],按生成顺序排列,末尾最新", ) active_version_idx: Mapped[int] = mapped_column( Integer, nullable=False, default=0, comment="当前活跃版本在 versions_json 中的索引(0-based)", ) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now) deleted_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))