docs(版本模块): 规则引擎与任务类型设计
This commit is contained in:
212
docs/agent-spec.md
Normal file
212
docs/agent-spec.md
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
# Agent 规范
|
||||||
|
|
||||||
|
本文件是 FTB 系统中所有 AI Agent 的**唯一权威定义**。任何对 agent 的能力、职责、权限、协作方式的修改,必须先在本文件落地,再同步到 architecture / decisions / workflow / roadmap / glossary。
|
||||||
|
|
||||||
|
## 何时更新本文件
|
||||||
|
|
||||||
|
1. **新增 agent**:新建一个独立 agent
|
||||||
|
2. **agent 职责变化**:输入/输出/调用条件变了
|
||||||
|
3. **agent 权限变化**:可读哪些数据、可写哪些数据变了
|
||||||
|
4. **多 agent 协作方式变化**:编排顺序、依赖关系、出错回退策略变了
|
||||||
|
|
||||||
|
不影响以上四类的 prompt 微调、模型版本切换、性能优化不需要更新本文件。
|
||||||
|
|
||||||
|
## 全局原则
|
||||||
|
|
||||||
|
1. **AI 不直接动数据,先生草案,用户确认**
|
||||||
|
- 所有写入实体(DevTask / TestCase)必须带 `aiDraft: true` 标记
|
||||||
|
- 用户编辑保存后,标记自动清除(在 `useDevTaskStore.updateTask` / `useTestCaseStore.updateTestCase` 里实现)
|
||||||
|
|
||||||
|
2. **每条产物强制带引用**
|
||||||
|
- DevTask / TestCase 必须有 `references: Reference[]`,至少 1 条
|
||||||
|
- 引用类型:`requirement` / `prototype_note` / `external`
|
||||||
|
- 不带引用的草案不允许写入
|
||||||
|
|
||||||
|
3. **AI 输出必须有"对账报告"**
|
||||||
|
- 拆解任务前,先输出三段对账:
|
||||||
|
- ✅ 完美对应(需求 ↔ 原型注释 ↔ 任务)
|
||||||
|
- ⚠️ 仅需求未见原型 / 仅原型未见需求
|
||||||
|
- ❓ 注释含糊无法转化
|
||||||
|
- 对账报告先呈现给用户,用户审核后才执行写入
|
||||||
|
|
||||||
|
4. **历史版本不强制存储**
|
||||||
|
- 系统不要求历史原型 URL 作为基准
|
||||||
|
- 拆偏问题靠"对账报告"暴露给用户,由人工补救
|
||||||
|
- 这条决定见 decisions.md #17
|
||||||
|
|
||||||
|
## Agent 列表
|
||||||
|
|
||||||
|
### Agent 1:Prototype Decompose Agent(原型拆解)
|
||||||
|
|
||||||
|
**目的**:把"产品方案原型 + 关联需求"拆解成开发任务草案 + 测试用例草案。
|
||||||
|
|
||||||
|
**输入**:
|
||||||
|
- 当前版本「产品方案」类型 + status=completed 的 VersionPlan,取其 `resultUrl` 作为**原型链接**(约定:产品方案的成果即原型)
|
||||||
|
- 当前版本关联需求列表(已被加进 Version 的 Requirement[])
|
||||||
|
- 版本成员清单(带角色:前端/后端/UI/测试)
|
||||||
|
|
||||||
|
**调用入口**:版本详情页 → 产品方案 Tab → 计划状态 = completed 后,按钮「AI 拆解任务和用例」
|
||||||
|
|
||||||
|
**触发条件**:
|
||||||
|
- 当前版本至少有 1 条 type=product 的 VersionPlan 处于 `completed` 且 resultUrl 非空(提交了原型)
|
||||||
|
- 当前版本至少关联 1 条需求
|
||||||
|
|
||||||
|
**输出**:
|
||||||
|
- 对账报告(结构化文本,含"完美对应/单边/含糊"三段)
|
||||||
|
- DevTask 草案数组(每条带 `aiDraft: true` + `references[]`)
|
||||||
|
- TestCase 草案数组(每条带 `aiDraft: true` + `references[]`)
|
||||||
|
|
||||||
|
**写入**:
|
||||||
|
- 用户确认后,调用 `useDevTaskStore.createTask` 和 `useTestCaseStore.createTestCase`
|
||||||
|
- 写入字段中 `aiDraft: true`、`aiDraftAt: ISO时间戳`
|
||||||
|
|
||||||
|
**权限**:
|
||||||
|
- 读:Version, Requirement, VersionPlan, Member
|
||||||
|
- 写:DevTask(仅 aiDraft 草案)、TestCase(仅 aiDraft 草案)
|
||||||
|
- 不得修改:Requirement、Version、VersionPlan、Member、Bug
|
||||||
|
|
||||||
|
**失败回退**:
|
||||||
|
- 原型 URL 不可达 → 报告"原型无法访问",不写入任何数据
|
||||||
|
- 没有已完成的产品方案计划 → 报告"请先完成产品方案并提交原型成果",不写入
|
||||||
|
- 关联需求为空 → 报告"无关联需求,无法对照",不写入
|
||||||
|
- 对账报告全是 ❓ → 报告"原型注释含糊度过高,建议人工拆解",不写入
|
||||||
|
|
||||||
|
**MVP 阶段限制**(V3.1):
|
||||||
|
- 只生成 DevTask 和 TestCase 草案
|
||||||
|
- 不自动分配 assignee(assignee 留给用户从草案编辑时手填)
|
||||||
|
- 不做"上一版基准 diff"
|
||||||
|
|
||||||
|
### Agent 2:Risk Watch Agent(风险预警)— 待规划
|
||||||
|
|
||||||
|
仅占位,正式规划见 roadmap.md V3.2。
|
||||||
|
|
||||||
|
### Agent 3:Schedule Suggest Agent(排期建议)— 待规划
|
||||||
|
|
||||||
|
仅占位,正式规划见 roadmap.md V3.2。
|
||||||
|
|
||||||
|
## 多 Agent 协作(V3.2 规划)
|
||||||
|
|
||||||
|
当前 V3.1 只有 Prototype Decompose Agent 单独运行。
|
||||||
|
未来 Risk Watch / Schedule Suggest 引入后,编排策略另行设计。
|
||||||
|
|
||||||
|
## 实现位置
|
||||||
|
|
||||||
|
V3.1 起,所有 Agent **走 NestJS 后端**(不走 Next.js API Route),原因:
|
||||||
|
- 与现有 `product` / `requirement` 模块架构一致
|
||||||
|
- 共享 Prisma 实例便于后续 AiLog 持久化
|
||||||
|
- 多 Agent 引入时统一在 `AiGateway` 管理 prompt / 降级 / 重试
|
||||||
|
|
||||||
|
代码位置:
|
||||||
|
```
|
||||||
|
apps/server/src/modules/
|
||||||
|
├── ai/
|
||||||
|
│ ├── ai.module.ts
|
||||||
|
│ ├── ai.controller.ts # POST /api/v1/ai/decompose
|
||||||
|
│ ├── ai.service.ts # 抓原型 + 调 LLM + 解析
|
||||||
|
│ ├── ai-gateway.service.ts # Anthropic 客户端单例(懒加载,key 改了重建)
|
||||||
|
│ ├── prompts/decompose.ts # System Prompt + Tool Schema
|
||||||
|
│ └── dto/decompose.dto.ts # 入参校验
|
||||||
|
└── config/
|
||||||
|
├── config.module.ts
|
||||||
|
├── ai-config.controller.ts # GET/PATCH /api/v1/config/ai, POST /test
|
||||||
|
├── ai-config.service.ts # 读写 data/ai-config.json
|
||||||
|
└── dto/update-ai-config.dto.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
共享类型:`packages/shared/src/agent.ts`(前后端通用)
|
||||||
|
|
||||||
|
## 配置管理
|
||||||
|
|
||||||
|
**多提供商支持(V3.1.5 起)**:系统支持配置任意数量的 AI 提供商,每个独立的 baseURL / apiKey / model,运行时切换激活。
|
||||||
|
|
||||||
|
**支持的 API 格式**:
|
||||||
|
- `anthropic` — Anthropic 官方 + 兼容 Anthropic Messages API 格式的中转站(如 ikuncode 的 anthropic 端点)
|
||||||
|
- `openai` — OpenAI 官方 + 兼容 OpenAI Chat Completions 格式的中转站
|
||||||
|
|
||||||
|
**API Key 优先级**:当前激活提供商的 apiKey → 环境变量 `ANTHROPIC_API_KEY`(兜底,仅 anthropic 格式可用)
|
||||||
|
|
||||||
|
**前端配置入口**:`/admin/ai-config`,仅超管(`role.permissions` 含 `'*'`)可见
|
||||||
|
|
||||||
|
**字段(每个 Provider)**:
|
||||||
|
- `id`:用户自定义唯一 ID(如 `ikuncode`)
|
||||||
|
- `name`:显示名
|
||||||
|
- `format`:`anthropic` / `openai`
|
||||||
|
- `baseURL`:完整 API endpoint
|
||||||
|
- `apiKey`:完整 Key 仅在服务端持有;前端只能拿到 mask 视图
|
||||||
|
- `model`:该提供商上使用的模型 ID
|
||||||
|
- `remark`:可选备注
|
||||||
|
|
||||||
|
**全局字段**:
|
||||||
|
- `activeProviderId`:当前激活哪个 provider
|
||||||
|
- `updatedAt` / `updatedBy`:审计
|
||||||
|
|
||||||
|
**测试连接**:`POST /api/v1/config/ai/test` 带 `{ id }`,用 16 token 极简调用验证目标 provider 可用性
|
||||||
|
|
||||||
|
**激活**:`POST /api/v1/config/ai/activate` 带 `{ id }`,切换激活 provider;AiGateway 缓存自动失效,下次调用重新构建客户端
|
||||||
|
|
||||||
|
**安全约束**:
|
||||||
|
- 配置文件路径在 .gitignore 里(`apps/server/data/`),不进入版本控制
|
||||||
|
- 前端 GET 接口永远不返回完整 Key
|
||||||
|
- 修改 Key 只能从前端 PATCH 上传新值,不支持读出旧值
|
||||||
|
- 编辑提供商时若不传 apiKey,则保留原值
|
||||||
|
|
||||||
|
**数据迁移**:旧版(V3.1)的 `{ anthropicApiKey, model }` 单 key 结构,自动迁移为多 providers 结构(id 为 `anthropic-official`,自动激活)。
|
||||||
|
|
||||||
|
## 数据契约
|
||||||
|
|
||||||
|
### Reference 类型
|
||||||
|
|
||||||
|
```ts
|
||||||
|
interface Reference {
|
||||||
|
type: 'requirement' | 'prototype_note' | 'external';
|
||||||
|
id: string; // REQ-008 / QY0007 / 自由文本
|
||||||
|
label: string; // 展示用
|
||||||
|
url?: string; // 可选跳转链接
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### AI 草案标记
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// DevTask 和 TestCase 共有
|
||||||
|
aiDraft?: boolean;
|
||||||
|
aiDraftAt?: string; // ISO 时间戳
|
||||||
|
references?: Reference[];
|
||||||
|
```
|
||||||
|
|
||||||
|
### Agent 输入预期
|
||||||
|
|
||||||
|
```ts
|
||||||
|
interface DecomposeInput {
|
||||||
|
version: VersionWithContext; // 上下文(不含 prototypeUrl,原型从产品方案成果取)
|
||||||
|
prototypeUrl: string; // 从产品方案 completed 计划的 resultUrl 派生
|
||||||
|
requirements: Requirement[]; // 当前版本所属项目下已采纳、可用于本次拆解的需求
|
||||||
|
members: VersionMember[]; // 该版本参与人员(带角色)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
要求:`requirements` 不能从产品级全量需求池直接取,必须经过项目维度和已采纳状态过滤。
|
||||||
|
|
||||||
|
### Agent 输出预期
|
||||||
|
|
||||||
|
```ts
|
||||||
|
interface DecomposeOutput {
|
||||||
|
report: {
|
||||||
|
matched: Array<{ reqId: string; noteIds: string[]; taskCount: number }>;
|
||||||
|
reqOnly: string[]; // 需求 ID 列表
|
||||||
|
noteOnly: string[]; // 原型注释 ID 列表
|
||||||
|
ambiguous: Array<{ noteId: string; reason: string }>;
|
||||||
|
};
|
||||||
|
devTaskDrafts: Array<Omit<DevTask, 'id' | 'taskNo' | 'createdAt' | 'updatedAt' | 'isBlocked' | 'categoryId'> & { categoryCode: string; aiDraft: true; aiDraftAt: string; references: Reference[] }>;
|
||||||
|
testCaseDrafts: Array<Omit<TestCase, 'id' | 'caseNo' | 'createdAt' | 'updatedAt' | 'status' | 'categoryId'> & { categoryCode: string; aiDraft: true; aiDraftAt: string; references: Reference[] }>;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
要求:AI 不输出数据库 `categoryId`,只输出稳定 `categoryCode`。前端确认写入时按 `TaskCategory.code` 映射成 `categoryId`;映射失败时使用对应分组的默认类型兜底。
|
||||||
|
|
||||||
|
## 视觉规范
|
||||||
|
|
||||||
|
AI 草案在 DevTask / TestCase 列表中的视觉区分:
|
||||||
|
- 整行加 `border-l-2 border-l-purple-400 bg-purple-50/30`
|
||||||
|
- 标题旁紫色徽章「AI 草案」(`bg-purple-100 text-purple-600`)
|
||||||
|
- 用户在详情抽屉里编辑保存任意字段后,徽章和左边线自动消失
|
||||||
@@ -33,8 +33,8 @@ Requirement Version TestCase
|
|||||||
| 前端 | Next.js 14 (App Router) | TypeScript + 客户端组件为主 |
|
| 前端 | Next.js 14 (App Router) | TypeScript + 客户端组件为主 |
|
||||||
| UI | Tailwind CSS + Shadcn/ui | 紧凑信息密度、现代风格 |
|
| UI | Tailwind CSS + Shadcn/ui | 紧凑信息密度、现代风格 |
|
||||||
| 状态 | Zustand | 每个领域一个 store |
|
| 状态 | Zustand | 每个领域一个 store |
|
||||||
| 持久化 | localStorage(V1) | 后端 NestJS + Prisma 已搭好但未启用 |
|
| 持久化 | PostgreSQL AppData(V2.1) | 业务数据走 NestJS `/data/:key`,不再以浏览器存储为主 |
|
||||||
| 后端 | NestJS + Prisma + PostgreSQL(V2) | 暂未启用 |
|
| 后端 | NestJS + Prisma + PostgreSQL(V2) | 已接入通用数据文档层,后续再逐表关系化 |
|
||||||
| AI | Anthropic SDK(V3 远景) | 健康度/风险预警/排期建议 |
|
| AI | Anthropic SDK(V3 远景) | 健康度/风险预警/排期建议 |
|
||||||
|
|
||||||
## 模块结构
|
## 模块结构
|
||||||
@@ -113,17 +113,14 @@ DevTask 没有"已完成"状态,"已提测"就是终态——开发交付完
|
|||||||
|
|
||||||
## 数据持久化
|
## 数据持久化
|
||||||
|
|
||||||
**V1(当前):** 全部 localStorage,每个 store 独立 key
|
**V2.1(当前):** 通用服务端文档表 `app_data`
|
||||||
- `ftb_overview_v1` - 产品/项目/版本树
|
- 后端:`apps/server/src/modules/data/` 提供 `GET/PUT /api/v1/data/:key`
|
||||||
- `ftb_requirements_v3`
|
- 数据库:Prisma `AppData` 模型,表名 `app_data`,`key` 为主键,`value` 为 JSONB
|
||||||
- `ftb_version_plans_v1`
|
- 前端:各 Zustand store 保持现有数据形状,通过 `apps/web/lib/server-data.ts` 读写服务端
|
||||||
- `ftb_dev_tasks_v1`
|
- 覆盖范围:产品/项目/版本树、需求池、调研/产品方案/UI 计划、开发任务、测试用例、Bug、成员/角色/部门、任务类型、任务工时日志、加班记录
|
||||||
- `ftb_test_cases_v1`
|
- 浏览器仅保留登录会话(`ftb_auth_session` / `ftb_auth_persist`),不再作为业务数据主存储
|
||||||
- `ftb_bugs_v1`
|
|
||||||
- `ftb_overtime_v1`
|
|
||||||
- `ftb_task_categories_v1`
|
|
||||||
|
|
||||||
**V2(计划):** NestJS + Prisma + PostgreSQL,Schema 已设计但尚未运行 migration。
|
**后续 V2.2(计划):** 将 `app_data` 中稳定的数据形状逐步拆成关系表和领域 CRUD API。拆表前不要恢复业务 localStorage 缓存,避免线上部署后出现多端数据分叉。
|
||||||
|
|
||||||
## 权限模型(轻量)
|
## 权限模型(轻量)
|
||||||
|
|
||||||
@@ -134,3 +131,35 @@ V1 仅做前端校验,无后端鉴权:
|
|||||||
- 版本 `members` 为空时所有人可见(兼容旧数据)
|
- 版本 `members` 为空时所有人可见(兼容旧数据)
|
||||||
|
|
||||||
V2 接入后端后改为基于 `ProjectMember` 表的 RBAC(Owner/Admin/Member/Viewer)。
|
V2 接入后端后改为基于 `ProjectMember` 表的 RBAC(Owner/Admin/Member/Viewer)。
|
||||||
|
|
||||||
|
## AI Agent 层
|
||||||
|
|
||||||
|
详细规范见 `agent-spec.md`。要点:
|
||||||
|
|
||||||
|
- AI Agent 不是一个独立服务,而是嵌在前端的"特定调用入口"。当前 V3.1 仅 Prototype Decompose Agent。
|
||||||
|
- Agent 写入数据时必须带 `aiDraft: true` 标记,列表中视觉区分(紫色边)。用户编辑后自动清除标记。
|
||||||
|
- DevTask / TestCase 加入 `references[]` 字段,记录任务/用例的来源(需求 / 原型批注)。Agent 和人工创建均强制至少 1 条引用。
|
||||||
|
- 原型链接**不在 Version 上独立存储**,而是来自产品方案 (VersionPlan type=product) 已完成计划的 `resultUrl`。约定:提交产品方案的成果就是原型。
|
||||||
|
- AI 服务实现走 **NestJS 后端**(`apps/server/src/modules/ai/`),不走 Next.js API Route。
|
||||||
|
- API Key 通过 **`/admin/ai-config` 页面配置**(仅超管可见),存到 `apps/server/data/ai-config.json`,不入 git;环境变量 `ANTHROPIC_API_KEY` 作为兜底。
|
||||||
|
|
||||||
|
新增涉及 AI 的实体字段:
|
||||||
|
|
||||||
|
| 实体 | 字段 | 类型 | 说明 |
|
||||||
|
|------|------|------|------|
|
||||||
|
| DevTask | references | Reference[]? | 引用来源(需求/原型批注) |
|
||||||
|
| DevTask | aiDraft | boolean? | AI 草案标记 |
|
||||||
|
| DevTask | aiDraftAt | string? | AI 生成时间戳 |
|
||||||
|
| TestCase | references | Reference[]? | 同上 |
|
||||||
|
| TestCase | aiDraft | boolean? | 同上 |
|
||||||
|
| TestCase | aiDraftAt | string? | 同上 |
|
||||||
|
|
||||||
|
## 版本模块规则层(V2.2 设计约束)
|
||||||
|
|
||||||
|
版本详情里的计划完成、需求候选和任务类型映射必须走规则层:
|
||||||
|
|
||||||
|
- `version-plan-workflow.ts`:调研/产品方案/UI 设计的子任务、需求覆盖、成果提交和完成条件。
|
||||||
|
- `requirement-selector.ts`:当前版本所属项目下可关联需求的候选筛选,默认只返回 `status === 'adopted'` 的项目需求。
|
||||||
|
- `task-category.ts`:DevTask/TestCase 共用任务类型字典,`id` 用于存储,`code` 用于 AI 语义映射。
|
||||||
|
|
||||||
|
页面组件只消费规则层输出,不直接拼完成条件或候选筛选条件。
|
||||||
|
|||||||
@@ -155,3 +155,117 @@
|
|||||||
4. 简单文案/样式调整
|
4. 简单文案/样式调整
|
||||||
|
|
||||||
**理由**:brainstorming 适合新功能设计,bug fix 强行套流程浪费时间。
|
**理由**:brainstorming 适合新功能设计,bug fix 强行套流程浪费时间。
|
||||||
|
|
||||||
|
## 17. AI 拆解不存历史原型,靠对账报告兜底
|
||||||
|
|
||||||
|
**问题**:FTB 接入时,禅道里项目可能已经迭代到 V1.6,前面历史原型不在系统里。AI 拆解 V1.6 时如果做"V1.5 → V1.6 diff",需要用户额外提供历史原型 URL。
|
||||||
|
|
||||||
|
**决策**:**不要求用户提供历史原型 URL**。AI 拆解只用三样输入:当前版本原型 + 关联需求 + 版本成员。
|
||||||
|
|
||||||
|
**对应风险**:AI 可能把"上版本就有的功能"也当成"本次新做"。
|
||||||
|
|
||||||
|
**应对**:要求 Agent 输出**对账报告**,三段:
|
||||||
|
- ✅ 完美对应(需求 ↔ 原型注释 ↔ 任务)
|
||||||
|
- ⚠️ 仅需求未见原型 / 仅原型未见需求
|
||||||
|
- ❓ 注释含糊无法转化
|
||||||
|
|
||||||
|
**理由**:让历史版本入库的成本远高于让用户对账的成本。对账报告本来就是 AI 拆解的标配,能同时兜住"拆偏"和"拆漏"两类问题。让团队补需求清单,比让团队补历史原型容易。
|
||||||
|
|
||||||
|
## 18. AI 写入必须带 aiDraft 标记 + 引用来源
|
||||||
|
|
||||||
|
**问题**:AI 直接写入开发任务/用例,团队无法分辨"这是 AI 拆的还是人手填的",出错时找不到来源。
|
||||||
|
|
||||||
|
**决策**:
|
||||||
|
- DevTask / TestCase 加 `aiDraft: boolean` 字段
|
||||||
|
- AI 写入时强制 `aiDraft: true`
|
||||||
|
- 列表中 AI 草案视觉区分(紫色左边线 + AI 草案徽章)
|
||||||
|
- 用户编辑保存后 `aiDraft` 自动清除(在 store 的 update 方法里实现)
|
||||||
|
- 同时加 `references: Reference[]` 字段,记录引用来源(需求 / 原型批注)
|
||||||
|
|
||||||
|
**理由**:
|
||||||
|
- 可识别性:团队一眼分辨 AI 产出 vs 人工产出
|
||||||
|
- 可追溯性:每条任务知道是从哪条需求 + 哪条原型批注来的
|
||||||
|
- 可信任:用户编辑即认可,自动转正常状态
|
||||||
|
|
||||||
|
## 19. 引用机制对 AI 和人工一致
|
||||||
|
|
||||||
|
**问题**:如果只有 AI 任务带 references,人工任务不带,会出现两套规则:用户看到 AI 任务有引用、人工没有,体验割裂;做"任务可追溯"功能时数据缺失。
|
||||||
|
|
||||||
|
**决策**:人工创建 DevTask / TestCase 时也强制带 references。
|
||||||
|
- 表单加「关联需求」(从版本已加需求里多选,自动转 requirement 类型 reference)
|
||||||
|
- 表单加「原型批注」(手填编号或自由文本,逗号/空格分隔,自动转 prototype_note 类型 reference)
|
||||||
|
- AI 草案唯一区别只剩 `aiDraft: true` 这一个状态字段
|
||||||
|
|
||||||
|
**理由**:单一数据形状,UI 复用;可追溯性是任务本身的属性,不该由"谁创建"决定。
|
||||||
|
|
||||||
|
## 20. AI 配置走页面不走 .env
|
||||||
|
|
||||||
|
**问题**:早期 ANTHROPIC_API_KEY 只能写到 `apps/server/.env`,配置流程对非技术人员不友好;切换 key 要重启 NestJS。
|
||||||
|
|
||||||
|
**决策**:
|
||||||
|
- 加 `apps/server/src/modules/config/` 模块,提供 GET/PATCH/POST `/api/v1/config/ai` 接口
|
||||||
|
- 配置存到 `apps/server/data/ai-config.json`(在 .gitignore 里)
|
||||||
|
- 前端 `/admin/ai-config` 页面(仅超管可见)支持修改 Key、切换模型、测试连接
|
||||||
|
- AiGateway 优先读文件,其次读环境变量;切换 key 后客户端单例自动重建
|
||||||
|
- 前端 GET 接口永远不返回完整 Key,只返回 mask(如 `sk-ant...xxxx`)
|
||||||
|
|
||||||
|
**理由**:
|
||||||
|
- 运营/管理可以自助维护,不依赖工程师改代码
|
||||||
|
- Key 在服务器存储,前端永远拿不到完整内容,安全等同 .env
|
||||||
|
- 走 .env 的兜底保留,给 CI / 早期部署留路径
|
||||||
|
|
||||||
|
## 21. 多 AI 提供商抽象,支持中转站
|
||||||
|
|
||||||
|
**问题**:早期 AiGateway 硬绑定 Anthropic 官方 SDK,无法走 ikuncode 等中转站,也不能切换到 OpenAI 格式提供商。
|
||||||
|
|
||||||
|
**决策**:引入 Provider 抽象层。
|
||||||
|
- `apps/server/src/modules/ai/providers/` 下两个实现:`AnthropicProvider` / `OpenAIProvider`
|
||||||
|
- 共同实现 `AiProvider` 接口(`callTool` / `ping`),把厂商差异封装在 provider 内部
|
||||||
|
- `prompts/decompose.ts` 用格式无关的 JSON Schema,由各 provider 包装成 Anthropic 的 `input_schema` 或 OpenAI 的 `parameters`
|
||||||
|
- 配置数据结构升级为 `{ providers: [], activeProviderId }`,支持配置多个 provider 运行时切换
|
||||||
|
- 旧的单 key 配置自动迁移成 `providers[0]`
|
||||||
|
|
||||||
|
**支持范围**:当前两类格式覆盖 99% 中转站
|
||||||
|
- `anthropic`:Anthropic 官方 / 中转站(兼容 Messages API + tool_use)
|
||||||
|
- `openai`:OpenAI 官方 / 中转站(兼容 Chat Completions + tool calling)
|
||||||
|
|
||||||
|
**理由**:
|
||||||
|
- 用户可以自由选择厂家或中转站,不被一家锁死
|
||||||
|
- 每个 provider 独立 model 字段,因为不同提供商上同名模型不一定可用
|
||||||
|
- "激活"概念让多套配置同时存在,方便 A/B 切换
|
||||||
|
- 抽象层让上层 AiService 完全不感知厂商差异,未来加 Risk Watch / Schedule Suggest Agent 时复用
|
||||||
|
|
||||||
|
## 22. 业务数据先迁到 PostgreSQL AppData,再逐步关系化
|
||||||
|
|
||||||
|
**问题**:V1 业务数据存在浏览器 localStorage 中,用户在 Application Storage 执行 Clear site data 后,产品、项目、版本、需求池、版本详情里的调研/产品方案/UI/开发任务/测试用例/Bug,以及成员、任务类型等都会丢失。系统未来要部署到服务器,浏览器不能作为业务数据主存储。
|
||||||
|
|
||||||
|
**决策**:先引入服务端通用数据文档层:
|
||||||
|
- Prisma 增加 `AppData` 模型(表 `app_data`,`key` + JSONB `value`)
|
||||||
|
- NestJS 增加 `DataModule`,通过 `GET/PUT /api/v1/data/:key` 读写允许的业务数据 key
|
||||||
|
- 前端 store 保持现有数据形状和业务逻辑,只把持久化从 localStorage 切换到 `/data/:key`
|
||||||
|
- 覆盖 key:`products-overview`、`requirements`、`version-plans`、`dev-tasks`、`test-cases`、`bugs`、`members`、`task-categories`、`task-worklogs`、`overtime`
|
||||||
|
- 浏览器只保留登录态,不保存业务主数据
|
||||||
|
|
||||||
|
**理由**:
|
||||||
|
- 当前模块多、数据形状仍在快速调整,一次性全量关系化风险高、改动面大
|
||||||
|
- JSONB 文档表能立刻解决“清浏览器数据导致业务数据丢失”的线上部署问题
|
||||||
|
- 保持 store 数据形状不变,能降低迁移对现有 UI、AI 拆解、工作台聚合的冲击
|
||||||
|
- 后续等字段稳定后,再把 `app_data` 中的文档逐步迁入关系表和领域 CRUD API
|
||||||
|
|
||||||
|
## 23. 版本计划完成条件进入工作流引擎,任务类型使用稳定语义码
|
||||||
|
|
||||||
|
**问题**:版本模块里,调研/产品方案/UI 设计的完成动作散在 `PlanTab` 和 `PlanDetailDrawer`,右上角勾选按钮会绕过子任务和成果提交。开发任务的任务类型太粗,测试用例没有任务类型,AI 拆解只输出 `role`,无法稳定映射到业务分类。
|
||||||
|
|
||||||
|
**决策**:
|
||||||
|
- 新增 `version-plan-workflow.ts`,统一判断计划是否可勾选子任务、是否可提交成果、是否可完成、缺少什么条件。
|
||||||
|
- 取消计划卡片右上角的“直接完成”勾选按钮,完成只能通过提交成果触发。
|
||||||
|
- 调研/产品方案/UI 设计都使用子任务清单;完成时必须满足规则引擎要求并提交链接或文件成果。
|
||||||
|
- 新增 `requirement-selector.ts`,所有关联需求候选都从当前版本所属项目下的已采纳需求中取,不从全量需求池取。
|
||||||
|
- DevTask 和 TestCase 共用 `TaskCategory` 字典,`TestCase` 增加 `categoryId`。
|
||||||
|
- `TaskCategory` 增加稳定 `code`,AI 输出 `categoryCode`,前端再映射为当前系统的 `categoryId`。
|
||||||
|
|
||||||
|
**理由**:
|
||||||
|
- 完成条件属于业务规则,不属于按钮组件;集中到工作流引擎后,列表和抽屉能保持一致。
|
||||||
|
- 需求候选来源属于领域边界;统一 selector 能避免从需求池、项目需求、版本需求之间误取数据。
|
||||||
|
- AI 不应该猜数据库 id;稳定语义码能兼容管理员调整展示名称,也方便后续扩展更多模型。
|
||||||
|
- 测试用例带任务类型后,才能知道测试覆盖范围,AI 拆解和人工创建的数据形状也一致。
|
||||||
|
|||||||
@@ -1,11 +1,17 @@
|
|||||||
# 开发路线图
|
# 开发路线图
|
||||||
|
|
||||||
## 当前阶段:V1 — 前端 Mock + 业务流程打磨
|
## 当前阶段:V2.1 — 服务端持久化第一阶段
|
||||||
|
|
||||||
所有数据用 localStorage 持久化,重点验证业务模型和交互。
|
业务流程仍保持 V1 的前端 store 形状,但业务数据主存储已切到 NestJS + PostgreSQL `app_data` 文档表。浏览器只保留登录态,不再保存产品、项目、版本、需求、版本详情、成员、任务类型等业务数据。
|
||||||
|
|
||||||
### 已完成(按时间倒序)
|
### 已完成(按时间倒序)
|
||||||
|
|
||||||
|
**2026-06-24**
|
||||||
|
- 新增 NestJS `DataModule` + Prisma `AppData`,提供 `GET/PUT /api/v1/data/:key`
|
||||||
|
- 产品/项目/版本树、需求池、调研/产品方案/UI、开发任务、测试用例、Bug 改为服务端持久化
|
||||||
|
- 成员/角色/部门、任务类型、任务工时日志、加班记录改为服务端持久化
|
||||||
|
- 登录改为读取服务端成员数据;浏览器只保留登录会话
|
||||||
|
|
||||||
**2026-06-16**
|
**2026-06-16**
|
||||||
- 项目模块顶部卡片(总版本数/已开发/需求数/Bug 总数)
|
- 项目模块顶部卡片(总版本数/已开发/需求数/Bug 总数)
|
||||||
- 项目模块版本记录与版本详情数据联动(耗时 + 状态胶囊)
|
- 项目模块版本记录与版本详情数据联动(耗时 + 状态胶囊)
|
||||||
@@ -47,38 +53,70 @@
|
|||||||
|
|
||||||
## V2 — 后端接入
|
## V2 — 后端接入
|
||||||
|
|
||||||
NestJS + Prisma + PostgreSQL Schema 已设计,等业务流程稳定后开始迁移。
|
NestJS + Prisma + PostgreSQL 已开始接入。第一阶段先用 `app_data` JSONB 文档表承接现有 store 数据形状,避免浏览器清站点数据导致业务数据丢失;第二阶段再逐步拆成关系表。
|
||||||
|
|
||||||
### 关键任务
|
### 关键任务
|
||||||
|
|
||||||
1. **运行 Prisma migration**:把现有的 lib/*.ts 类型转为 Prisma schema
|
1. **服务端文档层**:`app_data` + `/api/v1/data/:key`(第一阶段已实现)
|
||||||
2. **API 层**:每个 store 对应一组 CRUD endpoint
|
2. **localStorage → API 切换**:业务主数据不再写浏览器(第一阶段已实现)
|
||||||
3. **localStorage → API 切换**:保留 localStorage 作为离线缓存
|
3. **运行 Prisma 同步/迁移**:本地和服务器数据库都需要创建 `app_data`
|
||||||
4. **认证**:NextAuth.js + JWT
|
4. **关系化拆表**:把稳定模块从 JSONB 拆成 Product/Project/Version/Task 等领域表
|
||||||
5. **权限**:RBAC(Owner/Admin/Member/Viewer),按项目/版本级别
|
5. **认证**:NextAuth.js + JWT
|
||||||
|
6. **权限**:RBAC(Owner/Admin/Member/Viewer),按项目/版本级别
|
||||||
|
7. **版本规则引擎收敛**:VersionPlan 完成条件、关联需求候选、TaskCategory 语义码、TestCase.categoryId 统一收束到规则层
|
||||||
|
|
||||||
### 数据迁移策略
|
### 数据迁移策略
|
||||||
|
|
||||||
提供管理员脚本把当前用户的 localStorage 数据导出为 SQL,导入到 PostgreSQL。
|
当前不做本地导入导出。清站点数据后浏览器旧数据无法恢复,后续新增数据直接写入 PostgreSQL。若以后需要迁移旧浏览器数据,再单独做管理员导入工具。
|
||||||
|
|
||||||
## V3 — AI 集成
|
## V3 — AI Agent 集成
|
||||||
|
|
||||||
### 已规划场景
|
详细 Agent 规范见 `agent-spec.md`。本节只列规划,不重复 Agent 实现细节。
|
||||||
|
|
||||||
1. **需求智能分解**:输入需求描述,AI 拆解为子任务(技术分析+UI 调整+联调+测试)
|
### V3.1 — Prototype Decompose Agent(首个 Agent)
|
||||||
2. **风险预警**:自动识别延期/阻塞集中/工时偏差大的任务,提前预警
|
|
||||||
3. **排期建议**:基于成员负载和历史耗时,建议下一阶段任务分配
|
|
||||||
4. **需求转任务**:需求采纳后一键生成 DevTask 草稿
|
|
||||||
5. **健康度智能解读**:把数据指标转化为自然语言报告
|
|
||||||
|
|
||||||
### 落地方式
|
**目标**:从产品方案的原型 + 关联需求,拆解出开发任务草案 + 测试用例草案。
|
||||||
|
|
||||||
`apps/server/src/modules/ai/`:
|
**已完成的数据底座**(2026-06):
|
||||||
- `AiGateway` — 统一 prompt 管理、token 计量、降级
|
- DevTask / TestCase 加 references[] + aiDraft + aiDraftAt
|
||||||
- `AiTaskService.decompose(description)`
|
- 创建表单加「原型批注」字段
|
||||||
- `AiRiskService.analyze(projectId)`
|
- 列表中 AI 草案视觉区分(紫色边 + 徽章)
|
||||||
- `AiScheduleService.suggest(projectId)`
|
- 编辑后自动清除 aiDraft 标记
|
||||||
- `AiLog` 表存调用记录,便于审计
|
- agent-spec.md / glossary.md 文档落地
|
||||||
|
- 约定:原型链接 = 产品方案 (VersionPlan type=product) 已完成计划的 resultUrl,不在 Version 上独立存储
|
||||||
|
|
||||||
|
**待实现**:
|
||||||
|
1. 后端 `AiGateway` + `PrototypeDecomposeService`(NestJS module)
|
||||||
|
2. 前端「AI 拆解任务和用例」按钮(产品方案 Tab)
|
||||||
|
3. 对账报告组件(弹窗呈现三段:完美对应 / 单边 / 含糊)
|
||||||
|
4. 用户确认后批量创建 DevTask + TestCase 草案
|
||||||
|
5. AiLog 表(调用记录、token 计量、用时)
|
||||||
|
|
||||||
|
**MVP 范围限制**:
|
||||||
|
- 不自动分配 assignee(留给用户在草案上手填)
|
||||||
|
- 不做"上一版基准 diff"(按 decisions.md #17 决议)
|
||||||
|
- 单 Agent 单 Round,不做多 Agent 编排
|
||||||
|
|
||||||
|
### V3.2 — Risk Watch Agent + Schedule Suggest Agent
|
||||||
|
|
||||||
|
**Risk Watch Agent**:自动识别延期/阻塞集中/工时偏差大的任务,提前预警
|
||||||
|
|
||||||
|
**Schedule Suggest Agent**:基于成员负载和历史耗时,建议下一阶段任务分配
|
||||||
|
|
||||||
|
**多 Agent 协作设计**:到 V3.2 才真正涉及,当前 agent-spec.md 仅占位
|
||||||
|
|
||||||
|
### V3.3 — 其他场景候选
|
||||||
|
|
||||||
|
1. 需求智能分类(自动归档到产品 / 项目)
|
||||||
|
2. 健康度智能解读(数据指标 → 自然语言报告)
|
||||||
|
3. 需求转任务(需求采纳后一键生成 DevTask 草稿)
|
||||||
|
|
||||||
|
### 落地约束
|
||||||
|
|
||||||
|
- **不直接动数据**:所有 Agent 写入必须带 `aiDraft: true`,用户编辑后才转正
|
||||||
|
- **必须有引用**:所有 AI 产物带 references,用户能追溯到源头
|
||||||
|
- **必须有对账报告**:拆解类 Agent 输出前端展示三段报告,让用户决策
|
||||||
|
- **可降级**:原型不可达 / 输入数据不全 / 模型超时,明确告知用户失败原因,不写入任何数据
|
||||||
|
|
||||||
## 不在路线图(明确不做)
|
## 不在路线图(明确不做)
|
||||||
|
|
||||||
@@ -95,6 +133,6 @@ NestJS + Prisma + PostgreSQL Schema 已设计,等业务流程稳定后开始
|
|||||||
|------|------|
|
|------|------|
|
||||||
| V1 业务流程打磨 | 进行中 |
|
| V1 业务流程打磨 | 进行中 |
|
||||||
| V1 朋友试用反馈 | 持续中 |
|
| V1 朋友试用反馈 | 持续中 |
|
||||||
| V2 后端接入 | 等 V1 稳定 |
|
| V2 后端接入 | 进行中(V2.1 AppData 已实现) |
|
||||||
| V3 AI 集成 | 等 V2 数据沉淀 |
|
| V3 AI 集成 | 等 V2 数据沉淀 |
|
||||||
| 公开发布 | TBD |
|
| 公开发布 | TBD |
|
||||||
|
|||||||
226
docs/superpowers/specs/2026-06-25-version-module-rules-design.md
Normal file
226
docs/superpowers/specs/2026-06-25-version-module-rules-design.md
Normal file
@@ -0,0 +1,226 @@
|
|||||||
|
# 版本模块规则引擎与任务类型设计
|
||||||
|
|
||||||
|
## 背景
|
||||||
|
|
||||||
|
版本详情里的调研、产品方案、UI 设计、开发任务、测试用例已经形成一条执行链路,但有几处规则还散在 UI 组件里:
|
||||||
|
|
||||||
|
- 开发任务的任务类型太粗,测试用例还没有任务类型。
|
||||||
|
- AI 拆解只输出 `role`,不能稳定落到当前系统的任务类型字典。
|
||||||
|
- 计划任务可以通过右上角勾选直接完成,绕过子任务和成果提交。
|
||||||
|
- 关联需求的候选来源不够明确,容易误用全量需求池。
|
||||||
|
- 调研、产品方案、UI 设计的关联需求选择缺少全选能力。
|
||||||
|
|
||||||
|
这次设计的目标是把这些规则收敛到字典、选择器和工作流引擎里,而不是继续在页面组件里散写条件。
|
||||||
|
|
||||||
|
## 目标
|
||||||
|
|
||||||
|
1. 任务类型能支撑更细的开发与测试范围。
|
||||||
|
2. DevTask 和 TestCase 共用同一套任务类型字典。
|
||||||
|
3. AI 拆解必须输出任务类型,并能稳定映射到系统字典。
|
||||||
|
4. VersionPlan 的完成条件由统一规则函数判断。
|
||||||
|
5. 所有关联需求入口只从当前版本所属项目下的已采纳需求中选择,不从全量需求池选择。
|
||||||
|
6. 调研、产品方案、UI 设计的关联需求选择支持全选。
|
||||||
|
7. 项目文档明确约束:跨模块联动、状态流转、完成条件、AI 契约必须优先考虑引擎、状态机或统一规则函数。
|
||||||
|
|
||||||
|
## 非目标
|
||||||
|
|
||||||
|
- 不做本地数据导入导出。
|
||||||
|
- 不在这一步把 `app_data` 全量拆成关系表。
|
||||||
|
- 不让 AI 自动分配负责人。
|
||||||
|
- 不让 AI 直接写入正式 DevTask/TestCase;仍然只写入草案。
|
||||||
|
|
||||||
|
## 方案概览
|
||||||
|
|
||||||
|
新增或调整三个规则层:
|
||||||
|
|
||||||
|
1. `task-category.ts`:任务类型字典扩展为开发、测试、实施、其他,并增加稳定语义码。
|
||||||
|
2. `requirement-selector.ts`:统一筛选当前项目下可用于关联的需求。
|
||||||
|
3. `version-plan-workflow.ts`:统一计算计划进度、是否能提交成果、是否能完成、缺少什么条件。
|
||||||
|
|
||||||
|
页面组件只负责展示和触发动作,不直接决定业务规则。
|
||||||
|
|
||||||
|
## 任务类型字典
|
||||||
|
|
||||||
|
`TaskCategory` 继续作为开发任务和测试用例的共享字典,但增加一个稳定字段:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
interface TaskCategory {
|
||||||
|
id: string; // 存储主键,仍用于 DevTask.categoryId / TestCase.categoryId
|
||||||
|
code: string; // 稳定语义码,给 AI 和映射逻辑使用
|
||||||
|
name: string; // 展示名称,可被管理员调整
|
||||||
|
group: 'development' | 'testing' | 'implementation' | 'other';
|
||||||
|
color?: string;
|
||||||
|
sortOrder: number;
|
||||||
|
isSystem: boolean;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
推荐预置分类示例:
|
||||||
|
|
||||||
|
- 开发:前端页面、前端交互、后端接口、后端业务逻辑、数据库/数据结构、权限/流程、第三方集成、接口联调
|
||||||
|
- 测试:功能测试、接口测试、异常场景、兼容性测试、回归测试、数据校验
|
||||||
|
- 实施:数据处理、实施支持、配置部署
|
||||||
|
- 其他:文档、协调、待确认
|
||||||
|
|
||||||
|
`id` 用于系统存储,`code` 用于 AI 输出和迁移兼容。管理员可以改名称,但不建议随意修改系统预置 `code`。
|
||||||
|
|
||||||
|
## 测试用例任务类型
|
||||||
|
|
||||||
|
`TestCase` 增加 `categoryId`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
interface TestCase {
|
||||||
|
categoryId: string;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
影响范围:
|
||||||
|
|
||||||
|
- `TestCaseCreateModal` 增加任务类型必填项。
|
||||||
|
- `TestCaseRow` 和 `TestCaseDetailDrawer` 展示类型标签。
|
||||||
|
- `useTestCaseStore.fetchTestCases` 对旧数据做兼容补齐,默认映射到测试分组的第一个系统类型。
|
||||||
|
- AI 草案写入 TestCase 时也要映射 `categoryCode -> categoryId`。
|
||||||
|
|
||||||
|
## 关联需求选择规则
|
||||||
|
|
||||||
|
所有关联需求入口统一使用同一套候选规则:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
requirements.filter((r) =>
|
||||||
|
r.projectId === version.projectId &&
|
||||||
|
r.status === 'adopted'
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
含义:
|
||||||
|
|
||||||
|
- 候选来自当前版本所属项目下的需求,不从产品级全量需求池直接取。
|
||||||
|
- 只有已采纳需求可被新选择。
|
||||||
|
- 如果历史计划已经关联了某条需求,但该需求后来不再满足候选条件,编辑时保留旧关联并标记为“历史关联”,避免悄悄丢数据。
|
||||||
|
- 版本需求 Tab、调研计划、产品方案、UI 设计、开发任务和测试用例中的需求选择都复用该规则函数。
|
||||||
|
|
||||||
|
调研、产品方案、UI 设计的关联需求控件增加:
|
||||||
|
|
||||||
|
- 全选当前候选。
|
||||||
|
- 清空选择。
|
||||||
|
- 已选数量 / 候选数量提示。
|
||||||
|
- 候选为空时说明需要先在项目下采纳需求。
|
||||||
|
|
||||||
|
## VersionPlan 工作流引擎
|
||||||
|
|
||||||
|
新增 `apps/web/lib/version-plan-workflow.ts`,作为计划完成规则的唯一入口。
|
||||||
|
|
||||||
|
建议导出:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
interface PlanCompletionState {
|
||||||
|
checklistTotal: number;
|
||||||
|
checklistCompleted: number;
|
||||||
|
requirementTotal: number;
|
||||||
|
requirementCompleted: number;
|
||||||
|
hasResult: boolean;
|
||||||
|
canSubmitResult: boolean;
|
||||||
|
canComplete: boolean;
|
||||||
|
missingReasons: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPlanCompletionState(plan: VersionPlan): PlanCompletionState;
|
||||||
|
function canTogglePlanChecklist(plan: VersionPlan, now?: Date): boolean;
|
||||||
|
function canEditPlanRequirementCoverage(plan: VersionPlan, now?: Date): boolean;
|
||||||
|
```
|
||||||
|
|
||||||
|
完成规则:
|
||||||
|
|
||||||
|
- 调研、产品方案、UI 设计都使用 `tasks` 作为子任务清单。
|
||||||
|
- 子任务必须全部勾选完成。
|
||||||
|
- 完成时必须提交成果,成果可以是链接或文件。
|
||||||
|
- 产品方案和 UI 设计如果有关联需求覆盖清单,也必须全部勾选覆盖完成。
|
||||||
|
- 右上角“直接完成”的勾选按钮取消。
|
||||||
|
- `PlanTab` 和 `PlanDetailDrawer` 都只调用工作流引擎,不再各自写完成条件。
|
||||||
|
|
||||||
|
状态写入仍保持:
|
||||||
|
|
||||||
|
- `pending -> in_progress -> completed`
|
||||||
|
- `actualStartAt` 在开始时写入。
|
||||||
|
- `completedAt` 只能通过提交成果完成时写入。
|
||||||
|
|
||||||
|
## AI 拆解契约
|
||||||
|
|
||||||
|
AI 输出不直接返回数据库 `categoryId`,而是返回稳定语义码:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
interface AgentDevTaskDraft {
|
||||||
|
title: string;
|
||||||
|
description?: string;
|
||||||
|
categoryCode: string;
|
||||||
|
priority: 'P0' | 'P1' | 'P2' | 'P3';
|
||||||
|
estimateHours: number;
|
||||||
|
references: AgentReference[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AgentTestCaseDraft {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
categoryCode: string;
|
||||||
|
priority: 'P0' | 'P1' | 'P2' | 'P3';
|
||||||
|
references: AgentReference[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
映射规则:
|
||||||
|
|
||||||
|
1. 优先按 `TaskCategory.code` 匹配。
|
||||||
|
2. 匹配不到时按名称做宽松匹配。
|
||||||
|
3. 仍匹配不到时,开发任务落到开发分组默认类型,测试用例落到测试分组默认类型。
|
||||||
|
4. 映射失败不阻断 AI 报告展示,但确认写入前必须能得到 `categoryId`。
|
||||||
|
|
||||||
|
`prompts/decompose.ts` 的 tool schema 要求 devTaskDrafts 和 testCaseDrafts 都必须带 `categoryCode`。
|
||||||
|
|
||||||
|
## UI 行为
|
||||||
|
|
||||||
|
- 计划卡片右上角不再显示直接完成的勾选按钮。
|
||||||
|
- 完成入口改为“提交成果”,按钮在条件不足时禁用并展示缺失原因。
|
||||||
|
- 完成弹窗保留链接/文件两种结果类型。
|
||||||
|
- 调研、产品方案、UI 设计新建/编辑时都展示关联需求选择,并支持全选。
|
||||||
|
- 测试用例新建弹窗增加任务类型选择。
|
||||||
|
- AI 草案确认弹窗展示每条任务/用例的任务类型。
|
||||||
|
|
||||||
|
## 兼容与迁移
|
||||||
|
|
||||||
|
当前业务数据仍存于 PostgreSQL `app_data` JSONB。
|
||||||
|
|
||||||
|
- 新增字段时在 store fetch 阶段做轻量兼容补齐。
|
||||||
|
- 旧 TestCase 没有 `categoryId` 时补齐默认测试类型。
|
||||||
|
- 旧 TaskCategory 没有 `code` 时按系统预置映射补齐;自定义类型生成稳定 code。
|
||||||
|
- 不恢复业务 localStorage 缓存。
|
||||||
|
|
||||||
|
## 验证计划
|
||||||
|
|
||||||
|
实现时至少覆盖:
|
||||||
|
|
||||||
|
- `version-plan-workflow` 单元测试:
|
||||||
|
- 子任务未完成不能完成。
|
||||||
|
- 未提交成果不能完成。
|
||||||
|
- 子任务完成 + 成果存在才可完成。
|
||||||
|
- 产品方案/UI 设计有关联需求覆盖时,未覆盖完不能完成。
|
||||||
|
- 任务类型映射测试:
|
||||||
|
- `categoryCode` 能映射系统类型。
|
||||||
|
- 未知 `categoryCode` 有合理 fallback。
|
||||||
|
- TestCase 旧数据能补齐类型。
|
||||||
|
- AI schema 测试:
|
||||||
|
- devTaskDrafts 和 testCaseDrafts 都要求 `categoryCode`。
|
||||||
|
- 手工 UI 验证:
|
||||||
|
- 调研/产品/UI 关联需求全选可用。
|
||||||
|
- 候选需求只来自当前项目已采纳需求。
|
||||||
|
- 顶部直接完成按钮消失。
|
||||||
|
- 测试用例创建必须选择任务类型。
|
||||||
|
|
||||||
|
## 后续实现顺序
|
||||||
|
|
||||||
|
1. 写规则引擎和选择器测试。
|
||||||
|
2. 实现任务类型字典扩展和旧数据兼容。
|
||||||
|
3. 给 TestCase 增加 `categoryId`。
|
||||||
|
4. 接入 VersionPlan 工作流引擎。
|
||||||
|
5. 接入需求选择器和全选 UI。
|
||||||
|
6. 升级 AI schema、共享类型和草案写入映射。
|
||||||
|
7. 跑类型检查和核心测试。
|
||||||
@@ -39,7 +39,8 @@
|
|||||||
- [ ] 是否需要在 `workspace-engine.ts` 加聚合?
|
- [ ] 是否需要在 `workspace-engine.ts` 加聚合?
|
||||||
- [ ] 删除版本时是否需要清理这类数据?
|
- [ ] 删除版本时是否需要清理这类数据?
|
||||||
- [ ] 工作台 / 版本详情 / 项目详情三处的统计是否同步?
|
- [ ] 工作台 / 版本详情 / 项目详情三处的统计是否同步?
|
||||||
- [ ] localStorage 旧数据是否需要兼容处理?
|
- [ ] 是否需要新增 `app_data` key(后端 `data-keys.ts` + 前端 `server-data.ts`)?
|
||||||
|
- [ ] 是否需要从旧浏览器数据做一次性迁移?(当前不做本地导入导出)
|
||||||
|
|
||||||
## Drawer(侧边详情)规范
|
## Drawer(侧边详情)规范
|
||||||
|
|
||||||
@@ -85,15 +86,19 @@
|
|||||||
|
|
||||||
朋友拉新代码出现"显示问题"时,按顺序排查:
|
朋友拉新代码出现"显示问题"时,按顺序排查:
|
||||||
|
|
||||||
1. 旧 localStorage 数据格式不兼容 → 让朋友清缓存
|
1. 后端是否启动:`GET http://localhost:3001/api/v1/config/ai` 应返回 200
|
||||||
2. 类型定义和实际数据不一致(缺字段)
|
2. 数据库是否启动并完成 Prisma 同步:`app_data` 表必须存在
|
||||||
3. 列宽溢出导致裁切
|
3. 对应 `app_data.key` 是否有值,例如 `products-overview` / `requirements` / `dev-tasks`
|
||||||
4. 派生计算错误(filter 条件错)
|
4. 前端 store 是否已经调用对应 `fetch*` 方法
|
||||||
5. 跨模块联动断了(store 的 store.getState() 调用时机)
|
5. 类型定义和实际 JSON 数据不一致(缺字段)
|
||||||
|
6. 列宽溢出导致裁切
|
||||||
|
7. 派生计算错误(filter 条件错)
|
||||||
|
8. 跨模块联动断了(store 的 store.getState() 调用时机)
|
||||||
|
|
||||||
## 测试 / 验证流程
|
## 测试 / 验证流程
|
||||||
|
|
||||||
- 改动后必须 `npx tsc --noEmit` 通过
|
- 改动后必须 `npx tsc --noEmit` 通过
|
||||||
|
- 涉及服务端数据持久化:`pnpm --filter server exec prisma validate --schema prisma/schema.prisma`
|
||||||
- 涉及 UI 改动:`curl http://localhost:3000/<path>` 检查 200
|
- 涉及 UI 改动:`curl http://localhost:3000/<path>` 检查 200
|
||||||
- 不会自动跑 dev server,假定它已经运行
|
- 不会自动跑 dev server,假定它已经运行
|
||||||
|
|
||||||
@@ -116,3 +121,66 @@ Workspace 页面(树筛选 + tab 筛选 + 已完成开关)
|
|||||||
```
|
```
|
||||||
|
|
||||||
新增模块时,只需在 `aggregateWorkItems` 中添加聚合逻辑,工作台自动展示。
|
新增模块时,只需在 `aggregateWorkItems` 中添加聚合逻辑,工作台自动展示。
|
||||||
|
|
||||||
|
## AI 拆解工作流(V3.1)
|
||||||
|
|
||||||
|
详细 Agent 规范见 `agent-spec.md`。这里是用户视角的工作流:
|
||||||
|
|
||||||
|
```
|
||||||
|
1. 创建版本(不需要单独填原型链接)
|
||||||
|
↓
|
||||||
|
2. 在版本详情 → 产品方案 Tab 创建一条 product 计划
|
||||||
|
↓
|
||||||
|
3. 完成产品方案计划,提交「成果」(成果链接即原型链接,附成果标题)
|
||||||
|
↓
|
||||||
|
4. 从当前项目已采纳需求中关联需求到本版本
|
||||||
|
↓
|
||||||
|
5. 点击「AI 拆解任务和用例」按钮(位于产品方案 Tab)
|
||||||
|
↓
|
||||||
|
6. Agent 从 product 类型的 completed 计划取 resultUrl 作为原型,
|
||||||
|
抓取原型 + 关联需求 + 版本成员,输出对账报告 + 任务/用例草案
|
||||||
|
↓
|
||||||
|
7. 用户审核对账报告
|
||||||
|
├─ 报告全 ✅:直接确认写入
|
||||||
|
├─ 报告有 ⚠️/❓:选择性放弃部分草案 / 补充信息后重跑
|
||||||
|
└─ 报告全 ❓:放弃 AI 拆解,人工创建
|
||||||
|
↓
|
||||||
|
8. 确认后,DevTask / TestCase 草案写入对应 Tab,标记 aiDraft: true
|
||||||
|
↓
|
||||||
|
9. 团队成员在 DevTask Tab 看到紫色边的 AI 草案任务
|
||||||
|
↓
|
||||||
|
10. 任意成员编辑任务(改标题/描述/负责人/优先级/时间/分类),保存后 aiDraft 自动清除
|
||||||
|
(changeStatus / setBlocked 等用户主动操作也会清除)
|
||||||
|
```
|
||||||
|
|
||||||
|
**触发条件**(AI 拆解按钮可点):
|
||||||
|
- 至少有 1 条 type=product 的产品方案计划处于 completed 且 resultUrl 非空
|
||||||
|
- 至少 1 条需求关联到本版本
|
||||||
|
|
||||||
|
**人工创建任务/用例的引用要求**:
|
||||||
|
- 创建 DevTask 时已选「关联需求」自动作为 reference 写入
|
||||||
|
- 创建表单加「原型批注」字段(手填,逗号或空格分隔,如 `QY0007, QY0023`)
|
||||||
|
- 至少一类引用非空才能保存(V3.1 暂未做强校验,靠 UI 引导)
|
||||||
|
|
||||||
|
## 高级开发约束:规则先归位
|
||||||
|
|
||||||
|
涉及以下任意类型的改动时,先判断规则应该放在哪一层,不允许直接在页面组件里散写临时判断:
|
||||||
|
|
||||||
|
- 跨模块联动:例如 Requirement、VersionPlan、DevTask、TestCase、Bug 互相派生状态。
|
||||||
|
- 状态流转:例如 `pending -> in_progress -> completed`、`todo -> testing -> submitted`。
|
||||||
|
- 完成条件:例如子任务是否完成、是否提交成果、是否允许点击完成。
|
||||||
|
- 候选数据来源:例如关联需求只能来自当前项目已采纳需求,不能从全量需求池随手取。
|
||||||
|
- AI 写入契约:例如 AI 输出任务类型、引用来源、草案标记。
|
||||||
|
|
||||||
|
默认落点:
|
||||||
|
|
||||||
|
- 可派生数据进 `*-engine.ts` 或纯函数 helper。
|
||||||
|
- 有状态流转的实体要有状态机或 workflow helper。
|
||||||
|
- 多个组件共用的候选筛选规则进 selector/helper。
|
||||||
|
- AI 输入输出字段先更新 `agent-spec.md` 和 shared type,再改 prompt/schema。
|
||||||
|
|
||||||
|
版本模块新增规则:
|
||||||
|
|
||||||
|
- `version-plan-workflow.ts` 是调研/产品方案/UI 设计完成条件的唯一入口。
|
||||||
|
- `requirement-selector.ts` 是版本内关联需求候选的唯一入口。
|
||||||
|
- `TaskCategory.code` 是 AI 和系统任务类型的稳定映射锚点,`id` 只作为存储主键。
|
||||||
|
|||||||
Reference in New Issue
Block a user