from __future__ import annotations from datetime import datetime from sqlalchemy import BigInteger, DateTime, ForeignKey, Integer, String, Text, UniqueConstraint, func from sqlalchemy.orm import Mapped, mapped_column, relationship from app.models.base import Base, TimestampMixin class Knowledge(Base, TimestampMixin): __tablename__ = "sys_knowledge" id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) name: Mapped[str] = mapped_column(String(100), nullable=False) feishu_space_id: Mapped[str] = mapped_column(String(100), nullable=False) feishu_node_id: Mapped[str] = mapped_column(String(100), nullable=False) status: Mapped[int] = mapped_column(default=1, nullable=False) remark: Mapped[str | None] = mapped_column(String(255), nullable=True) source_title: Mapped[str | None] = mapped_column(String(255), nullable=True) knowledge_type: Mapped[str] = mapped_column(String(30), default="general", nullable=False) review_mode: Mapped[str] = mapped_column(String(30), default="manual", nullable=False) lifecycle_status: Mapped[str] = mapped_column(String(30), default="active", nullable=False) source_status: Mapped[str] = mapped_column(String(30), default="normal", nullable=False) source_error: Mapped[str | None] = mapped_column(Text, nullable=True) manifest_confirmed: Mapped[int] = mapped_column(Integer, default=0, nullable=False) current_version_id: Mapped[int | None] = mapped_column(BigInteger, nullable=True) pending_version_id: Mapped[int | None] = mapped_column(BigInteger, nullable=True) last_synced_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) last_published_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) migration_status: Mapped[str] = mapped_column(String(30), default="pending", nullable=False) user_permissions: Mapped[list["UserKnowledgePermission"]] = relationship( "UserKnowledgePermission", back_populates="knowledge" ) class UserKnowledgePermission(Base, TimestampMixin): __tablename__ = "sys_user_kb" id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) user_id: Mapped[int] = mapped_column(ForeignKey("sys_user.id"), index=True, nullable=False) knowledge_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge.id"), index=True, nullable=False) effective_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) expired_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) created_by: Mapped[int | None] = mapped_column(BigInteger, nullable=True) user: Mapped["User"] = relationship("User", back_populates="knowledge_permissions") knowledge: Mapped[Knowledge] = relationship("Knowledge", back_populates="user_permissions") class KnowledgeSourceSnapshot(Base): __tablename__ = "sys_knowledge_source_snapshot" id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) knowledge_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge.id"), index=True, nullable=False) sync_job_id: Mapped[int | None] = mapped_column(BigInteger, index=True, nullable=True) source_title: Mapped[str] = mapped_column(String(255), nullable=False) source_content: Mapped[str] = mapped_column(Text, nullable=False) content_hash: Mapped[str] = mapped_column(String(64), index=True, nullable=False) source_identifier: Mapped[str] = mapped_column(String(255), nullable=False) fetched_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), nullable=False) created_by: Mapped[int | None] = mapped_column(BigInteger, nullable=True) class KnowledgeVersion(Base): __tablename__ = "sys_knowledge_version" __table_args__ = (UniqueConstraint("knowledge_id", "version_no", name="uq_kb_version_no"),) id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) knowledge_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge.id"), index=True, nullable=False) snapshot_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge_source_snapshot.id"), nullable=False) version_no: Mapped[int] = mapped_column(Integer, nullable=False) status: Mapped[str] = mapped_column(String(30), index=True, nullable=False) quality_status: Mapped[str] = mapped_column(String(30), default="pending", nullable=False) change_summary: Mapped[str | None] = mapped_column(Text, nullable=True) quality_report: Mapped[str | None] = mapped_column(Text, nullable=True) processing_rule_version: Mapped[str] = mapped_column(String(50), nullable=False) generation_model: Mapped[str | None] = mapped_column(String(100), nullable=True) created_by: Mapped[int | None] = mapped_column(BigInteger, nullable=True) created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), nullable=False) published_by: Mapped[int | None] = mapped_column(BigInteger, nullable=True) published_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) class KnowledgeManifest(Base): __tablename__ = "sys_knowledge_manifest" id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) knowledge_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge.id"), index=True, nullable=False) version_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge_version.id"), index=True, nullable=False) purpose: Mapped[str] = mapped_column(Text, nullable=False) applicable_questions: Mapped[str] = mapped_column(Text, nullable=False) inapplicable_questions: Mapped[str] = mapped_column(Text, nullable=False) core_topics: Mapped[str] = mapped_column(Text, nullable=False) entities: Mapped[str | None] = mapped_column(Text, nullable=True) boundaries: Mapped[str | None] = mapped_column(Text, nullable=True) content_hash: Mapped[str] = mapped_column(String(64), nullable=False) change_level: Mapped[str] = mapped_column(String(20), default="major", nullable=False) confirmed: Mapped[int] = mapped_column(Integer, default=0, nullable=False) confirmed_by: Mapped[int | None] = mapped_column(BigInteger, nullable=True) confirmed_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) class KnowledgeSection(Base): __tablename__ = "sys_knowledge_section" id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) knowledge_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge.id"), index=True, nullable=False) version_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge_version.id"), index=True, nullable=False) section_key: Mapped[str] = mapped_column(String(64), nullable=False) title: Mapped[str] = mapped_column(String(255), nullable=False) content: Mapped[str] = mapped_column(Text, nullable=False) source_start: Mapped[int] = mapped_column(Integer, nullable=False) source_end: Mapped[int] = mapped_column(Integer, nullable=False) sort_order: Mapped[int] = mapped_column(Integer, nullable=False) content_hash: Mapped[str] = mapped_column(String(64), nullable=False) class KnowledgeChunk(Base): __tablename__ = "sys_knowledge_chunk" id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) knowledge_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge.id"), index=True, nullable=False) version_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge_version.id"), index=True, nullable=False) section_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge_section.id"), index=True, nullable=False) title: Mapped[str] = mapped_column(String(255), nullable=False) content: Mapped[str] = mapped_column(Text, nullable=False) normalized_text: Mapped[str] = mapped_column(Text, nullable=False) keywords: Mapped[str | None] = mapped_column(Text, nullable=True) synonyms: Mapped[str | None] = mapped_column(Text, nullable=True) source_start: Mapped[int] = mapped_column(Integer, nullable=False) source_end: Mapped[int] = mapped_column(Integer, nullable=False) sort_order: Mapped[int] = mapped_column(Integer, nullable=False) content_hash: Mapped[str] = mapped_column(String(64), nullable=False) class KnowledgeCard(Base): __tablename__ = "sys_knowledge_card" id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) knowledge_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge.id"), index=True, nullable=False) version_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge_version.id"), index=True, nullable=False) section_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge_section.id"), index=True, nullable=False) title: Mapped[str] = mapped_column(String(255), nullable=False) summary: Mapped[str] = mapped_column(Text, nullable=False) core_conclusion: Mapped[str] = mapped_column(Text, nullable=False) applicable_questions: Mapped[str] = mapped_column(Text, nullable=False) inapplicable_questions: Mapped[str] = mapped_column(Text, nullable=False) keywords: Mapped[str] = mapped_column(Text, nullable=False) synonyms: Mapped[str | None] = mapped_column(Text, nullable=True) entities: Mapped[str | None] = mapped_column(Text, nullable=True) risk_level: Mapped[str] = mapped_column(String(20), default="normal", nullable=False) source_range: Mapped[str] = mapped_column(String(100), nullable=False) content_hash: Mapped[str] = mapped_column(String(64), nullable=False) generation_model: Mapped[str | None] = mapped_column(String(100), nullable=True) generation_rule_version: Mapped[str] = mapped_column(String(50), nullable=False) review_status: Mapped[str] = mapped_column(String(20), default="pending", nullable=False) class KnowledgeSyncJob(Base): __tablename__ = "sys_knowledge_sync_job" id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) knowledge_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge.id"), index=True, nullable=False) mode: Mapped[str] = mapped_column(String(30), nullable=False) status: Mapped[str] = mapped_column(String(30), index=True, nullable=False) stage: Mapped[str] = mapped_column(String(50), nullable=False) progress: Mapped[int] = mapped_column(Integer, default=0, nullable=False) source_error: Mapped[str | None] = mapped_column(Text, nullable=True) result_summary: Mapped[str | None] = mapped_column(Text, nullable=True) requested_by: Mapped[int] = mapped_column(BigInteger, nullable=False) created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), nullable=False) started_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) finished_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) class KnowledgeReviewRecord(Base): __tablename__ = "sys_knowledge_review_record" id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) knowledge_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge.id"), index=True, nullable=False) version_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge_version.id"), index=True, nullable=False) card_id: Mapped[int | None] = mapped_column(ForeignKey("sys_knowledge_card.id"), nullable=True) action: Mapped[str] = mapped_column(String(30), nullable=False) reason: Mapped[str | None] = mapped_column(Text, nullable=True) reviewed_by: Mapped[int] = mapped_column(BigInteger, nullable=False) created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), nullable=False) class KnowledgePublishLog(Base): __tablename__ = "sys_knowledge_publish_log" id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) knowledge_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge.id"), index=True, nullable=False) from_version_id: Mapped[int | None] = mapped_column(BigInteger, nullable=True) to_version_id: Mapped[int | None] = mapped_column(BigInteger, nullable=True) action: Mapped[str] = mapped_column(String(30), nullable=False) keep_open: Mapped[int] = mapped_column(Integer, default=0, nullable=False) detail_json: Mapped[str | None] = mapped_column(Text, nullable=True) operated_by: Mapped[int] = mapped_column(BigInteger, nullable=False) created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), nullable=False) class KnowledgeRetrievalLog(Base): __tablename__ = "sys_knowledge_retrieval_log" id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) session_id: Mapped[int | None] = mapped_column(BigInteger, index=True, nullable=True) message_id: Mapped[int | None] = mapped_column(BigInteger, index=True, nullable=True) user_id: Mapped[int | None] = mapped_column(BigInteger, index=True, nullable=True) question: Mapped[str] = mapped_column(Text, nullable=False) catalog_snapshot: Mapped[str] = mapped_column(Text, nullable=False) catalog_hash: Mapped[str] = mapped_column(String(64), nullable=False) safety_rule_version: Mapped[str] = mapped_column(String(50), nullable=False) knowledge_called: Mapped[int] = mapped_column(Integer, default=0, nullable=False) selected_knowledge_ids: Mapped[str | None] = mapped_column(String(500), nullable=True) query_terms: Mapped[str | None] = mapped_column(Text, nullable=True) tool_trace: Mapped[str | None] = mapped_column(Text, nullable=True) final_section_ids: Mapped[str | None] = mapped_column(String(500), nullable=True) discarded_conflicts: Mapped[str | None] = mapped_column(Text, nullable=True) final_answer: Mapped[str | None] = mapped_column(Text, nullable=True) status: Mapped[str] = mapped_column(String(20), nullable=False) tool_cost_ms: Mapped[int | None] = mapped_column(Integer, nullable=True) total_cost_ms: Mapped[int | None] = mapped_column(Integer, nullable=True) error_message: Mapped[str | None] = mapped_column(Text, nullable=True) attention_created: Mapped[int] = mapped_column(Integer, default=0, nullable=False) created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), nullable=False) class KnowledgeRetrievalCandidate(Base): __tablename__ = "sys_knowledge_retrieval_candidate" id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) retrieval_log_id: Mapped[int] = mapped_column(ForeignKey("sys_knowledge_retrieval_log.id"), index=True, nullable=False) knowledge_id: Mapped[int] = mapped_column(BigInteger, index=True, nullable=False) version_id: Mapped[int] = mapped_column(BigInteger, index=True, nullable=False) chunk_id: Mapped[int] = mapped_column(BigInteger, nullable=False) section_id: Mapped[int] = mapped_column(BigInteger, nullable=False) lexical_score: Mapped[str] = mapped_column(String(30), nullable=False) rerank_score: Mapped[str | None] = mapped_column(String(30), nullable=True) selected: Mapped[int] = mapped_column(Integer, default=0, nullable=False) discard_reason: Mapped[str | None] = mapped_column(String(255), nullable=True) class HumanAttentionRecord(Base): __tablename__ = "sys_human_attention_record" id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) session_id: Mapped[int] = mapped_column(BigInteger, index=True, nullable=False) message_id: Mapped[int] = mapped_column(BigInteger, index=True, nullable=False) user_id: Mapped[int] = mapped_column(BigInteger, index=True, nullable=False) trigger_message: Mapped[str] = mapped_column(Text, nullable=False) problem_summary: Mapped[str] = mapped_column(Text, nullable=False) trigger_reason: Mapped[str] = mapped_column(Text, nullable=False) priority: Mapped[str] = mapped_column(String(20), index=True, nullable=False) status: Mapped[str] = mapped_column(String(20), index=True, default="pending", nullable=False) handler_id: Mapped[int | None] = mapped_column(BigInteger, nullable=True) handler_note: Mapped[str | None] = mapped_column(Text, nullable=True) created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), nullable=False) updated_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), onupdate=func.now(), nullable=False) class HumanAttentionHistory(Base): __tablename__ = "sys_human_attention_history" id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) attention_id: Mapped[int] = mapped_column(ForeignKey("sys_human_attention_record.id"), index=True, nullable=False) from_status: Mapped[str | None] = mapped_column(String(20), nullable=True) to_status: Mapped[str] = mapped_column(String(20), nullable=False) note: Mapped[str | None] = mapped_column(Text, nullable=True) operated_by: Mapped[int] = mapped_column(BigInteger, nullable=False) created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), nullable=False)