//! 数据模型定义 — 与数据库表对应的 Rust 结构体 use df_ai_core::model::{deserialize_model_configs, ModelConfig}; use serde::{Deserialize, Serialize}; // ============================================================ // 想法相关模型 // ============================================================ /// 想法记录 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct IdeaRecord { pub id: String, pub title: String, pub description: String, pub status: String, pub priority: i32, pub score: Option, pub tags: Option, // JSON 数组 pub source: Option, pub promoted_to: Option, // 晋升后的 project_id pub ai_analysis: Option, // AI 分析结果 JSON pub scores: Option, // 多维评分 JSON (feasibility/impact/urgency/overall) pub created_at: String, pub updated_at: String, } // ============================================================ // 项目相关模型 // ============================================================ /// 项目记录 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ProjectRecord { pub id: String, pub name: String, pub description: String, pub status: String, pub idea_id: Option, /// 绑定的本地代码目录(绝对路径,可空=未绑定,第二步导入历史项目时复用) pub path: Option, /// 技术栈 JSON 数组字符串(如 ["rust","vue","tauri"],由探测填充,可空) pub stack: Option, pub created_at: String, pub updated_at: String, } // ============================================================ // 任务相关模型 // ============================================================ /// 任务记录 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct TaskRecord { pub id: String, pub project_id: String, pub title: String, pub description: String, pub status: String, pub priority: i32, pub branch_name: Option, pub assignee: Option, pub workflow_def_id: Option, // 关联的工作流定义 ID pub base_branch: Option, // 基础分支 /// review 退回累计轮数(in_review→in_progress / testing→in_review 时 +1, /// 由 advance_task 原子写入,见 df-nodes::task_advance_node)。 /// #[serde(default)] 兼容旧前端无该字段的 JSON(老任务记录默认 0)。 #[serde(default)] pub review_rounds: i32, /// 任务产出 JSON 字符串(AiNode 自审闭环,决策 a:task 中心,产出跟 task 走)。 /// /// 三方读写约定:ai_execute 写产出 / ai_self_review 读产出做自审 / human_review 展示产出对象。 /// 经通用 update_field 写白名单(非 status 那种状态机收口字段),TEXT NULL 向后兼容。 /// #[serde(skip_serializing_if)] 无产出不序列化(省前端字段空值),#[serde(default)] 兼容旧 JSON。 #[serde(skip_serializing_if = "Option::is_none")] #[serde(default)] pub output_json: Option, /// 关联灵感 ID(F-260619-01,1对1 单向,任务→灵感)。 /// 复用 projects.idea_id 模式(REFERENCES ideas(id) 外键),可空(任务可不关联灵感)。 /// 老任务无 idea_id → None。#[serde(default)] 兼容旧前端 JSON(无该字段时为 None)。 #[serde(default)] pub idea_id: Option, pub created_at: String, pub updated_at: String, } /// 分支记录 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct BranchRecord { pub id: String, pub project_id: String, pub task_id: Option, pub name: String, pub base: String, pub status: String, pub created_at: String, pub updated_at: String, pub merged_at: Option, } /// 发布记录 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ReleaseRecord { pub id: String, pub project_id: String, pub version: String, pub status: String, pub task_ids: String, // JSON 数组 pub changelog: Option, pub created_at: String, pub released_at: Option, } // ============================================================ // 工作流相关模型 // ============================================================ /// 工作流执行记录 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct WorkflowRecord { pub id: String, pub name: String, pub dag_json: String, // DAG 的 JSON 序列化 pub status: String, pub triggered_by: Option, pub project_id: Option, // 关联项目 ID pub task_id: Option, // 关联任务 ID pub created_at: String, pub completed_at: Option, } /// 节点执行记录 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct NodeExecutionRecord { pub id: String, pub workflow_id: String, pub node_id: String, pub node_type: String, pub status: String, pub input_json: Option, pub output_json: Option, pub error_message: Option, pub started_at: Option, pub completed_at: Option, } // ============================================================ // AI 相关模型 (V3) // ============================================================ /// AI 提供商配置记录 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct AiProviderRecord { pub id: String, pub name: String, pub provider_type: String, pub api_key: String, pub base_url: String, pub default_model: String, pub models: Option, // JSON array of model names /// 模型能力配置数组(F-01 阶段1,4 维度 + 路由控制)。 /// DB TEXT 列存 JSON 字符串,from_row 经 deserialize_model_configs 解析。 /// 向后兼容:老库 NULL/空/老字符串数组 → 空 Vec 或转默认 ModelConfig。default_model 保留过渡。 #[serde(default, deserialize_with = "deserialize_model_configs")] pub model_configs: Vec, pub is_default: bool, pub config: Option, // JSON extra config pub created_at: String, pub updated_at: String, /// provider 是否进入负载均衡池(F-260614-04)。false = 仅作为配置存在,不参与主链路由/选池。 /// 老库迁移默认 1(单 provider 路径零变化)。 #[serde(default = "default_enabled")] pub enabled: bool, /// provider 在负载均衡池中的选择权重(0-100,F-260614-04)。高权重优先被选为主; /// 同权重时退化近似轮询。老库迁移默认 50。 #[serde(default = "default_weight")] pub weight: u32, } /// AiProviderRecord.enabled 的 serde 默认(true)。老库/缺字段 JSON → enabled。 fn default_enabled() -> bool { true } /// AiProviderRecord.weight 的 serde 默认(50)。老库/缺字段 JSON → 50。 fn default_weight() -> u32 { 50 } /// AI 对话记录 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct AiConversationRecord { pub id: String, pub title: Option, pub messages: String, // JSON array of ChatMessage pub provider_id: Option, pub model: Option, pub models: Option, // 用过的所有 model(JSON 数组字符串,去重) pub archived: bool, // 是否归档(侧栏折叠展示) pub pinned: bool, // 是否置顶(排序置前;UX-17) pub prompt_tokens: Option, // 输入 token 累计(流式 usage 落库) pub completion_tokens: Option, // 输出 token 累计(流式 usage 落库) pub created_at: String, pub updated_at: String, } /// AI 工具执行审计记录 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct AiToolExecutionRecord { pub id: String, pub conversation_id: Option, /// 消息级溯源:工具调用所属的 ChatMessage.id(F-260619-04)。 /// NULL = 老库行 / 消息级溯源未启用期的记录 / 无法关联的调用。 /// 升级后,audit 写入从 ContextManager 取当前 assistant 消息 id 填入(P1 接入,P0 只建列)。 #[serde(default, skip_serializing_if = "Option::is_none")] pub message_id: Option, pub tool_call_id: String, pub tool_name: String, pub arguments: String, pub result: Option, pub status: String, // pending/approved/rejected/executing/completed/failed pub risk_level: String, // low/medium/high pub requested_at: String, pub executed_at: Option, pub decided_by: Option, // human/auto } /// 消息记录(ai_messages 表,F-260619-03 消息拆分存储)。 /// /// 每条 ChatMessage 一行,替代 `ai_conversations.messages` 的整对话 JSON 列存。 /// 主键 `id` = ChatMessage.id(构造时 ULID 风格生成),(conversation_id, seq) UNIQUE /// 保证对话内序号唯一。本结构仅承载持久化映射,P0 阶段 ContextManager 仍走旧 JSON 列, /// 切读策略待用户决策(P2)。 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct AiMessageRecord { /// 消息全局唯一 ID(= ChatMessage.id),主键 pub id: String, /// 关联对话 ID pub conversation_id: String, /// 对话内序号(排序用,从 0 起) pub seq: i64, /// 消息角色:system/user/assistant/tool pub role: String, /// 文本内容(parts 的 Text 片与 content 一致) pub content: String, /// 多模态 parts JSON(可空) pub parts: Option, /// 工具调用 ID(role=Tool 时必填) pub tool_call_id: Option, /// AI 发起的工具调用 JSON(可空) pub tool_calls: Option, /// 生成该消息的 model(仅 assistant) pub model: Option, /// 消息状态:active/compressed/archived_segment/truncated(默认 active) pub status: String, /// DeepSeek thinking 推理内容(可空) pub reasoning_content: Option, /// 消息创建时间(Unix 毫秒,可空) pub timestamp: Option, /// 落库时间字符串(迁移期 fallback 到对话 created_at) pub created_at: String, } // ============================================================ // 知识库模型 (V7) // ============================================================ /// 知识条目记录(经验沉淀基本单元,共享记忆层) #[derive(Debug, Clone, Serialize, Deserialize)] pub struct KnowledgeRecord { pub id: String, pub kind: String, // KnowledgeKind snake_case(7 种) pub title: String, pub content: String, pub tags: Option, // JSON 数组字符串 pub status: String, // candidate|pending_review|published|archived pub confidence: Option, // high|medium|low(AI 提炼自评,可空) pub reuse_count: i32, // 唯一客观排序信号 pub verified: bool, // 发布审核时一次性人工标 pub source_project: Option, // 来源项目(仅溯源不过滤) pub source_ref: Option, // 来源实体引用(如 conv:{id}) pub reasoning: Option, // AI 提炼判断依据("为何值得沉淀"),手动录入为 None pub created_at: String, pub updated_at: String, } /// 知识生命线事件记录(追加型审计:产生/审核/引用/归档) #[derive(Debug, Clone, Serialize, Deserialize)] pub struct KnowledgeEventRecord { pub id: String, pub knowledge_id: String, pub event_type: String, // created | extracted | status_changed | referenced | archived pub source_ref: Option, // 触发来源: conv:{id} / manual / system pub context_json: Option, // JSON: 因 event_type 而异 pub timestamp: String, }