# ============================================================================= # 企微IT智能服务台 — 知识库优化建议 Pydantic Schema # ============================================================================= # 说明:定义知识库优化建议的请求/响应数据结构 # 包含:建议创建、审核、列表查询等 # ============================================================================= from datetime import datetime from typing import Any, Dict, List, Optional from pydantic import BaseModel, Field from app.schemas.enums import ( AudienceEnum, GraphSyncStatusEnum, RelationTypeEnum, SourceTypeEnum, SuggestionStatusEnum, ) # ----------------------------------------------------------------------------- # 创建建议请求 Schema # ----------------------------------------------------------------------------- class KnowledgeSuggestionCreate(BaseModel): """创建知识库优化建议请求 Schema。 通常由AI分析服务自动创建,也可手动创建。 新增 Tier0 图字段 + audience + confidence。 """ suggestion_type: str = Field( ..., description="建议类型:new_faq=新增FAQ/update=更新/outdated=标记过时", ) title: str = Field(..., description="建议标题", max_length=256) content: str = Field(..., description="答案内容") category: str = Field(default="其他", description="分类") tags: List[str] = Field(default_factory=list, description="标签列表") source_type: str = Field( ..., description="分析来源:annotation=标注数据/conversation=会话数据/ai_uncertain=AI不确定/manual=手动录入/document_ragflow=RAGFlow文档", ) source_data: Optional[List[str]] = Field( default=None, description="相关会话ID或标注ID列表" ) reason: Optional[str] = Field(default=None, description="生成理由") # ── Tier0 扩展字段 ── confidence: Optional[float] = Field( default=None, description="AI 生成置信度(0.0-1.0)", ge=0.0, le=1.0 ) audience: Optional[AudienceEnum] = Field( default=None, description="受众类型" ) issue: Optional[str] = Field( default=None, description="图节点:问题名称", max_length=256 ) action: Optional[str] = Field( default=None, description="图节点:动作名称", max_length=256 ) relation_type: Optional[RelationTypeEnum] = Field( default=None, description="图关系类型" ) parent_issue: Optional[str] = Field( default=None, description="父 Issue 名称", max_length=256 ) graph_meta: Optional[Dict[str, Any]] = Field( default=None, description="图结构扩展元数据" ) # ----------------------------------------------------------------------------- # 审核建议请求 Schema # ----------------------------------------------------------------------------- class KnowledgeSuggestionApprove(BaseModel): """审核通过知识库优化建议请求 Schema。""" pass class KnowledgeSuggestionReject(BaseModel): """拒绝知识库优化建议请求 Schema。""" reject_reason: str = Field(..., description="拒绝理由", max_length=500) # ----------------------------------------------------------------------------- # 改写建议请求 Schema(Tier0 新增 — 训练师改写提案) # ----------------------------------------------------------------------------- class KnowledgeSuggestionRewrite(BaseModel): """训练师改写知识库优化建议请求 Schema。 坐席/训练师在审批时可直接修改提案内容后重新提交审批。 改写后状态重置为 pending,重新走审批流程。 """ title: Optional[str] = Field(default=None, description="修改后的标题", max_length=256) content: Optional[str] = Field(default=None, description="修改后的内容") category: Optional[str] = Field(default=None, description="修改后的分类") tags: Optional[List[str]] = Field(default=None, description="修改后的标签列表") confidence: Optional[float] = Field( default=None, description="修改后的置信度", ge=0.0, le=1.0 ) audience: Optional[AudienceEnum] = Field( default=None, description="修改后的受众类型" ) issue: Optional[str] = Field( default=None, description="修改后的图节点:问题名称", max_length=256 ) action: Optional[str] = Field( default=None, description="修改后的图节点:动作名称", max_length=256 ) relation_type: Optional[RelationTypeEnum] = Field( default=None, description="修改后的图关系类型" ) parent_issue: Optional[str] = Field( default=None, description="修改后的父 Issue 名称", max_length=256 ) # ----------------------------------------------------------------------------- # 合并建议请求 Schema(任务3:P2 知识去重合并) # ----------------------------------------------------------------------------- class KnowledgeSuggestionMerge(BaseModel): """合并重复建议请求 Schema。 将 duplicate_id 的建议合并到当前建议(primary), 重复建议状态变为 rejected(合并归入)。 """ duplicate_id: str = Field(..., description="要合并的重复建议ID") # ----------------------------------------------------------------------------- # 知识库优化建议响应 Schema # ----------------------------------------------------------------------------- class KnowledgeSuggestionResponse(BaseModel): """知识库优化建议响应 Schema。 返回建议记录详情,包含 Tier0 所有扩展字段。 """ id: str = Field(..., description="建议ID") suggestion_type: str = Field(..., description="建议类型") status: str = Field(..., description="状态") title: str = Field(..., description="标题") content: str = Field(..., description="内容") category: str = Field(..., description="分类") tags: List[str] = Field(default_factory=list, description="标签列表") source_type: str = Field(..., description="分析来源") source_data: Optional[List[str]] = Field(default=None, description="来源数据") reason: Optional[str] = Field(default=None, description="生成理由") reject_reason: Optional[str] = Field(default=None, description="拒绝理由") reviewer_id: Optional[str] = Field(default=None, description="审核人ID") reviewed_at: Optional[datetime] = Field(default=None, description="审核时间") # ── Tier0 扩展字段 ── confidence: Optional[float] = Field(default=None, description="AI 生成置信度") audience: Optional[str] = Field(default=None, description="受众类型") issue: Optional[str] = Field(default=None, description="图节点:问题名称") action: Optional[str] = Field(default=None, description="图节点:动作名称") relation_type: Optional[str] = Field(default=None, description="图关系类型") parent_issue: Optional[str] = Field(default=None, description="父 Issue 名称") graph_meta: Optional[Dict[str, Any]] = Field( default=None, description="图结构扩展元数据" ) graph_sync_status: Optional[str] = Field( default="pending", description="图同步状态" ) source_failed: bool = Field(default=False, description="AI 生成失败标记") queued_at: Optional[datetime] = Field(default=None, description="入队列时间") applied_at: Optional[datetime] = Field(default=None, description="应用到 KB 的时间") created_at: datetime = Field(..., description="创建时间") updated_at: datetime = Field(..., description="更新时间") class Config: from_attributes = True # ----------------------------------------------------------------------------- # 知识库优化建议列表响应 Schema # ----------------------------------------------------------------------------- class KnowledgeSuggestionListResponse(BaseModel): """知识库优化建议列表响应 Schema。""" total: int = Field(..., description="总数量") items: List[KnowledgeSuggestionResponse] = Field(..., description="建议列表") # ----------------------------------------------------------------------------- # 知识库优化建议统计 Schema # ----------------------------------------------------------------------------- class KnowledgeSuggestionStatsResponse(BaseModel): """知识库优化建议统计响应 Schema。""" total: int = Field(..., description="总建议数") pending: int = Field(..., description="待审核数") queued: int = Field(0, description="队列中数") approved: int = Field(..., description="已通过数") rejected: int = Field(..., description="已拒绝数") applied: int = Field(..., description="已应用数") graph_synced: int = Field(0, description="图已同步数") expired: int = Field(0, description="已过期数") new_faq_count: int = Field(..., description="新增FAQ建议数") update_count: int = Field(..., description="更新建议数") outdated_count: int = Field(..., description="过时标记数")