# ER 图(数据范式草案) | 字段 | 值 | |---|---| | 版本 | v0.1(草案) | | 最后更新日期 | 2026-10-14 | | 状态 | **草稿 · 待确认** | | 本次变更原因 | 初次创建,基于存量调研逆向还原 | | 图示规范 | mermaid(禁止静态图片,见 rules/11 必须规则 9) | > **重要说明(评审 S5 修复)**: > **① 本文档描述的是 v2 目标态,不是存量现状。**凡与存量实现冲突处,以本文档为准。 > **② 字段来源于逆向还原**(存量代码 + 云函数调用点),未与云函数源码逐字段核对。 > **③ 标 `❓` 的字段/实体/关系尚未证实**,需在阶段②核对契约后定稿。 > **④ 禁止据此图直接建表。** > **⑤ v2 数据源事实**:`AgentTask` / `AgentTaskRun` / `AgentLiveEvent` 三表**已于 2026-10-13 建成**(含 `company` 指针); > 存量 `FmodeAgent.tasks[]` 死字段路径**废弃**。当前唯一缺口是**云函数接收端未实现**。 --- ## 一、平台与租户(基础层) ```mermaid erDiagram %% 注:Conversation 实体属性见 §三(本图只画关系,不重复定义) Company ||--o{ AppUser : "多租户隔离" Company ||--o{ Agent : "归属" AppUser ||--o{ Agent : "拥有/可见" AppUser ||--o{ Conversation : "参与" Agent ||--o{ Conversation : "参与" Company { string objectId PK string name } AppUser { string objectId PK string username string mobile pointer company FK "Pointer_Company 必须" array roles "超管/普通" bool isDeleted "软删" } Agent { string objectId PK pointer company FK "Pointer_Company 必须" string name string avatar string kind "AI数字生命" pointer owner FK "归属用户" bool isDeleted } ``` **铁律(rules/05、CLAUDE.md 黄金规则 6)**:所有业务表必须带 `company: Pointer`;删除一律软删 `isDeleted=true`。 --- ## 二、运行状态域(云函数 `xlosi3m46q`) **v2 目标态**:任务数据有独立落库表,由容器 kanban 采集上报(见 §二.B)。 ```mermaid erDiagram Agent ||--o| AgentStatus : "实时状态" Agent ||--o{ HostMetric : "主机指标" Agent ||--o{ Channel : "通道配置" Agent ||--o{ AgentTask : "多任务(真源)" AgentStatus { pointer agent FK pointer company FK "必须" string status "running/idle/error/offline" string currentTask "当前任务(单值,来自 env)" string currentAction "❓" string headline "❓" string balance "❓余额(服务端换算后余额,支撑 AC-07.1/07.4)" string balancePageUrl "❓余额外链地址(支撑 AC-07.4)" bool isDeleted datetime updatedAt } HostMetric { pointer agent FK pointer company FK "必须" float cpu float memory float disk "❓" int uptime "❓" bool isDeleted } Channel { pointer agent FK pointer company FK "必须" string type "❓" string name "❓" bool enabled "❓" bool isDeleted } ``` > **⚠️ 存量问题(保留警示)**:存量 `FmodeAgent.tasks[]` 数组字段**从未落库上报**, > `core/tasks.service.ts` 的多任务分支永不命中 —— "多任务并行"在**存量中**是宣传语而非实现。 > **v2 处置**:废弃该字段路径,改由下节的三张表承载(裁决:任务看板纳入,见 SPEC FR-07b)。 #### §二.B 任务域(v2 新增数据源 · 真源) ```mermaid erDiagram Agent ||--o{ AgentTask : "产出" AgentTask ||--o{ AgentTaskRun : "运行流水" AgentTask ||--o{ AgentLiveEvent : "事件(仅落库)" AgentTask ||--o{ AgentTaskComment : "评论" AgentTask ||--o{ AgentTaskAttachment : "附件" AgentTask { pointer agent FK pointer company FK "必须" string taskId "源 kanban.db tasks.id" string title string status "triage/todo/scheduled/ready/running/blocked/done" string assignee "❓取值域待核" int priority "❓" string body "markdown,截断 4000" string branchName "❓" string projectId "❓" string blockKind "❓阻塞类型" int consecutiveFailures "❓连续失败数" string lastFailureError "❓" string currentStepKey "❓" datetime startedAt "❓" datetime completedAt "❓" datetime lastHeartbeatAt "❓" datetime createdAt "❓" bool isDeleted } AgentTaskRun { pointer task FK "❓" pointer company FK "必须" int runId "源 task_runs.id" string status "running/done/blocked/crashed/timed_out/failed/released" string outcome "completed/blocked/crashed/timed_out/spawn_failed/gave_up/reclaimed" string stepKey "❓" string summary "❓截断 1000" string error "❓" int workerPid "❓" datetime startedAt "❓" datetime endedAt "❓" bool isDeleted } AgentLiveEvent { pointer task FK "❓" pointer company FK "必须" int eventId "源 task_events.id" string kind "❓" object payload "❓按需截断" datetime createdAt "❓" bool isDeleted } AgentTaskComment { pointer task FK "必须" pointer company FK "必须" int commentId "源 task_comments.id" string author "❓取值域待核" string body "截断 2000" datetime createdAt bool isDeleted } AgentTaskAttachment { pointer task FK "必须" pointer company FK "必须" int attachmentId "源 task_attachments.id" string filename string storedPath "容器内路径,非外链" string contentType "❓" int size datetime createdAt bool isDeleted } ``` > **建表状态**:`AgentTask` / `AgentTaskRun` / `AgentLiveEvent` 三表**已于 2026-10-13 建成** > (`AgentTask` 21 业务字段 / `AgentTaskRun` 13 / `AgentLiveEvent` 14,均含 `company` Pointer)。 > ✅ `company` 指针**已证实存在**;其余字段名与取值域**待核对**(见 §七 核对表)。 > > 🔴 **`AgentTaskComment` / `AgentTaskAttachment` 两表尚未建成**(本图为 v2 目标态)。 > **为何需要**:SPEC FR-07b AC-07b.2 要求任务详情展示"评论 / 附件",而源库 `kanban.db` > **确有** `task_comments`(19 条)/ `task_attachments`(7 条)两表,且采集脚本 `kanban-report.py` > **已采集**这两类数据并放入 payload。若只为三张表落库,这两类数据会**丢在云函数里**。 > **结论**:这是**云函数改造的一并新增**,与 FR-07b 同属一个工作流,不额外增加阻塞面。 > **备选(若建表审批受阻)**:将评论/附件以 JSON 存入 `AgentTask.extra`,但会牺牲查询能力; > **推荐建表**。 > > **前端消费口径**:`AgentTask`/`AgentTaskRun`/`AgentTaskComment`/`AgentTaskAttachment` = 任务看板消费; > **`AgentLiveEvent` 一期仅落库,前端不消费**(SPEC FR-07b)。 --- ## 三、会话域(Matrix + provision) ```mermaid erDiagram Agent ||--o| MatrixConfig : "容器签发(RP5Ht55NeX)" Agent ||--o{ Message : "消息" Conversation ||--o{ Message : "包含" MatrixConfig { pointer agent FK pointer company FK "必须" bool isDeleted string userId "mxUserId" string homeserverUrl string accessToken "❓前端持有的凭据形态待确认" bool provisioned datetime provisionedAt } Conversation { string roomId PK "Matrix room id" pointer agent FK pointer user FK pointer company FK "必须" bool isDeleted string lastMessagePreview datetime lastMessageAt int unread } Message { string eventId PK "Matrix event id" string roomId FK string sender string body string msgType "text/file/image/video" string mediaUrl "OBS 外链 ❓" pointer company FK "必须" bool isDeleted datetime ts } ``` > **安全注记**:`MatrixConfig.accessToken` 的存储位置与生命周期需在阶段②明确; > 存量 `core/matrix-client.ts` 存在**明文 TURN 凭据硬编码**(违反黄金规则 9),v2 必须改为服务端签发。 --- ## 四、交付与项目域(云函数 `lfYlgU7SkK`) ```mermaid erDiagram Project ||--o{ Deliverable : "包含" Agent ||--o{ Deliverable : "产出" Deliverable ||--o{ Artifact : "附件" Project ||--o{ Conversation : "关联会话 ❓未证实" Project { string objectId PK "❓实体存在性待核对(见七-4)" pointer company FK "必须" string name "❓" string status "❓" bool isDeleted } Deliverable { string objectId PK pointer company FK "必须" pointer project FK "❓" pointer agent FK "必须" string title string summary string type "交付物类型" datetime deliveredAt bool isDeleted "必须" } Artifact { string objectId PK pointer company FK "必须" bool isDeleted pointer deliverable FK string name string kind "file/image/video" string url "OBS 外链 ❓" int size "❓" string mime "❓" } ``` --- ## 五、事件域(派生,非独立表) ```mermaid erDiagram Event { string id PK "派生的合成 id" string category "delivery/exec/alert" string level "info/warn/error" pointer agent FK string title string detail datetime ts } ``` > **注**:存量 `EventsService` 的"事件"是**由交付物 + 状态派生**的合成数据,无独立事件表。 > 若 v2 需要真实事件流(审计/告警),须新增服务端落库——**这是潜在的新需求**,已列访谈问卷 Q3.4。 --- ## 六、云函数契约索引(待补详细 API 文档) | 云函数 ID | 用途 | 涉及实体 | 契约文档 | |---|---|---|---| | `xlosi3m46q` | 数字生命状态 | AgentStatus / HostMetric / (AgentTask ❓) | `docs/03-interface/api/` 待建 | | `lfYlgU7SkK` | 交付物 | Deliverable / Artifact | 待建 | | `RP5Ht55NeX` | Matrix 容器签发 | MatrixConfig | 待建 | | `zl4yU8PAEB` | Token 同步 + **租户权威判定**(SPEC FR-02 AC-02.4 的承载方) | `AppUser.company` | 待建 | | `AlP56LCKFm` | 上传预签名 | Artifact | 待建 | 统一入口:`POST https://server.fmode.cn/api/functions`,请求体 `{ id, token, params }`。 --- ## 七、定稿前必须核对的事项 | # | 待核对项 | 方式 | |---|---|---| | 1 | `AgentTask`/`tasks[]` 是否存在、字段定义 | 查云函数源码或问服务端归属方 | | 2 | `AgentStatus` 全字段名(现为逆向推测) | 同上 | | 3 | `Deliverable`/`Artifact` 字段名与类型 | 同上 | | 4 | `Project` 是否真实存在独立表 | 同上 | | 5 | 各表的 `company` 隔离落实情况 | 平台 Schema 查看 | | 6 | 软删 `isDeleted` 是否所有业务表都有 | 同上 |