791 lines
27 KiB
Markdown
791 lines
27 KiB
Markdown
# Inbox V2 数据库设计
|
||
|
||
本文档是 `inbox v2` 的数据库开发基线。
|
||
|
||
它服务于三件事:
|
||
|
||
1. 明确 `v2` 到底使用哪些数据库。
|
||
2. 明确每张表的字段、主键、外键和作用。
|
||
3. 明确各张表之间的关系,作为后续 `store / app / http` 实现依据。
|
||
|
||
## 1. 物理数据库
|
||
|
||
`v2` 先只使用 **1 个物理数据库**:
|
||
|
||
| 数据库 | 引擎 | 是否采用 | 用途 |
|
||
| --- | --- | --- | --- |
|
||
| `inbox.db` | SQLite | 是 | 所有运行时业务数据、在线可编辑配置、配置审计 |
|
||
| Redis | - | 否 | 当前不需要单独缓存或队列 |
|
||
| PostgreSQL | - | 否 | 当前先不引入额外运维复杂度 |
|
||
| 独立日志库 | - | 否 | 执行日志先跟主库放一起 |
|
||
| 向量库 | - | 否 | 当前主流程不依赖向量检索 |
|
||
|
||
一句话:
|
||
|
||
- `V2` 先只有一个库:`inbox.db`
|
||
|
||
## 2. 关键决策
|
||
|
||
### 2.1 配置入库
|
||
|
||
因为 `roles / prompts / skills / config` 需要满足:
|
||
|
||
- 前端可编辑
|
||
- 保存后立即生效
|
||
- 不需要改文件后再发版
|
||
|
||
所以第二版里,这些内容的**运行时真源就是数据库**。
|
||
|
||
文件只保留这些作用:
|
||
|
||
- 默认模板
|
||
- 初始化导入源
|
||
- 内置技能的原始资产
|
||
|
||
### 2.2 立即生效的定义
|
||
|
||
这里的“立即生效”定义为:
|
||
|
||
- 配置保存成功后
|
||
- **下一次新的 agent run / 新的消息处理 / 新的 HTTP 请求** 立即读取最新配置
|
||
|
||
不包含:
|
||
|
||
- 已经运行中的 agent 进程半路热切换配置
|
||
|
||
### 2.3 配置覆盖规则
|
||
|
||
在线配置支持两层作用域:
|
||
|
||
1. `global`
|
||
2. `workspace override`
|
||
|
||
解析优先级固定为:
|
||
|
||
`workspace row > global row`
|
||
|
||
也就是说:
|
||
|
||
- 如果某个 workspace 有自己的 prompt/config/binding,就优先使用它
|
||
- 否则回退到全局默认
|
||
|
||
### 2.4 统一建模原则
|
||
|
||
1. 所有业务主键统一使用 `TEXT`
|
||
2. 所有时间统一使用 UTC RFC3339
|
||
3. 核心业务关系用结构化表,不用 JSON blob 代替
|
||
4. JSON 只用于快照和弱结构扩展字段
|
||
5. `topic` 是业务主实体
|
||
6. `product` 接管需求整理文档
|
||
7. `clarifier_state / clarifier_artifacts / topic_records` 在 `v2` 中不再保留
|
||
|
||
## 3. 数据域划分
|
||
|
||
| 数据域 | 表 |
|
||
| --- | --- |
|
||
| 系统 | `schema_migrations` |
|
||
| 项目与工作区 | `projects`, `workspaces` |
|
||
| 在线角色配置 | `roles`, `role_prompts`, `role_configs`, `skills`, `role_skill_bindings` |
|
||
| Topic 与文档 | `topics`, `topic_documents` |
|
||
| 消息协作 | `messages`, `message_deliveries` |
|
||
| Requirement / Discovery / Workflow / Merge | `requirements`, `discovery_rounds`, `discovery_candidates`, `discovery_votes`, `workflow_runs`, `workflow_run_logs`, `merge_requests` |
|
||
|
||
## 4. 表清单总览
|
||
|
||
| 表名 | 数据域 | 说明 |
|
||
| --- | --- | --- |
|
||
| `schema_migrations` | 系统 | 迁移历史 |
|
||
| `projects` | 项目 | 项目主表 |
|
||
| `workspaces` | 工作区 | 工作区主表 |
|
||
| `roles` | 在线角色配置 | 角色定义 |
|
||
| `role_prompts` | 在线角色配置 | 角色提示词 |
|
||
| `role_configs` | 在线角色配置 | 角色模型和运行配置 |
|
||
| `skills` | 在线角色配置 | 技能定义 |
|
||
| `role_skill_bindings` | 在线角色配置 | 角色与技能绑定 |
|
||
| `topics` | Topic | 统一 topic 主实体 |
|
||
| `topic_documents` | Topic | `PRD`、`Decision Log`、Discovery 文档 |
|
||
| `messages` | 消息协作 | 消息信封与正文 |
|
||
| `message_deliveries` | 消息协作 | 消息收件与归档状态 |
|
||
| `requirements` | Requirement | pool 队列项 |
|
||
| `discovery_rounds` | Discovery | discovery 轮次 |
|
||
| `discovery_candidates` | Discovery | discovery 候选项 |
|
||
| `discovery_votes` | Discovery | discovery 投票 |
|
||
| `workflow_runs` | Workflow | 角色执行记录 |
|
||
| `workflow_run_logs` | Workflow | 执行日志流 |
|
||
| `merge_requests` | Merge | merge 请求记录 |
|
||
|
||
## 5. 表字段定义
|
||
|
||
### 5.1 `schema_migrations`
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `version` | `INTEGER` | PK | 迁移版本号 |
|
||
| `name` | `TEXT` | NOT NULL | 迁移名称 |
|
||
| `applied_at` | `TEXT` | NOT NULL | 执行时间 |
|
||
|
||
### 5.2 `projects`
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `id` | `TEXT` | PK | 项目 ID |
|
||
| `slug` | `TEXT` | NOT NULL, UNIQUE | 项目标识 |
|
||
| `name` | `TEXT` | NOT NULL | 展示名称 |
|
||
| `root_path` | `TEXT` | NOT NULL, UNIQUE | 项目根目录 |
|
||
| `default_branch` | `TEXT` | NOT NULL | 默认分支 |
|
||
| `status` | `TEXT` | NOT NULL | `active / archived` |
|
||
| `created_at` | `TEXT` | NOT NULL | 创建时间 |
|
||
| `updated_at` | `TEXT` | NOT NULL | 更新时间 |
|
||
|
||
关系:
|
||
|
||
- `projects 1 -> N workspaces`
|
||
|
||
### 5.3 `workspaces`
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `id` | `TEXT` | PK | 工作区 ID |
|
||
| `project_id` | `TEXT` | FK -> `projects.id` | 所属项目 |
|
||
| `slug` | `TEXT` | NOT NULL, UNIQUE | 工作区标识 |
|
||
| `name` | `TEXT` | NOT NULL | 展示名称 |
|
||
| `root_path` | `TEXT` | NOT NULL, UNIQUE | 工作区路径 |
|
||
| `base_branch` | `TEXT` | NOT NULL | 基线分支 |
|
||
| `worktree_branch` | `TEXT` | NOT NULL, UNIQUE | 工作分支 |
|
||
| `runtime_backend` | `TEXT` | NOT NULL | `local / container / remote` |
|
||
| `status` | `TEXT` | NOT NULL | `active / paused / archived` |
|
||
| `created_at` | `TEXT` | NOT NULL | 创建时间 |
|
||
| `updated_at` | `TEXT` | NOT NULL | 更新时间 |
|
||
|
||
关系:
|
||
|
||
- `workspaces N -> 1 projects`
|
||
- `workspaces 1 -> N topics`
|
||
- `workspaces 1 -> N messages`
|
||
- `workspaces 1 -> N requirements`
|
||
- `workspaces 1 -> N discovery_rounds`
|
||
- `workspaces 1 -> N workflow_runs`
|
||
- `workspaces 1 -> N merge_requests`
|
||
|
||
### 5.4 `roles`
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `name` | `TEXT` | PK | 角色名,例如 `product` |
|
||
| `title` | `TEXT` | NOT NULL | 展示名称 |
|
||
| `category` | `TEXT` | NOT NULL | `product / delivery / review / discovery` |
|
||
| `description` | `TEXT` | NOT NULL DEFAULT `''` | 角色说明 |
|
||
| `is_enabled` | `INTEGER` | NOT NULL | 1 启用,0 禁用 |
|
||
| `is_builtin` | `INTEGER` | NOT NULL | 1 内置,0 自定义 |
|
||
| `sort_order` | `INTEGER` | NOT NULL DEFAULT `0` | 排序 |
|
||
| `created_at` | `TEXT` | NOT NULL | 创建时间 |
|
||
| `updated_at` | `TEXT` | NOT NULL | 更新时间 |
|
||
|
||
关系:
|
||
|
||
- `roles 1 -> N role_prompts`
|
||
- `roles 1 -> N role_configs`
|
||
- `roles 1 -> N role_skill_bindings`
|
||
- `roles 1 -> N messages`
|
||
- `roles 1 -> N message_deliveries`
|
||
- `roles 1 -> N requirements`
|
||
- `roles 1 -> N discovery_candidates`
|
||
- `roles 1 -> N discovery_votes`
|
||
- `roles 1 -> N workflow_runs`
|
||
|
||
### 5.5 `role_prompts`
|
||
|
||
当前生效的提示词表。
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `id` | `TEXT` | PK | 提示词记录 ID |
|
||
| `role_name` | `TEXT` | FK -> `roles.name` | 所属角色 |
|
||
| `workspace_id` | `TEXT` | FK -> `workspaces.id`, NULLABLE | 为空表示全局默认;非空表示 workspace override |
|
||
| `prompt_kind` | `TEXT` | NOT NULL | `system / clarification / plan / review / freeze / execution / verification / discovery` |
|
||
| `content_markdown` | `TEXT` | NOT NULL | 提示词正文 |
|
||
| `version` | `INTEGER` | NOT NULL | 当前版本号 |
|
||
| `updated_by` | `TEXT` | NOT NULL DEFAULT `''` | 修改人或修改来源 |
|
||
| `created_at` | `TEXT` | NOT NULL | 创建时间 |
|
||
| `updated_at` | `TEXT` | NOT NULL | 更新时间 |
|
||
|
||
唯一约束:
|
||
|
||
- 全局:每个 `(role_name, prompt_kind)` 只能有 1 条全局默认记录
|
||
- 工作区:每个 `(role_name, workspace_id, prompt_kind)` 只能有 1 条 override 记录
|
||
|
||
关系:
|
||
|
||
- `role_prompts N -> 1 roles`
|
||
- `role_prompts N -> 1 workspaces`(可空)
|
||
|
||
### 5.6 `role_configs`
|
||
|
||
当前生效的角色运行配置表。
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `id` | `TEXT` | PK | 配置记录 ID |
|
||
| `role_name` | `TEXT` | FK -> `roles.name` | 所属角色 |
|
||
| `workspace_id` | `TEXT` | FK -> `workspaces.id`, NULLABLE | 为空表示全局默认;非空表示 workspace override |
|
||
| `model` | `TEXT` | NOT NULL DEFAULT `''` | 默认模型 |
|
||
| `model_provider` | `TEXT` | NOT NULL DEFAULT `''` | 模型提供方 |
|
||
| `provider_name` | `TEXT` | NOT NULL DEFAULT `''` | Provider 名称 |
|
||
| `provider_base_url` | `TEXT` | NOT NULL DEFAULT `''` | Provider Base URL |
|
||
| `provider_wire_api` | `TEXT` | NOT NULL DEFAULT `''` | Provider Wire API |
|
||
| `reasoning_effort` | `TEXT` | NOT NULL DEFAULT `''` | 默认 reasoning 等级 |
|
||
| `plan_model` | `TEXT` | NOT NULL DEFAULT `''` | 规划阶段专用模型 |
|
||
| `plan_reasoning_effort` | `TEXT` | NOT NULL DEFAULT `''` | 规划阶段 reasoning |
|
||
| `disable_response_storage` | `INTEGER` | NOT NULL DEFAULT `0` | 是否关闭响应持久化 |
|
||
| `shell_env_inherit` | `TEXT` | NOT NULL DEFAULT `core` | 继承环境变量策略 |
|
||
| `shell_env_overrides_json` | `TEXT` | NOT NULL DEFAULT `{}` | 环境变量覆盖项 |
|
||
| `extra_config_json` | `TEXT` | NOT NULL DEFAULT `{}` | 其他扩展配置 |
|
||
| `version` | `INTEGER` | NOT NULL | 当前版本号 |
|
||
| `updated_by` | `TEXT` | NOT NULL DEFAULT `''` | 修改人或修改来源 |
|
||
| `created_at` | `TEXT` | NOT NULL | 创建时间 |
|
||
| `updated_at` | `TEXT` | NOT NULL | 更新时间 |
|
||
|
||
唯一约束:
|
||
|
||
- 全局:每个 `role_name` 只能有 1 条全局默认配置
|
||
- 工作区:每个 `(role_name, workspace_id)` 只能有 1 条 override 配置
|
||
|
||
关系:
|
||
|
||
- `role_configs N -> 1 roles`
|
||
- `role_configs N -> 1 workspaces`(可空)
|
||
|
||
### 5.7 `skills`
|
||
|
||
技能定义表。运行时真正使用数据库中的技能内容。
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `id` | `TEXT` | PK | 技能 ID |
|
||
| `skill_key` | `TEXT` | NOT NULL, UNIQUE | 稳定标识 |
|
||
| `name` | `TEXT` | NOT NULL | 展示名称 |
|
||
| `description` | `TEXT` | NOT NULL DEFAULT `''` | 技能说明 |
|
||
| `source_type` | `TEXT` | NOT NULL | `builtin / imported / custom` |
|
||
| `content_markdown` | `TEXT` | NOT NULL DEFAULT `''` | 技能正文内容 |
|
||
| `status` | `TEXT` | NOT NULL | `active / disabled / archived` |
|
||
| `version` | `INTEGER` | NOT NULL | 当前版本号 |
|
||
| `created_at` | `TEXT` | NOT NULL | 创建时间 |
|
||
| `updated_at` | `TEXT` | NOT NULL | 更新时间 |
|
||
|
||
关系:
|
||
|
||
- `skills 1 -> N role_skill_bindings`
|
||
|
||
### 5.8 `role_skill_bindings`
|
||
|
||
角色与技能的绑定表。
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `id` | `TEXT` | PK | 绑定记录 ID |
|
||
| `role_name` | `TEXT` | FK -> `roles.name` | 角色 |
|
||
| `workspace_id` | `TEXT` | FK -> `workspaces.id`, NULLABLE | 为空表示全局默认;非空表示 workspace override |
|
||
| `skill_id` | `TEXT` | FK -> `skills.id` | 技能 |
|
||
| `is_enabled` | `INTEGER` | NOT NULL | 1 启用,0 禁用 |
|
||
| `sort_order` | `INTEGER` | NOT NULL DEFAULT `0` | 排序 |
|
||
| `config_json` | `TEXT` | NOT NULL DEFAULT `{}` | 绑定级配置 |
|
||
| `version` | `INTEGER` | NOT NULL | 当前版本号 |
|
||
| `updated_by` | `TEXT` | NOT NULL DEFAULT `''` | 修改人或修改来源 |
|
||
| `created_at` | `TEXT` | NOT NULL | 创建时间 |
|
||
| `updated_at` | `TEXT` | NOT NULL | 更新时间 |
|
||
|
||
唯一约束:
|
||
|
||
- 全局:每个 `(role_name, skill_id)` 只能有 1 条全局默认绑定
|
||
- 工作区:每个 `(role_name, workspace_id, skill_id)` 只能有 1 条 override 绑定
|
||
|
||
关系:
|
||
|
||
- `role_skill_bindings N -> 1 roles`
|
||
- `role_skill_bindings N -> 1 skills`
|
||
- `role_skill_bindings N -> 1 workspaces`(可空)
|
||
|
||
### 5.10 `topics`
|
||
|
||
这是第二版的主实体表。
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `id` | `TEXT` | PK | topic ID |
|
||
| `workspace_id` | `TEXT` | FK -> `workspaces.id` | 所属工作区 |
|
||
| `slug` | `TEXT` | NOT NULL | 稳定标识 |
|
||
| `title` | `TEXT` | NOT NULL | 标题 |
|
||
| `space` | `TEXT` | NOT NULL | `discovery / clarify / pool / workflow` |
|
||
| `status` | `TEXT` | NOT NULL | 当前状态 |
|
||
| `source_topic_id` | `TEXT` | FK -> `topics.id`, NULLABLE | 来源 topic |
|
||
| `owner_role_name` | `TEXT` | FK -> `roles.name`, NULLABLE | 当前主责角色 |
|
||
| `summary` | `TEXT` | NOT NULL DEFAULT `''` | 摘要 |
|
||
| `meta_json` | `TEXT` | NOT NULL DEFAULT `{}` | 扩展元数据 |
|
||
| `created_at` | `TEXT` | NOT NULL | 创建时间 |
|
||
| `updated_at` | `TEXT` | NOT NULL | 更新时间 |
|
||
| `closed_at` | `TEXT` | NULLABLE | 关闭时间 |
|
||
|
||
唯一约束:
|
||
|
||
- 每个 workspace 下 `slug` 唯一
|
||
|
||
关系:
|
||
|
||
- `topics N -> 1 workspaces`
|
||
- `topics N -> 1 topics`(`source_topic_id`)
|
||
- `topics N -> 1 roles`(`owner_role_name`)
|
||
- `topics 1 -> N topic_documents`
|
||
- `topics 1 -> N messages`
|
||
- `topics 1 -> N requirements`
|
||
- `topics 1 -> N discovery_rounds`
|
||
- `topics 1 -> N workflow_runs`
|
||
- `topics 1 -> N merge_requests`
|
||
|
||
### 5.11 `topic_documents`
|
||
|
||
topic 持有的正式文档。
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `id` | `TEXT` | PK | 文档 ID |
|
||
| `topic_id` | `TEXT` | FK -> `topics.id` | 所属 topic |
|
||
| `kind` | `TEXT` | NOT NULL | `prd / decision_log / discovery_request / discovery_result` |
|
||
| `content_markdown` | `TEXT` | NOT NULL | Markdown 正文 |
|
||
| `version` | `INTEGER` | NOT NULL | 版本号 |
|
||
| `updated_by_role_name` | `TEXT` | FK -> `roles.name`, NULLABLE | 最后更新角色 |
|
||
| `created_at` | `TEXT` | NOT NULL | 创建时间 |
|
||
| `updated_at` | `TEXT` | NOT NULL | 更新时间 |
|
||
|
||
唯一约束:
|
||
|
||
- 每个 topic 下每种 `kind` 只能有 1 条当前文档
|
||
|
||
说明:
|
||
|
||
- `PRD` 与 `Decision Log` 在 `v2` 中归 `product` 所有
|
||
|
||
### 5.12 `messages`
|
||
|
||
消息主表。
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `id` | `TEXT` | PK | 消息 ID |
|
||
| `workspace_id` | `TEXT` | FK -> `workspaces.id` | 所属工作区 |
|
||
| `topic_id` | `TEXT` | FK -> `topics.id` | 所属 topic |
|
||
| `from_role_name` | `TEXT` | FK -> `roles.name` | 发送角色 |
|
||
| `to_expr` | `TEXT` | NOT NULL | 原始收件表达式,例如 `backend`、`all` |
|
||
| `type` | `TEXT` | NOT NULL | `chat / proposal / question / decision / summary` |
|
||
| `stage` | `TEXT` | NOT NULL | `clarification / plan / review / freeze / execution / verification / discovery` |
|
||
| `round` | `INTEGER` | NULLABLE | 回合号 |
|
||
| `reply_to_message_id` | `TEXT` | FK -> `messages.id`, NULLABLE | 回复目标消息 |
|
||
| `body_markdown` | `TEXT` | NOT NULL | 消息正文 |
|
||
| `created_at` | `TEXT` | NOT NULL | 创建时间 |
|
||
|
||
关系:
|
||
|
||
- `messages N -> 1 workspaces`
|
||
- `messages N -> 1 topics`
|
||
- `messages N -> 1 roles`
|
||
- `messages N -> 1 messages`(`reply_to_message_id`)
|
||
- `messages 1 -> N message_deliveries`
|
||
|
||
### 5.13 `message_deliveries`
|
||
|
||
每个实际收件人的投递状态。
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `message_id` | `TEXT` | FK -> `messages.id` | 对应消息 |
|
||
| `recipient_role_name` | `TEXT` | FK -> `roles.name` | 实际收件角色 |
|
||
| `state` | `TEXT` | NOT NULL | `pending / received / read / archived` |
|
||
| `delivered_at` | `TEXT` | NOT NULL | 投递时间 |
|
||
| `read_at` | `TEXT` | NULLABLE | 已读时间 |
|
||
| `archived_at` | `TEXT` | NULLABLE | 归档时间 |
|
||
| `updated_at` | `TEXT` | NOT NULL | 更新时间 |
|
||
|
||
主键:
|
||
|
||
- `PRIMARY KEY (message_id, recipient_role_name)`
|
||
|
||
说明:
|
||
|
||
- `to: all` 会在这里展开成多条记录
|
||
|
||
|
||
- 它只表达“线程绑定”
|
||
- 不表达“这次执行的历史”
|
||
|
||
### 5.15 `requirements`
|
||
|
||
pool 阶段的结构化队列项。
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `id` | `TEXT` | PK | requirement ID |
|
||
| `workspace_id` | `TEXT` | FK -> `workspaces.id` | 所属工作区 |
|
||
| `topic_id` | `TEXT` | FK -> `topics.id` | 来源 topic |
|
||
| `title` | `TEXT` | NOT NULL | 标题 |
|
||
| `body_markdown` | `TEXT` | NOT NULL | 详细说明 |
|
||
| `status` | `TEXT` | NOT NULL | `pending / dispatched / completed / archived` |
|
||
| `priority` | `INTEGER` | NOT NULL | 优先级 |
|
||
| `created_by_role_name` | `TEXT` | FK -> `roles.name` | 创建角色,通常是 `product` |
|
||
| `created_at` | `TEXT` | NOT NULL | 创建时间 |
|
||
| `updated_at` | `TEXT` | NOT NULL | 更新时间 |
|
||
| `completed_at` | `TEXT` | NULLABLE | 完成时间 |
|
||
|
||
说明:
|
||
|
||
- `requirements` 以 `workspace + topic` 为来源
|
||
- 不再把 `project_id` 当成 requirement 的主归属
|
||
|
||
### 5.16 `discovery_rounds`
|
||
|
||
discovery 轮次主表。
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `id` | `TEXT` | PK | round ID |
|
||
| `workspace_id` | `TEXT` | FK -> `workspaces.id` | 所属工作区 |
|
||
| `topic_id` | `TEXT` | FK -> `topics.id` | 关联 topic |
|
||
| `phase` | `TEXT` | NOT NULL | `collecting / voting / completed / cancelled` |
|
||
| `request_document_id` | `TEXT` | FK -> `topic_documents.id`, NULLABLE | discovery request 文档 |
|
||
| `result_document_id` | `TEXT` | FK -> `topic_documents.id`, NULLABLE | discovery result 文档 |
|
||
| `started_at` | `TEXT` | NOT NULL | 开始时间 |
|
||
| `completed_at` | `TEXT` | NULLABLE | 完成时间 |
|
||
| `updated_at` | `TEXT` | NOT NULL | 更新时间 |
|
||
|
||
关系:
|
||
|
||
- `discovery_rounds N -> 1 workspaces`
|
||
- `discovery_rounds N -> 1 topics`
|
||
- `discovery_rounds 1 -> N discovery_candidates`
|
||
|
||
### 5.17 `discovery_candidates`
|
||
|
||
discovery 候选项结构化表。
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `id` | `TEXT` | PK | candidate ID |
|
||
| `round_id` | `TEXT` | FK -> `discovery_rounds.id` | 所属 round |
|
||
| `proposer_role_name` | `TEXT` | FK -> `roles.name` | 提出角色 |
|
||
| `status` | `TEXT` | NOT NULL | `draft / ready / accepted / rejected / archived` |
|
||
| `title` | `TEXT` | NOT NULL | 候选标题 |
|
||
| `problem` | `TEXT` | NOT NULL DEFAULT `''` | 问题描述 |
|
||
| `evidence` | `TEXT` | NOT NULL DEFAULT `''` | 证据 |
|
||
| `proposal` | `TEXT` | NOT NULL DEFAULT `''` | 提案内容 |
|
||
| `expected_impact` | `TEXT` | NOT NULL DEFAULT `''` | 预期收益 |
|
||
| `risk` | `TEXT` | NOT NULL DEFAULT `''` | 风险 |
|
||
| `how_to_verify` | `TEXT` | NOT NULL DEFAULT `''` | 验证方式 |
|
||
| `created_at` | `TEXT` | NOT NULL | 创建时间 |
|
||
| `updated_at` | `TEXT` | NOT NULL | 更新时间 |
|
||
|
||
关系:
|
||
|
||
- `discovery_candidates N -> 1 discovery_rounds`
|
||
- `discovery_candidates N -> 1 roles`
|
||
- `discovery_candidates 1 -> N discovery_votes`
|
||
|
||
### 5.18 `discovery_votes`
|
||
|
||
discovery 候选项投票表。
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `id` | `TEXT` | PK | vote ID |
|
||
| `round_id` | `TEXT` | FK -> `discovery_rounds.id` | 所属 round |
|
||
| `candidate_id` | `TEXT` | FK -> `discovery_candidates.id` | 所投候选项 |
|
||
| `voter_role_name` | `TEXT` | FK -> `roles.name` | 投票角色 |
|
||
| `vote` | `TEXT` | NOT NULL | `agree / reject / unclear` |
|
||
| `reason` | `TEXT` | NOT NULL DEFAULT `''` | 原因 |
|
||
| `created_at` | `TEXT` | NOT NULL | 创建时间 |
|
||
|
||
唯一约束:
|
||
|
||
- 每个角色对每个候选项最多投 1 票
|
||
|
||
### 5.19 `workflow_runs`
|
||
|
||
执行阶段主表。
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `id` | `TEXT` | PK | run ID |
|
||
| `workspace_id` | `TEXT` | FK -> `workspaces.id` | 所属工作区 |
|
||
| `topic_id` | `TEXT` | FK -> `topics.id` | 所属 topic |
|
||
| `role_name` | `TEXT` | FK -> `roles.name` | 执行角色 |
|
||
| `stage` | `TEXT` | NOT NULL | `plan / review / execution / verification` |
|
||
| `mode` | `TEXT` | NOT NULL DEFAULT `''` | 运行模式 |
|
||
| `status` | `TEXT` | NOT NULL | `running / succeeded / failed / cancelled` |
|
||
| `request_message_id` | `TEXT` | FK -> `messages.id`, NULLABLE | 触发消息 |
|
||
| `config_snapshot_json` | `TEXT` | NOT NULL DEFAULT `{}` | 启动时解析出的 prompt/config/skills 快照 |
|
||
| `command_json` | `TEXT` | NOT NULL DEFAULT `[]` | 执行命令快照 |
|
||
| `reply_message_id` | `TEXT` | FK -> `messages.id`, NULLABLE | 执行完成后的回复消息 |
|
||
| `exit_code` | `INTEGER` | NOT NULL DEFAULT `0` | 退出码 |
|
||
| `started_at` | `TEXT` | NOT NULL | 开始时间 |
|
||
| `completed_at` | `TEXT` | NULLABLE | 完成时间 |
|
||
| `error_message` | `TEXT` | NOT NULL DEFAULT `''` | 错误信息 |
|
||
|
||
说明:
|
||
|
||
- 新的 run 启动时必须把解析后的角色配置快照写入 `config_snapshot_json`
|
||
- 这样后续即使 prompt/config 被改动,历史 run 仍然可追溯
|
||
|
||
### 5.20 `workflow_run_logs`
|
||
|
||
执行日志流。
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `run_id` | `TEXT` | FK -> `workflow_runs.id` | 所属 run |
|
||
| `seq` | `INTEGER` | NOT NULL | 行序号 |
|
||
| `stream` | `TEXT` | NOT NULL | `stdout / stderr / system` |
|
||
| `content` | `TEXT` | NOT NULL | 日志内容 |
|
||
| `created_at` | `TEXT` | NOT NULL | 创建时间 |
|
||
|
||
主键:
|
||
|
||
- `PRIMARY KEY (run_id, seq)`
|
||
|
||
关系:
|
||
|
||
- `workflow_run_logs N -> 1 workflow_runs`
|
||
|
||
### 5.21 `merge_requests`
|
||
|
||
merge 请求记录。
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `id` | `TEXT` | PK | merge request ID |
|
||
| `workspace_id` | `TEXT` | FK -> `workspaces.id` | 所属工作区 |
|
||
| `topic_id` | `TEXT` | FK -> `topics.id` | 所属 topic |
|
||
| `workflow_run_id` | `TEXT` | FK -> `workflow_runs.id`, NULLABLE | 来源执行记录 |
|
||
| `requested_by_role_name` | `TEXT` | FK -> `roles.name`, NULLABLE | 发起角色 |
|
||
| `target_branch` | `TEXT` | NOT NULL | 目标分支 |
|
||
| `status` | `TEXT` | NOT NULL | `pending / merged / failed / cancelled` |
|
||
| `summary` | `TEXT` | NOT NULL DEFAULT `''` | 摘要 |
|
||
| `files_changed` | `INTEGER` | NOT NULL DEFAULT `0` | 改动文件数 |
|
||
| `insertions` | `INTEGER` | NOT NULL DEFAULT `0` | 新增行数 |
|
||
| `deletions` | `INTEGER` | NOT NULL DEFAULT `0` | 删除行数 |
|
||
| `changed_files_json` | `TEXT` | NOT NULL DEFAULT `[]` | 改动文件列表 |
|
||
| `created_at` | `TEXT` | NOT NULL | 创建时间 |
|
||
| `merged_at` | `TEXT` | NULLABLE | 合并时间 |
|
||
| `error_message` | `TEXT` | NOT NULL DEFAULT `''` | 失败原因 |
|
||
|
||
关系:
|
||
|
||
- `merge_requests N -> 1 workspaces`
|
||
- `merge_requests N -> 1 topics`
|
||
- `merge_requests N -> 1 workflow_runs`
|
||
- `merge_requests N -> 1 roles`
|
||
|
||
## 6. 表关系图
|
||
|
||
```mermaid
|
||
erDiagram
|
||
PROJECTS ||--o{ WORKSPACES : has
|
||
WORKSPACES ||--o{ TOPICS : owns
|
||
WORKSPACES ||--o{ MESSAGES : owns
|
||
WORKSPACES ||--o{ REQUIREMENTS : owns
|
||
WORKSPACES ||--o{ DISCOVERY_ROUNDS : owns
|
||
WORKSPACES ||--o{ WORKFLOW_RUNS : owns
|
||
WORKSPACES ||--o{ MERGE_REQUESTS : owns
|
||
|
||
ROLES ||--o{ ROLE_PROMPTS : has
|
||
ROLES ||--o{ ROLE_CONFIGS : has
|
||
ROLES ||--o{ ROLE_SKILL_BINDINGS : binds
|
||
SKILLS ||--o{ ROLE_SKILL_BINDINGS : used_by
|
||
|
||
TOPICS ||--o{ TOPIC_DOCUMENTS : has
|
||
TOPICS ||--o{ MESSAGES : contains
|
||
TOPICS ||--o{ REQUIREMENTS : produces
|
||
TOPICS ||--o{ DISCOVERY_ROUNDS : drives
|
||
TOPICS ||--o{ WORKFLOW_RUNS : executes
|
||
TOPICS ||--o{ MERGE_REQUESTS : results_in
|
||
|
||
MESSAGES ||--o{ MESSAGE_DELIVERIES : fans_out
|
||
MESSAGES ||--o{ MESSAGES : replies_to
|
||
|
||
DISCOVERY_ROUNDS ||--o{ DISCOVERY_CANDIDATES : includes
|
||
DISCOVERY_CANDIDATES ||--o{ DISCOVERY_VOTES : receives
|
||
|
||
WORKFLOW_RUNS ||--o{ WORKFLOW_RUN_LOGS : emits
|
||
WORKFLOW_RUNS ||--o| MERGE_REQUESTS : may_create
|
||
```
|
||
|
||
## 7. 关系说明
|
||
|
||
### 7.1 配置关系
|
||
|
||
| 主表 | 从表 | 关系 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `roles` | `role_prompts` | 1:N | 一个角色可有多种 prompt kind,也可有 workspace override |
|
||
| `roles` | `role_configs` | 1:N | 一个角色可有全局配置和多个 workspace override |
|
||
| `roles` | `role_skill_bindings` | 1:N | 一个角色可绑定多个技能 |
|
||
| `skills` | `role_skill_bindings` | 1:N | 一个技能可被多个角色使用 |
|
||
| `workspaces` | `role_prompts / role_configs / role_skill_bindings` | 1:N | workspace 级覆盖配置 |
|
||
|
||
### 7.2 业务关系
|
||
|
||
| 主表 | 从表 | 关系 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `projects` | `workspaces` | 1:N | 一个项目下有多个工作区 |
|
||
| `workspaces` | `topics` | 1:N | 一个工作区下有多个 topic |
|
||
| `topics` | `topic_documents` | 1:N | 一个 topic 下有多种文档 |
|
||
| `topics` | `messages` | 1:N | 一个 topic 下有多条消息 |
|
||
| `messages` | `message_deliveries` | 1:N | 一条消息可投递给多个角色 |
|
||
| `topics` | `requirements` | 1:N | 一个 topic 可产生多个 requirement |
|
||
| `topics` | `discovery_rounds` | 1:N | 一个 topic 可有多轮 discovery |
|
||
| `discovery_rounds` | `discovery_candidates` | 1:N | 一轮 discovery 可有多个候选项 |
|
||
| `discovery_candidates` | `discovery_votes` | 1:N | 一个候选项可收到多个角色投票 |
|
||
| `topics` | `workflow_runs` | 1:N | 一个 topic 可有多次执行 |
|
||
| `workflow_runs` | `workflow_run_logs` | 1:N | 一次执行有多条日志 |
|
||
| `topics` | `merge_requests` | 1:N | 一个 topic 可产生多个 merge 请求 |
|
||
|
||
### 7.3 特殊关系
|
||
|
||
| 字段 | 关系 | 说明 |
|
||
| --- | --- | --- |
|
||
| `topics.source_topic_id` | 自关联 | topic 可从另一个 topic 派生 |
|
||
| `messages.reply_to_message_id` | 自关联 | 消息可回复另一条消息 |
|
||
| `discovery_rounds.request_document_id` | 指向 `topic_documents` | discovery 输入文档 |
|
||
| `discovery_rounds.result_document_id` | 指向 `topic_documents` | discovery 输出文档 |
|
||
| `workflow_runs.config_snapshot_json` | 快照,不是 FK | 保存运行时解析后的配置结果 |
|
||
|
||
## 8. 读取优先级
|
||
|
||
以下三张配置表都采用相同规则:
|
||
|
||
- `role_prompts`
|
||
- `role_configs`
|
||
- `role_skill_bindings`
|
||
|
||
读取顺序固定为:
|
||
|
||
1. 先查当前 `workspace_id` 的覆盖记录
|
||
2. 如果没有,再查全局默认记录
|
||
|
||
这个规则是 `v2` 的硬约束,服务端、测试和前端都按这套理解实现。
|
||
|
||
## 9. 写入规则
|
||
|
||
### 9.1 配置写入
|
||
|
||
当用户在前端修改:
|
||
|
||
- 角色
|
||
- 提示词
|
||
- 技能
|
||
- 角色配置
|
||
- 技能绑定
|
||
|
||
服务端必须同时做两件事:
|
||
|
||
1. 更新当前生效表
|
||
|
||
### 9.2 新执行启动
|
||
|
||
当新的 `workflow_runs` 启动时:
|
||
|
||
1. 解析角色最终生效配置
|
||
- prompt
|
||
- role config
|
||
- skill binding
|
||
- skill 内容
|
||
2. 将解析结果写入 `workflow_runs.config_snapshot_json`
|
||
3. 再启动实际执行
|
||
|
||
这样可以同时满足:
|
||
|
||
- 配置立即生效
|
||
- 历史执行可追溯
|
||
|
||
## 10. V2 明确不保留的旧表
|
||
|
||
| 旧表 | V2 处理 |
|
||
| --- | --- |
|
||
| `topic_records` | 删除,合并进 `topics` |
|
||
| `clarifier_state` | 删除,状态回归 `topics` |
|
||
| `clarifier_artifacts` | 删除,合并进 `topic_documents` |
|
||
| `message_mailboxes` | 改为 `message_deliveries` |
|
||
| `dispatches` | 改为 `workflow_runs` |
|
||
| `dispatch_live_lines` | 改为 `workflow_run_logs` |
|
||
| `discovery_round_proposals` | 删除,改为 `discovery_candidates` |
|
||
| `discovery_round_votes` JSON blob | 删除,改为结构化 `discovery_votes` |
|
||
|
||
## 11. 对开发的直接约束
|
||
|
||
这份文档对 `v2` 开发有三条直接约束:
|
||
|
||
1. 不允许再出现“同一业务对象散落多个旧表”的设计。
|
||
2. 不允许再把在线可编辑配置只放文件、不进数据库。
|
||
3. 不允许再把 discovery 和 workflow 的核心结构塞回 JSON blob。
|
||
|
||
这份文档就是 `inbox v2` 的数据库基线,后续如果要改,应该直接更新这份文档,而不是各模块各自理解一版。
|
||
|
||
## 当前工作流图扩展
|
||
|
||
当前运行时已经在 `chains` / `tasks` / `workflow_runs` 上扩展了 leader-managed graph 字段,作为后续 DAG planning 的基础。
|
||
|
||
### chains
|
||
|
||
除基础标识与运行态字段外,`chains` 当前还包含:
|
||
|
||
- `purpose`:这条 chain 的目标与职责摘要
|
||
|
||
### tasks
|
||
|
||
除基础标题、正文、状态、依赖字段外,`tasks` 当前还包含:
|
||
|
||
- `task_kind`
|
||
- `execution`
|
||
- `gate`
|
||
- `verification`
|
||
- `milestone`
|
||
- `gate_policy`
|
||
- `none`
|
||
- `hard_stop`
|
||
- `ask_user`
|
||
- `leader_replan`
|
||
- `deliverables_json`
|
||
- `verification_mode`
|
||
- `none`
|
||
- `auto`
|
||
- `human`
|
||
- `batch_key`
|
||
- `replan_policy`
|
||
- `patch`
|
||
- `clarify`
|
||
- `stop`
|
||
|
||
说明:
|
||
|
||
- `task_kind = milestone` 是当前 milestone 的落地方式,不单独建表。
|
||
- `gate` task 用于前置检查;存在 gate 时,其它 task 默认先不放行。
|
||
|
||
### workflow_runs
|
||
|
||
`leader` 的结构化 planning 结果当前会持久化到:
|
||
|
||
- `workflow_runs.command_json`
|
||
|
||
其中包含:
|
||
|
||
- `plan_version`
|
||
- `plan_mode`
|
||
- `replan_reason`
|
||
- `supersedes`
|
||
- `execution_mode`
|
||
- `leader_reply`
|
||
- `chains`
|
||
- `tasks`
|
||
- `start_nodes`
|
||
|
||
说明:
|
||
|
||
- 空图首次规划使用 `plan_mode = initial`
|
||
- 主题已有 graph 时,leader 必须使用 `plan_mode = patch`
|
||
- 当前系统不允许 patch 模式扩图;patch 只能复用现有 graph
|