需求到交付(Requirement → Delivery)端到端流程
将一份需求文档(飞书链接、Markdown 文件、PRD、用户直接粘贴的需求描述等任意形式)变成可上线代码 + 自动化测试。整体分 7 个阶段,严格按顺序推进 ,每个阶段都要有显式的用户确认,禁止跳步。
关于自动化测试 :本流程不绑定特定测试框架。具体用什么(Cypress / Playwright / Vitest / Jest / Vue Test Utils / 其他)以及测什么层级(e2e / 集成 / 单元)由 用户选择 + 项目现有配置 共同决定,详见 Phase 5。
总览
Phase 1 需求文档落盘
↓
Phase 2 互动澄清(AskQuestion 写回文档)
↓
Phase 3 设计参照确认(参照模块 / Figma 链接 / 自行创作)
↓
Phase 4 接口与字段定义(已给 / 预设占位)
↓
Phase 5 测试策略确认(框架 / 类型 / 位置)
↓
Phase 6 代码实现(强制分批 + 用户确认)
↓
Phase 7 自动化测试(e2e / 单元,按 Phase 5 选定的框架)
启动后立刻用 TodoWrite 把上述 7 个阶段建成 todo,全程同步进度。
Phase 1:获取需求文档并落盘
触发:用户提供任意形式的需求文档,包括但不限于:
- 飞书/Lark 链接(公共域名如
feishu.cn/larksuite.com,或企业文档平台给出的官方链接等) - 项目内已有的 Markdown / PRD 文件路径
- 用户在对话中直接粘贴的需求描述文字
- Figma 设计稿链接(含需求说明)
- 其他网页链接 / PDF / 图片等
步骤:
- 通过 AskQuestion 询问:文档应该放在哪个 docs 目录? (给出几个常见选项,例如:
src/views/<模块>/docs/、docs/、用户自定义) - 按需求来源分支 获取原文:
- 飞书/Lark 链接 → 用可用的 Lark/飞书类 MCP 或官方导出能力读取全文(以当前环境已配置的 MCP 为准)
- 项目内 Markdown / PRD 文件 → 用 Read 工具读取
- 用户直接粘贴的文字 → 直接使用对话中的内容
- Figma 链接 → 用 Figma MCP 的
get_design_context获取(同时可作为 Phase 3 设计稿来源) - 其他网页 → 用 WebFetch 抓取
- 在指定目录下新建 Markdown 文件,文件名建议
<需求英文短名>-requirement.md - 按以下骨架填充(关键章节先占位,后续 Phase 填):
markdown
# {需求名称}
> 需求来源:{原始链接 / 文件路径 / "用户对话直接提供"}
> 同步时间:{YYYY-MM-DD}
## 一、需求概览(3-5 句话)
...
## 二、原文摘录(关键内容,非全文复制)
...
## 三、待确认问题
- [ ] 问题 1
- [ ] 问题 2
## 四、参照模块 / 设计稿
(Phase 3 填充)
## 五、接口与字段定义
(Phase 4 填充)
## 六、测试策略
(Phase 5 填充:测试框架、测试类型、文件位置、测试场景)
## 七、实现拆解
(Phase 6 填充)
完成后展示文档路径给用户,再进入 Phase 2。不要在此阶段输出大段需求总结正文给用户,所有内容写进文档即可。
Phase 2:互动澄清(AskQuestion 驱动,结果回写文档)
强制要求 :所有需要用户回答的"选择题/不明确点"必须用 AskQuestion 工具,禁止用普通对话列 1/2/3 让用户回。
步骤:
- 扫描文档,列出所有歧义点 / 模糊处 / 边界场景缺失项,写入「三、待确认问题」
- 通过 AskQuestion 分批 询问(每批不超过 5 个),优先级:
- 阻塞实现的核心规则(如唯一性、必填、互斥)
- 交互细节(弹窗 vs 抽屉 / 二次确认 / Loading)
- 数据校验(长度 / 正则 / 重复检测)
- 权限粒度(不同角色看到/操作什么)
- 边界场景(空数据 / 极端数据 / 网络异常 / 并发)
- 收到回答后立即将答案合并到文档对应章节(不要等到全部问完才回写)
- 把已解决的
- [ ]勾掉,继续下一批,直到没有歧义
Phase 3:设计参照确认
通过 AskQuestion 问一个三选一分支问题:
本次实现的设计来源是?
- A. 参照项目内现有模块(无需 Figma)
- B. 有 Figma 设计稿(请提供链接)
- C. 两者都没有,自行创作(按项目设计系统/已有风格创作)
分支 A:参照现有模块
- 追问参照哪个模块(用 AskQuestion 给出项目内典型模块作为选项;如无明显候选可让用户输入路径)
- 在文档「四、参照模块 / 设计稿」记录:
- 参照模块名 + 文件路径
- 维度对齐对比表(路由 / 菜单 / 权限 / API / 列表页 / 编辑页 / 状态枚举)
分支 B:有 Figma 链接
- 阻塞等待用户提供 Figma 链接(
figma.com/design/...等) - 拿到链接后写入「四、参照模块 / 设计稿」
- ⚠️ Phase 6 代码实现时必须 用 Figma MCP 的
get_design_context(fileKey + nodeId 从该链接解析)获取设计上下文,再开始写代码
分支 C:自行创作(必须遵循系统风格)
核心铁律 :自由度高 ≠ 可以随意发挥。必须先扫描并对齐项目已有风格,再开始设计。
C.1 扫描项目设计系统(强制前置)
进入 Phase 6 之前必须完成以下扫描,把结论写进文档「四、参照模块 / 设计稿」:
| 扫描维度 | 找什么 | 怎么找 |
|---|---|---|
| 设计 Token | CSS 变量、颜色/字号/间距/圆角/阴影 | 全局样式 / :root / 设计 Token 文件(以项目为准) |
| 通用组件 | 弹窗 / 下拉 / 表格 / 表单 / Popover | 组件库目录或业务封装组件目录 |
| 图标体系 | 项目统一图标用法 | src/assets/、src/icons/ 等(以项目为准) |
| 布局范式 | 列表页骨架、表单页骨架、抽屉骨架 | 同业务域内现有页面 |
| 交互范式 | 危险二次确认、Loading、空状态、分页样式 | 现有同类页面 |
| 文案风格 | 按钮文字 / 表头 / 提示语调("确认 / 取消 / 删除") | 现有页面 |
C.2 找一个"风格最近邻"作为隐式参照
即便没有官方参照模块,也要从项目里挑一个业务最相近的页面作为视觉/交互范本。在文档中记录:
markdown
## 四、参照模块 / 设计稿(自行创作 --- 隐式参照)
- **隐式参照模块**:`src/views/xxx/YyyList.vue`(理由:与本需求交互模式最接近)
- **沿用的设计 Token**:颜色 / 间距等(列出实际使用的 CSS 变量名)
- **沿用的通用组件**:列出项目内封装组件名
- **自创部分**:仅 XXX 区块(说明为何不能复用现有范式)
C.3 提交设计草案让用户预审
在动手写代码前,先用结构化文字描述设计方案(不要直接写代码),通过 AskQuestion 让用户确认:
- 页面骨架(顶部筛选 + 表格 + 分页 / 左导航 + 右内容 / 卡片网格 等)
- 关键交互流(创建走抽屉还是弹窗?删除是否二次确认?)
- 状态展示(Tag 颜色映射、空状态文案)
- 风险点(任何无法直接套用现有范式的地方)
用户确认后才进入 Phase 4 / Phase 6。
C.4 创作禁区(绝不要做)
- ❌ 引入项目里没有的颜色(应先在全局 Token / 主题中扩展,再在业务中使用)
- ❌ 绕过既有设计系统自造一整套基础控件(应优先复用项目封装)
- ❌ 与项目图标规范冲突的用法(以项目规则为准)
- ❌ 行内
style=写样式(除非项目规则明确允许动态样式) - ❌ 复制网上抄来的 UI 风格混搭进项目
Phase 4:接口与字段定义
通过 AskQuestion:
接口文档是否已经提供?
- A. 已提供(用户粘贴/给链接)
- B. 暂无(先用预设字段名占位,待后端给接口后再调整)
分支 A:已有接口文档
解析接口文档,在「五、接口与字段定义」按下表整理:
| 接口 | 方法 | URL | 入参字段 | 出参字段(含类型/含义) |
|---|
后续代码直接按此表对接,不再自行编字段。
分支 B:接口暂无 --- 生成占位定义区
⚠️ 这是核心机制。生成一个显眼的占位区,让后续接口给出后可整体替换:
markdown
## 五、接口与字段定义(⚠️ 待接口文档确认)
### 实体:Xxx(前端预设)
| 字段名(预设) | 类型 | 含义 | 备注 |
| -------------- | ------ | -------- | ------ |
| id | string | 主键 | 待确认 |
| name | string | 名称 | 待确认 |
| status | number | 状态枚举 | 待确认 |
| createTime | string | 创建时间 | 待确认 |
| ... | | | |
### 接口(前端预设)
- 列表:`POST /xxx/list` --- 入参:`{ page, size, keyword }` --- 出参:`{ list: Xxx[], total }`
- 创建:`POST /xxx/create` --- 入参:`{ name, ... }` --- 出参:`{ id }`
- 编辑:`POST /xxx/edit` --- 入参:`{ id, name, ... }`
- 删除:`POST /xxx/delete` --- 入参:`{ id }`
> ⚠️ 上述字段名与接口路径均为前端预设,等接口文档给出后**全文替换**。
> 代码中所有 mock 接口与字段引用,都应能通过搜索字段名/路径一次性替换。
代码实现阶段,所有字段引用都走这套预设,方便后期一次性替换。
Phase 5:测试策略确认(框架 / 类型 / 位置)
核心原则 :测试方案 = 项目现有配置 ∩ 用户偏好,不预设任何框架。
5.1 探测项目现有测试栈
先用 Glob / Read 探测项目里已经存在的测试基础设施:
| 探测目标 | 典型证据 |
|---|---|
| Cypress | cypress.config.{js,ts} / cypress/ 目录 / package.json 含 cypress 依赖 |
| Playwright | playwright.config.{js,ts} / e2e/ 或 tests/ 目录 / @playwright/test |
| Vitest | vitest.config.{js,ts} / vitest 在 devDependencies |
| Jest | jest.config.{js,ts} / __tests__/ / *.test.js |
| Vue Test Utils | @vue/test-utils 在 devDependencies |
| 其他 | Mocha、Karma、Testing Library 等 |
把探测结果作为 AskQuestion 的默认推荐选项。
5.2 通过 AskQuestion 让用户确认 3 件事
问题 1:测试类型?(允许多选)
- A. 端到端测试(e2e,覆盖完整用户路径)
- B. 集成 / 组件测试(挂载组件验证交互)
- C. 单元测试(纯函数 / utils / store / composable)
- D. 不写自动化(明确跳过 Phase 7)
问题 2:使用什么测试框架?
按 5.1 探测结果列出项目已有的框架作为优先选项;如果项目里都没有,再让用户选择新引入哪个。
问题 3:测试文件放在哪里?
按选定框架的项目约定给出候选路径,例如:
- e2e:
cypress/e2e/xxx.cy.js/tests/e2e/xxx.spec.ts/e2e/xxx.spec.ts - 单元:
src/**/__tests__/xxx.spec.ts/tests/unit/xxx.spec.js
5.3 写入需求文档
把上述 3 个回答写入文档「六、测试策略」章节:
markdown
## 六、测试策略
- **测试类型**:e2e / 单元 / 两者都有
- **测试框架**:Cypress 14 / Vitest 1.x / ...
- **文件位置**:cypress/e2e/xxx.cy.js(e2e),src/views/xxx/**tests**/(单元)
- **测试场景**(用户提供或后续补充):
- 场景 1:...
- 场景 2:...
重点 :本阶段只确认策略 + 把信息写入文档 ,不立即写测试代码。测试代码统一在 Phase 7 完成。
Phase 6:代码实现(强制分批,绝不一次性完成)
铁律:永远不要一次把所有代码改完。必须分批 + checkpoint,每一批让用户确认后再继续。
6.1 拆解任务并建 TodoWrite
按以下粒度拆 todo(粒度尽量小):
- 单个文件 / 单个组件 / 单个 API 模块为一批
- 多文件改动按 「常量定义 → API 层 → 单组件 → 子组件 → 集成 → 路由/菜单接入」 顺序拆
- 把拆解结果写入需求文档「七、实现拆解」章节
6.2 Figma 分支预处理
如果 Phase 3 选了 B(要 Figma):
- 进入 6.3 前,先调 Figma MCP 的
get_design_context(fileKey + nodeId 从需求文档中记录的链接解析) - 把设计稿与项目内已有设计系统 / 业务组件做映射
- 然后再按 6.3 分批实现
6.3 执行策略(每个 todo 一个循环)
- 把下一个 todo 标
in_progress - 只完成这一个 todo 涉及的文件改动
- 改完立即调 ReadLints 自查 lint
- 主动暂停 ,向用户报告:
- 这一批做了什么
- 涉及哪些文件
- 是否有需要用户决策的点
- 显式说:"请确认 OK 后我再继续下一批"
- 等用户确认 后才标
completed并启动下一个 todo
严禁连续做完 3 个以上 todo 才暂停。
6.4 项目规范自查清单(每批都过)
- Vue / 前端框架规范 :以当前仓库
.cursor/rules/、CONTRIBUTING、或 README 中针对 Vue 2 / Vue 3 / 其他栈 的约定为准,实现前对齐版本与风格(Composition API / Options API 等)。 - 定义注释规范 :若项目规则要求,则为每个
ref / reactive / computed / const / 箭头函数 / data 属性 / methods / api function等补充简洁说明(字数与格式以项目规则为准)。 - 统一组件与样式:弹窗、表单控件、图标、主题色等一律遵循项目既有封装与设计 Token,禁止与全局规范冲突的「另起炉灶」。
- 危险操作(删除/结束/暂停/冻结等):按项目要求做二次确认,勿静默执行不可逆操作。
- API 错误提示:若全局拦截器已统一提示,业务层避免重复弹同一类错误,以免打扰用户。
- 可测试性属性 (Phase 5 选了 e2e/集成测试时必加):所有交互元素打上项目约定的稳定测试属性(如
data-cy/data-test/data-testid),命名使用 kebab-case。 - 可测试性结构 (Phase 5 选了单元测试时):纯逻辑尽量抽到
utils/或 composable,避免深埋于单文件组件内难以单测。
Phase 7:自动化测试(按 Phase 5 选定的方案落地)
只在所有代码批次完成 + 用户最终确认通过后启动。如果 Phase 5 选了 "D. 不写自动化",直接跳过本阶段并告知用户。
7.1 通用步骤(不分框架)
- 把 Phase 5 收集的测试场景中可自动化的部分识别出来
- 不可自动化(纯视觉对比 / 跨域第三方页面 / 真实支付 / 等待真实异步几分钟)的,明确告知用户跳过并说明原因
- 在 Phase 5 指定的测试文件路径下写测试用例
- 测试代码同样分批写:一个测试文件 / 一个 describe 一次,写完跑通后再写下一个
7.2 按框架适配
按 Phase 5 选定的框架自动套用对应规范:
e2e 类(Cypress / Playwright)通用要点:
- 选择器优先稳定的
data-cy / data-test / data-testid,禁止脆弱 CSS(nth-child、长 ID 链) - 等待网络请求用拦截 + 别名,禁止 硬编码
wait(数字毫秒)- Cypress:
cy.intercept+cy.wait('@alias') - Playwright:
page.waitForResponse(/url/)
- Cypress:
- 绕过 UI 登录:按项目文档或测试基建 约定注入会话(localStorage / sessionStorage / cookie 等),禁止在仓库中硬编码真实账号密码或长期有效的密钥
- 用相对路径访问页面,禁止硬编码域名,由配置的 baseURL 提供
- 断言用强断言(
should('be.visible')/toBeVisible())而非仅检查存在 - 若仓库已有 e2e 测试规范文档(如
*.mdc或docs/下说明),严格遵循
单元 / 组件类(Vitest / Jest / Vue Test Utils)通用要点:
- 优先测纯函数 和逻辑分支,UI 渲染快照不主测
- 组件测试用
mount/shallowMount,外部依赖(API / store / router)全 mock - 异步逻辑必须
await flushPromises()或等到状态稳定再断言 - 命名清晰:
describe('XxxList', () => { it('在加载完成后渲染表格行', ...) }) - 单测覆盖率不追求 100%,覆盖核心业务逻辑 + 边界条件即可
7.3 兜底
如果项目从未配置过测试框架,且 Phase 5 让你"新引入"某框架:
- 先增量安装依赖、加最小配置文件(
vitest.config.ts或cypress.config.js等) - 配置和首个测试用例分开两个 todo 提交,每步暂停等用户确认
- 给出运行命令(如
pnpm test:unit/pnpm cypress open)让用户能本地验证
跨阶段强约束
| 约束 | 做法 |
|---|---|
| 永远先确认再执行 | Phase 之间显式暂停,不要默认继续 |
| AskQuestion 优先 | 任何需要用户选择的问题都用 AskQuestion,禁止纯文本列选项 |
| 文档单一来源 | 所有澄清结果回写需求文档;不要让信息散落在对话里 |
| TodoWrite 全程同步 | 从 Phase 1 启动到 Phase 7 完成,TodoWrite 状态实时更新 |
| 小步快跑 | 每批改动小到可单独 revert,便于用户随时退回 |
| 中文交流 | 与用户的所有沟通、文档内容、注释一律中文(若项目另有语言要求则从其约定) |
反模式(绝不要做)
- ❌ 一上来就写代码(没读需求来源 / 没确认需求 / 没问 Figma)
- ❌ 用纯文本「请回答:1. xxx 2. xxx 3. xxx」(应该用 AskQuestion)
- ❌ Phase 6 一次性改完 8 个文件后说"都做完了,看看吧"(应该分批 + checkpoint)
- ❌ 接口字段直接编 / 直接调用未确认的接口路径(应该走 Phase 4 占位机制)
- ❌ 跳过 Phase 5 直接在 Phase 7 才问测试用例放哪里
- ❌ 不看项目现有测试栈,强行引入新框架(应优先复用项目已有的)
- ❌ 在测试代码里硬编码等待时间(
cy.wait(5000)/page.waitForTimeout(5000))或用nth-child脆弱选择器 - ❌ 把澄清问题攒一波只问一次(应分批;每批不超过 5 个)
启动 Checklist(接到任意形式的需求文档后立刻做)
复制以下 checklist 作为 TodoWrite 初始内容:
css
- [ ] Phase 1:确认 docs 目录 → 按来源获取原文(飞书/文件/粘贴/Figma/网页)→ 落盘需求文档骨架
- [ ] Phase 2:用 AskQuestion 分批澄清歧义点 → 回写需求文档
- [ ] Phase 3:确认参照模块 OR Figma 链接 OR 自行创作(强制扫描项目风格)→ 写入文档
- [ ] Phase 4:确认接口文档 OR 生成预设字段占位区 → 写入文档
- [ ] Phase 5:探测项目测试栈 → AskQuestion 确认测试类型/框架/位置 → 写入文档
- [ ] Phase 6:分批实现代码(每批暂停等用户确认)
- [ ] Phase 7:按 Phase 5 选定方案写自动化测试(e2e / 单元,分批)
附:github仓库地址: github.com/x-y-17/my-s...