refactor(data): 收口关系表运行时数据源
Some checks failed
Deploy Production / Build, push, deploy, verify (push) Has been cancelled

- 移除已迁移业务 AppData 运行时 fallback,改走领域 API 和关系表快读
- 补齐需求产品负责人、版本计划任务 JSON 和成员 username 回填迁移
- 统一治理字典入口,并补充 AI provider、数据源契约和领域服务测试

Co-Authored-By: Codex GPT-5 <codex@openai.com>
This commit is contained in:
2026-07-09 14:59:49 +08:00
parent 1e6fb0c7aa
commit 2e595c7e72
98 changed files with 2938 additions and 1441 deletions

View File

@@ -72,7 +72,7 @@
- [ ] 是否需要在 `workspace-engine.ts` 加聚合?
- [ ] 删除版本时是否需要清理这类数据?
- [ ] 工作台 / 版本详情 / 项目详情三处的统计是否同步?
- [ ] 是否需要新增 `app_data` key后端 `data-keys.ts` + 前端 `server-data.ts`
- [ ] 是否需要新增关系表、Prisma model、领域 API、权限和审计
- [ ] 是否需要从旧浏览器数据做一次性迁移?(当前不做本地导入导出)
## Drawer侧边详情规范
@@ -131,9 +131,9 @@
朋友拉新代码出现"显示问题"时,按顺序排查:
1. 后端是否启动:`GET http://localhost:3001/api/v1/config/ai` 应返回 200
2. 数据库是否启动并完成 Prisma 同步:`app_data` 表必须存在
3. 对应 `app_data.key` 是否有,例如 `products-overview` / `requirements` / `dev-tasks`
4. 前端 store 是否已经调用对应 `fetch*` 方法
2. 数据库是否启动并完成 Prisma migration领域关系表必须存在
3. 对应领域 API 是否有数据,例如 `/api/v1/products``/api/v1/v2.2/workspace``/api/v1/versions/:versionId/plans`
4. 前端 store 是否已经调用对应 `fetch*` 方法,且是否传了正确的 `productId` / `versionId`
5. 类型定义和实际 JSON 数据不一致(缺字段)
6. 列宽溢出导致裁切
7. 派生计算错误filter 条件错)
@@ -147,10 +147,12 @@
- 涉及 UI 改动:`curl http://localhost:3000/<path>` 检查 200
- 不会自动跑 dev server假定它已经运行
## AppData 并发写入流程
## AppData 归档/配置写入流程
- 前端通过 `loadServerData(key)` 读取业务文档时,必须缓存响应里的 `version`
- 前端通过 `saveServerData(key, value)` 保存已读取过的 key 时,必须把最近一次成功读取/保存得到的 `version` 一起提交
- 正常业务 store 不再通过 `loadServerData(key)` / `saveServerData(key, value)` 读取或保存已迁移业务文档
- 仅允许低频配置例外使用 AppData成员配置中的部门/角色/密码规则、加班原因。小宝历史缓存/已读状态只保留迁移与归档读取价值,正常页面运行时不得读写这些 AppData key
- 前端通过 `loadServerData(key)` 读取配置文档时,必须缓存响应里的 `version`
- 前端通过 `saveServerData(key, value)` 保存已读取过的配置 key 时,必须把最近一次成功读取/保存得到的 `version` 一起提交。
- 后端只在 `key + updatedAt(version)` 匹配时更新;如果其他用户已经先保存,返回 `409 APP_DATA_CONFLICT`,响应包含当前服务端 `currentVersion``currentValue`
- 收到 `ServerDataConflictError` 时,不要自动重试覆盖。当前处理策略是阻止静默覆盖,后续 UI 冲突合并能力再单独补。
@@ -159,14 +161,14 @@
已迁移领域的 store 默认写入顺序:
1. 本地状态先做乐观更新,保持 UI 响应速度。
2. 优先调用 `apps/web/lib/domain-api.ts` 中的领域 API。
2. 调用 `apps/web/lib/domain-api.ts` 中的领域 API。
3. 领域 API 成功后,用服务端返回行替换本地临时行;若返回 `activities`,直接合并工作活动证据。
4. 领域 API 不可用或旧环境未部署时,才使用 `loadServerData` / `saveServerData` AppData 兼容兜底。
5. 不新增长期双写逻辑;AppData fallback 只用于兼容、迁移和回滚,不作为已迁移领域的事实源。
4. 领域 API 不可用时回滚乐观更新并提示 API/网络错误,不再写 AppData 兼容兜底。
5. 不新增双写逻辑;迁移、归档、回滚工具可以读历史 AppData但正常业务 UI 不把它当事实源。
当前领域主写范围:
- Product / Project / Version根数据主写`products-overview` 仅兼容
- Product / Project / Version根数据主写正常运行时不读 `products-overview`
- Requirement`productId` 写入,需求池列表走服务端分页、搜索、筛选、排序。
- VersionPlan / DevTask / TestCase / Bug`versionId` 写入,并维护工作活动和小宝 dirty 标记。
- Member / TaskCategory成员身份字段和任务类型字典主写关系表。
@@ -177,7 +179,7 @@
- 部门、角色、密码规则。
- 加班原因。
新增领域 store 时,先写 source contract 测试证明主写不是 `saveServerData('<key>')`,再实现领域 API 和 fallback
新增领域 store 时,先写 source contract 测试证明运行时不调用 `loadServerData('<key>')` / `saveServerData('<key>')`,再实现领域 API。
## V2.5 权限、审计与 AppData 退场流程
@@ -193,7 +195,7 @@ AppData key 退场遵循:
1. 所有业务 key 先在 `AppDataRetirementService` 标注状态和替代路径。
2. `write_frozen` / `read_only_archive` key 的写入返回 `409 APP_DATA_WRITE_FROZEN`;前端捕获 `ServerDataWriteFrozenError` 后提示改用领域 API。
3. 读取仍可用,只用于历史数据核对、兼容导入、归档导出和故障排查。
3. 读取仍可用,只用于历史数据核对、兼容导入、归档导出和故障排查;正常业务 UI 不应把读取结果当 fallback 数据源
4. 导出归档使用 `pnpm appdata:archive:export`,归档校验使用 `pnpm appdata:archive:verify -- --archive <file>`
5. 不新增 AppData key 作为主写新业务先设计关系表、Prisma model、领域 API、权限和审计。
@@ -206,8 +208,8 @@ AppData key 退场遵循:
跨阶段协调点:
- `xiaobao-risk-snapshots` / `xiaobao-risk-insights` 已进入只读归档V2.6 负责关系表写入、后台任务和重试
- `xiaobao-warning-views` 已进入只读归档;V2.7 负责 per-user read-state API。
- `xiaobao-risk-snapshots` / `xiaobao-risk-insights` 已进入只读归档;正常前端运行时不再读取或写入这些 AppData keyV2.6 关系表后台任务负责 summary/insight
- `xiaobao-warning-views` 已进入只读归档;正常前端运行时不再写该 AppData key当前页面已读状态仅作为浏览器本地 UI 状态,后续由 per-user read-state API 承接
- 成员身份写 `users`,但部门、角色、密码规则和加班原因的正式配置 schema 仍属 V2.7 管理治理。
## 与我相关Workspace数据流
@@ -350,9 +352,9 @@ Implementation convention:
- `xiaobao.warning:manage`:查看所有未结束版本的预警。
- `xiaobao.warning:view`:仅查看当前用户在 `version.members` 中的未结束版本。
V2.6/V3.2 后小宝当前 summary 由服务端后台刷新:领域写入标记 `xiaobao_risk_summaries.dirty=true` 并排入 `xiaobao.summary.refresh`worker 从版本下的计划、开发任务、测试用例、Bug、日报和工作活动重新计算风险。页面仍可用前端 `buildXiaobaoWorkItems` 做兼容聚合和快照保存,但默认优先读取 V2.2 summary。
V2.6/V3.2 后小宝当前 summary 由服务端后台刷新:领域写入标记 `xiaobao_risk_summaries.dirty=true` 并排入 `xiaobao.summary.refresh`worker 从版本下的计划、开发任务、测试用例、Bug、日报和工作活动重新计算风险。页面仍可用前端 `buildXiaobaoWorkItems` 做兼容聚合,但不再把快照或解读保存到 AppData默认优先读取 V2.2 summary。
AI 解读不由人工按钮触发。服务端 summary 刷新后按 policy 排入 `xiaobao.ai.interpret``at_risk``likely_delayed``blocked` 自动触发;`attention` 当前服务端只在临近发版且仍有未完成工作时触发,页面完整趋势策略仍保留作为兼容。缓存命中时复用解读;同版本最近 6 小时内已有解读时进入 cooldown不重复请求风险等级升级时可绕过缓存保存时间使用服务端写入时间不信任模型返回的 `generatedAt` 作为缓存新鲜度。V2.2 小宝快读会带出当前版本最新 generated 关系表解读,前端优先展示这份解读,再兼容`xiaobao-risk-insights` AppData 缓存。
AI 解读不由人工按钮触发。服务端 summary 刷新后按 policy 排入 `xiaobao.ai.interpret``at_risk``likely_delayed``blocked` 自动触发;`attention` 当前服务端只在临近发版且仍有未完成工作时触发。缓存命中时复用解读;同版本最近 6 小时内已有解读时进入 cooldown不重复请求风险等级升级时可绕过缓存保存时间使用服务端写入时间不信任模型返回的 `generatedAt` 作为缓存新鲜度。V2.2 小宝快读会带出当前版本最新 generated 关系表解读,前端优先展示这份解读,不再回读`xiaobao-risk-insights` AppData 缓存。
静默风险包括长期无更新、无日报、无活动、进行中事项无人处理等信号。日报和工作活动是风险解释的重要证据,必须进入 AI 解读输入。
@@ -362,19 +364,21 @@ AI 解读不由人工按钮触发。服务端 summary 刷新后按 policy 排入
- `assignment`:负责人或处理人被分配工作。
- `mention`:评论中 `@成员名` 或显式选择成员。
- `risk_alert`:小宝预警保存高风险快照后提醒管理者。
- `risk_alert`:小宝风险摘要/高风险事件触发后提醒管理者。
- `overdue_item`:逾期事项提醒。
评论统一使用 `CommentPanel`,支持 DevTask、TestCase、Bug、Requirement 和 VersionPlan。创建/删除评论必须写 audit提及成员必须生成 mention 通知。
项目成员治理走 `/projects/:projectId/members` 服务端接口。角色为 Owner/Admin/Member/ViewerOwner/Admin 可管理成员;服务端禁止移除或降级最后一个 Owner。版本成员可见性继续兼容旧 `version.members` 展示,但治理来源应逐步收敛到 ProjectMember。
管理驾驶舱 `/admin/management` 只查关系表和小宝 summary不读取 AppData并通过 RBAC adapter 校验 `management:view`。治理设置 `/admin/governance` 集中维护任务类型与需求字典;使用中的字典不可硬删,字典变更必须写 audit并通过 RBAC adapter 校验 `governance:manage`
管理驾驶舱 `/admin/management` 只查关系表和小宝 summary不读取 AppData并通过 RBAC adapter 校验 `management:view`。治理设置 `/admin/governance` 统一维护任务类型、需求类型、支持端与需求来源,并由 `governance:manage` 控制。需求池只消费治理字典,不再提供本地类型/来源/支持端管理抽屉AI 分析读取这些字段作为维度,不负责修改字典
## Business Analysis Agent 工作流(规划
## Business Analysis Agent 工作流(第一版已接入
Business Analysis Agent 用于 AI 助手业务数据对话,以及产品/项目/版本详情页的上下文分析入口。它只读关系表和 summary不写业务数据。
业务分析请求走 `POST /api/v1/ai/analysis`。前端必须传入 `surface` 和可用上下文 ID后端基于当前用户、服务端权限和页面上下文再次收窄范围不能只信任前端传入的权限或自然语言意图。
标准流程:
1. 用户在 `/wenfan-xiaobao` 或详情页输入问题。