Merge pull request 'sync: d8d-dev 结构重构为 modes/phases/rules 子目录 + journey 子模式拆分' (#49) from sync/d8d-skills-20260419-103101 into master

Reviewed-on: http://gitea.d8d.fun/d8dfun/bmad-method-template/pulls/49
This commit is contained in:
2026-04-19 11:53:58 +00:00
19 changed files with 536 additions and 419 deletions

View File

@@ -0,0 +1,172 @@
# 旅程定义
> 旅程模式子模式 1为所有 Epic 生成/重写用户旅程文件。
## 流程
```
1. 读取 PRD + Epic/Story 定义 + sprint-status.yaml
2. 读取入口配置:
- 小程序: 参见 ../../reference/platform-uni-app.md §4入口页面 = pages.json 第一个 page
- 管理后台: app/admin/src/app/ 路由结构(根 URL = 自然入口)
3. 为每个 Epic 生成/重写 epic-N-journeys.md
- 严格遵循旅程真实性规则(⛔ 见 ../../rules/journey-authenticity-rules.md
- 使用增强版旅程格式
3.2 生成后自检(⛔ 强制)
**Read fully and follow: ../../rules/journey-authenticity-rules.md**
- 读取刚生成的旅程文件 + 对应页面源码
- 按规则 R1-R5 逐条校验
- 违规 → 自动修复 → 重新校验max 3x
3.5 覆盖度评估FR 追踪矩阵交叉检查):
a. 读取 `03-epics-and-stories.md` 的 "FR 覆盖追踪矩阵" 表格
b. 读取所有 `epic-N-journeys.md` 中每条旅程涉及的技术验证步骤
c. 逐一比对:每个 FR 是否被至少 1 条旅程的验收标准或技术验证步骤覆盖
d. 计算 FR 覆盖率 = 已覆盖 FR 数 / 总 FR 数
e. 覆盖度门控:
- 100% → ✅ PASS
- 80-99% → ⚠️ WARN列出未覆盖 FR建议补充旅程
- <80% → ❌ FAIL必须补充旅程后才能进入验证子模式
f. 输出覆盖度报告到 `_bmad-output/implementation-artifacts/journey-coverage-report.md`
3.6 组件级覆盖校验(⛔ 强制 — FR 检查通过后必须执行):
⛔ 目的FR 级检查是二值判断("提到就算覆盖"),无法发现"1 步路过式覆盖"的问题。
此步骤深入到组件交互元素粒度,确保每个用户可操作的元素都被旅程验证。
a. 识别应用的所有主要视图/页面:
- 从 app-client.tsx 或路由配置提取视图列表(如 batch-list / batch-dashboard / batch-results
- 从 src/app/ 目录结构提取独立页面路由
b. 对每个主要视图,读取对应组件源码,提取所有用户交互元素:
- 按钮: onClick / handleClick / button 元素
- 输入框: input / textarea / type="text"
- 下拉选择: select / dropdown / combobox / Select 组件
- 筛选器/过滤器: filter / 筛选
- 分页控件: page / pagination / nextPage / setPage
- 导出/下载: export / download / csv / excel
- 对话框/弹窗: dialog / modal / open / close
c. 比对交互元素 vs 所有旅程的技术验证步骤:
- 每个交互元素必须被至少 1 条旅程的某个步骤覆盖
- 计算每个组件的覆盖深度 = 被旅程步骤覆盖的交互元素数 / 总交互元素数
d. 覆盖深度门控(⛔ 100% 覆盖强制 — 任何缺口必须自动补旅程):
| 组件交互元素数 | 最低覆盖要求 | 不满足时 |
|--------------|-------------|---------|
| 1-2 个 | 至少 1 步涉及 | ❌ FAIL → 自动补旅程 |
| 3-5 个 | 至少 1 条旅程含 ≥2 步专门操作该视图 | ❌ FAIL → 自动补旅程 |
| ≥6 个 | 必须有 1 条专门旅程(以该视图为主场景) | ❌ FAIL → 自动补旅程 |
| 任何数量 | 每个交互元素必须被覆盖 | 未覆盖元素 → 自动补到已有旅程或新建旅程步骤 |
e. 输出组件覆盖矩阵到覆盖度报告:
| 组件 | 交互元素数 | 被覆盖数 | 覆盖深度 | 旅程来源 | 状态 |
|------|-----------|---------|---------|---------|------|
f. 门控汇总(⛔ 100% 强制 — 无 WARN只有 PASS 或自动补):
- 所有组件所有交互元素 100% 覆盖 → ✅ PASS
- 有任何交互元素未被覆盖 → ❌ FAIL → 自动补充旅程步骤(见下方 g
g. 自动补旅程流程(⛔ 强制 — FAIL 后必须执行):
1. 列出所有未覆盖的交互元素(组件名 + 元素名 + 元素类型)
2. 判断补充策略:
a. 已有同视图的专门旅程 → 在该旅程中追加步骤覆盖缺失元素
b. 无同视图专门旅程 → 新建一条旅程,以该视图为主场景
3. 生成旅程步骤内容:
- 用户视角步骤: 从自然导航入口到操作该元素的完整路径
- 技术验证步骤: browser_click/type/select + 验证 API 调用
- 验收标准: 元素可交互且产生预期效果
4. 遵循旅程真实性规则 R1-R8⛔ 必须通过校验)
5. 写入对应 Epic 的旅程文件
6. 更新覆盖度报告的组件覆盖矩阵
7. 重新执行步骤 3.6.a-f 校验max 3 次)
8. 3 次后仍有未覆盖元素 → ❌ FAIL + 输出详细报告
4. 输出: "已生成/重写 N 个 Epic 旅程文件 + FR 覆盖率 X% + 组件覆盖率 Y%"
```
### ⛔ 用户旅程真实性原则
**必须严格遵守,违反 = 旅程无效 = 不许进入验证**
详细检测方法和自动修复策略见 **../../rules/journey-authenticity-rules.md**(统一规则集 R1-R5
**规则 1起始页必须是自然入口**
- 小程序:起始页 = 用户打开网址后看到的第一个页面(参见 ../../reference/platform-uni-app.md §4 入口页面)
- 管理后台:起始页 = 根 URL `/`(通常重定向到登录或 Dashboard
-`browser_navigate("/pages/login/index")` — 用户不会直接输入登录页 URL
-`browser_navigate("http://mini-xxx.dev.d8d.fun/")` — 用户打开网址看到首页
**规则 2操作路径必须可发现**
- 每一步操作必须是用户"看得见、点得到"的
- 必须描述用户**看到什么 → 做什么操作**
- ❌ "用户进入局头申请页"(怎么进去的?没写)
- ✅ "用户点'我的'Tab → 看到'申请成为局头'按钮 → 点击进入申请页"
**规则 3前置条件必须明确且可验证**
- 每个旅程必须写明"操作前系统/用户应处于什么状态"
- ❌ "用户提交申请"(什么用户?什么状态?)
- ✅ "前置:用户已登录(有 token且 organizer=null无局头身份"
**规则 4数据断言必须具体**
- 每个断言必须是可量化、可比较的
- ❌ "登录成功返回 JWT token"(太宽泛,任何返回都算通过)
- ✅ "用户 A 登录后返回的 userId ≠ 用户 B 登录后的 userId"
- ❌ "申请提交成功"(只检查 HTTP 200
- ✅ "申请前 organizer=null申请后 organizer.status=PENDING"
**规则 5跨越页面必须连续导航**
- 页面跳转必须通过用户操作触发(点击/提交),不得 `browser_navigate` 直接跳转
-`browser_navigate("/pages/organizer-apply/index")`
- ✅ 用户点击"申请成为局头"按钮 → 页面跳转到申请页
### 增强版旅程定义格式
```markdown
# Epic N 用户旅程
## 旅程 1: {名称}
- **起始页**: {自然入口 URL}
- **前置条件**: {用户状态、系统状态、数据状态}
- **跨越页面**: {涉及的页面列表}
### 用户视角步骤
1. 用户打开 {URL} → 看到 {首页/落地页}
2. 用户点击 {元素} → 跳转到 {页面}
3. 用户在 {页面} 看到 {内容} → 点击/填写 {操作}
4. ...
5. 用户最终看到 {结果}
### 技术验证步骤
1. {验证页面渲染}(无空白/404/错误)
2. {验证 API 调用}(具体的请求和响应断言)
3. {验证数据状态变化}(操作前 vs 操作后)
4. ...
### 数据状态变化
| 阶段 | 状态 |
|------|------|
| 操作前 | {状态快照} |
| {步骤N}后 | {状态变化} |
| 最终 | {预期最终状态} |
### 验收标准
- [ ] {具体可量化的断言1}
- [ ] {具体可量化的断言2}
- [ ] {全程使用自然导航路径}
```
### 旅程来源优先级
1. **PRD 用户场景**(最高优先级) — PRD 中描述的用户故事和使用场景
2. **Epic/Story 验收标准组合** — 多个 Story 的验收标准串联成完整流程
3. **已实现的路由/导航逻辑** — 从代码中提取的页面跳转关系
### 最低覆盖要求
- 每个非基础设施 Epic 至少 1 条旅程
- 纯基础设施 Epic如 Epic 0可豁免
- 每条旅程必须跨越至少 2 个页面
- 每条旅程必须包含至少 1 个数据状态变化

View File

@@ -1,289 +1,12 @@
# 旅程模式
# 旅程执行模板
> 专用用户旅程定义与验证模式。与验证模式并行,聚焦"真实用户行为"而非"功能点存在性"
## 为什么需要旅程模式
**用户旅程 ≠ 单元测试 ≠ Story 级验证**。
| 维度 | Story 验证 | 用户旅程 |
|------|-----------|---------|
| 目标 | 验证功能点存在且正确 | 验证用户能完成目标 |
| 入口 | 直接 navigate 到目标页面 | 从用户自然入口开始 |
| 范围 | 单个功能点 | 跨页面完整流程 |
| 断言 | API 返回 200 | 数据状态变化符合预期 |
| 失败模式 | "功能不存在" | "用户找不到入口/流程断了" |
Story 验证全部通过 ≠ 用户能正常使用系统。旅程模式弥补这个盲区。
## 旅程模式入口
用户选择"旅程模式"后,询问子模式:
1. **旅程定义** — 为所有 Epic 生成/重写 `epic-N-journeys.md`
2. **旅程验证** — 按真实用户行为执行每个 Epic 的旅程
## 子模式 1旅程定义
### 流程
```
1. 读取 PRD + Epic/Story 定义 + sprint-status.yaml
2. 读取入口配置:
- 小程序: 参见 ./reference/platform-uni-app.md §4入口页面 = pages.json 第一个 page
- 管理后台: app/admin/src/app/ 路由结构(根 URL = 自然入口)
3. 为每个 Epic 生成/重写 epic-N-journeys.md
- 严格遵循旅程真实性规则(⛔ 见 ./journey-authenticity-rules.md
- 使用增强版旅程格式
3.2 生成后自检(⛔ 强制)
**Read fully and follow: ./journey-authenticity-rules.md**
- 读取刚生成的旅程文件 + 对应页面源码
- 按规则 R1-R5 逐条校验
- 违规 → 自动修复 → 重新校验max 3x
3.5 覆盖度评估FR 追踪矩阵交叉检查):
a. 读取 `03-epics-and-stories.md` 的 "FR 覆盖追踪矩阵" 表格
b. 读取所有 `epic-N-journeys.md` 中每条旅程涉及的技术验证步骤
c. 逐一比对:每个 FR 是否被至少 1 条旅程的验收标准或技术验证步骤覆盖
d. 计算 FR 覆盖率 = 已覆盖 FR 数 / 总 FR 数
e. 覆盖度门控:
- 100% → ✅ PASS
- 80-99% → ⚠️ WARN列出未覆盖 FR建议补充旅程
- <80% FAIL必须补充旅程后才能进入验证子模式
f. 输出覆盖度报告到 `_bmad-output/implementation-artifacts/journey-coverage-report.md`
3.6 组件级覆盖校验(⛔ 强制 — FR 检查通过后必须执行):
⛔ 目的FR 级检查是二值判断("提到就算覆盖"),无法发现"1 步路过式覆盖"的问题。
此步骤深入到组件交互元素粒度,确保每个用户可操作的元素都被旅程验证。
a. 识别应用的所有主要视图/页面:
- 从 app-client.tsx 或路由配置提取视图列表(如 batch-list / batch-dashboard / batch-results
- 从 src/app/ 目录结构提取独立页面路由
b. 对每个主要视图,读取对应组件源码,提取所有用户交互元素:
- 按钮: onClick / handleClick / button 元素
- 输入框: input / textarea / type="text"
- 下拉选择: select / dropdown / combobox / Select 组件
- 筛选器/过滤器: filter / 筛选
- 分页控件: page / pagination / nextPage / setPage
- 导出/下载: export / download / csv / excel
- 对话框/弹窗: dialog / modal / open / close
c. 比对交互元素 vs 所有旅程的技术验证步骤:
- 每个交互元素必须被至少 1 条旅程的某个步骤覆盖
- 计算每个组件的覆盖深度 = 被旅程步骤覆盖的交互元素数 / 总交互元素数
d. 覆盖深度门控(⛔ 100% 覆盖强制 — 任何缺口必须自动补旅程):
| 组件交互元素数 | 最低覆盖要求 | 不满足时 |
|--------------|-------------|---------|
| 1-2 个 | 至少 1 步涉及 | ❌ FAIL → 自动补旅程 |
| 3-5 个 | 至少 1 条旅程含 ≥2 步专门操作该视图 | ❌ FAIL → 自动补旅程 |
| ≥6 个 | 必须有 1 条专门旅程(以该视图为主场景) | ❌ FAIL → 自动补旅程 |
| 任何数量 | 每个交互元素必须被覆盖 | 未覆盖元素 → 自动补到已有旅程或新建旅程步骤 |
e. 输出组件覆盖矩阵到覆盖度报告:
| 组件 | 交互元素数 | 被覆盖数 | 覆盖深度 | 旅程来源 | 状态 |
|------|-----------|---------|---------|---------|------|
f. 门控汇总(⛔ 100% 强制 — 无 WARN只有 PASS 或自动补):
- 所有组件所有交互元素 100% 覆盖 → ✅ PASS
- 有任何交互元素未被覆盖 → ❌ FAIL → 自动补充旅程步骤(见下方 g
g. 自动补旅程流程(⛔ 强制 — FAIL 后必须执行):
1. 列出所有未覆盖的交互元素(组件名 + 元素名 + 元素类型)
2. 判断补充策略:
a. 已有同视图的专门旅程 → 在该旅程中追加步骤覆盖缺失元素
b. 无同视图专门旅程 → 新建一条旅程,以该视图为主场景
3. 生成旅程步骤内容:
- 用户视角步骤: 从自然导航入口到操作该元素的完整路径
- 技术验证步骤: browser_click/type/select + 验证 API 调用
- 验收标准: 元素可交互且产生预期效果
4. 遵循旅程真实性规则 R1-R8⛔ 必须通过校验)
5. 写入对应 Epic 的旅程文件
6. 更新覆盖度报告的组件覆盖矩阵
7. 重新执行步骤 3.6.a-f 校验max 3 次)
8. 3 次后仍有未覆盖元素 → ❌ FAIL + 输出详细报告
4. 输出: "已生成/重写 N 个 Epic 旅程文件 + FR 覆盖率 X% + 组件覆盖率 Y%"
```
### ⛔ 用户旅程真实性原则
**必须严格遵守,违反 = 旅程无效 = 不许进入验证**。
详细检测方法和自动修复策略见 **./journey-authenticity-rules.md**(统一规则集 R1-R5
**规则 1起始页必须是自然入口**
- 小程序:起始页 = 用户打开网址后看到的第一个页面(参见 ./reference/platform-uni-app.md §4 入口页面)
- 管理后台:起始页 = 根 URL `/`(通常重定向到登录或 Dashboard
- ❌ `browser_navigate("/pages/login/index")` — 用户不会直接输入登录页 URL
- ✅ `browser_navigate("http://mini-xxx.dev.d8d.fun/")` — 用户打开网址看到首页
**规则 2操作路径必须可发现**
- 每一步操作必须是用户"看得见、点得到"的
- 必须描述用户**看到什么 → 做什么操作**
- ❌ "用户进入局头申请页"(怎么进去的?没写)
- ✅ "用户点'我的'Tab → 看到'申请成为局头'按钮 → 点击进入申请页"
**规则 3前置条件必须明确且可验证**
- 每个旅程必须写明"操作前系统/用户应处于什么状态"
- ❌ "用户提交申请"(什么用户?什么状态?)
- ✅ "前置:用户已登录(有 token且 organizer=null无局头身份"
**规则 4数据断言必须具体**
- 每个断言必须是可量化、可比较的
- ❌ "登录成功返回 JWT token"(太宽泛,任何返回都算通过)
- ✅ "用户 A 登录后返回的 userId ≠ 用户 B 登录后的 userId"
- ❌ "申请提交成功"(只检查 HTTP 200
- ✅ "申请前 organizer=null申请后 organizer.status=PENDING"
**规则 5跨越页面必须连续导航**
- 页面跳转必须通过用户操作触发(点击/提交),不得 `browser_navigate` 直接跳转
- ❌ `browser_navigate("/pages/organizer-apply/index")`
- ✅ 用户点击"申请成为局头"按钮 → 页面跳转到申请页
### 增强版旅程定义格式
```markdown
# Epic N 用户旅程
## 旅程 1: {名称}
- **起始页**: {自然入口 URL}
- **前置条件**: {用户状态、系统状态、数据状态}
- **跨越页面**: {涉及的页面列表}
### 用户视角步骤
1. 用户打开 {URL} → 看到 {首页/落地页}
2. 用户点击 {元素} → 跳转到 {页面}
3. 用户在 {页面} 看到 {内容} → 点击/填写 {操作}
4. ...
5. 用户最终看到 {结果}
### 技术验证步骤
1. {验证页面渲染}(无空白/404/错误)
2. {验证 API 调用}(具体的请求和响应断言)
3. {验证数据状态变化}(操作前 vs 操作后)
4. ...
### 数据状态变化
| 阶段 | 状态 |
|------|------|
| 操作前 | {状态快照} |
| {步骤N}后 | {状态变化} |
| 最终 | {预期最终状态} |
### 验收标准
- [ ] {具体可量化的断言1}
- [ ] {具体可量化的断言2}
- [ ] {全程使用自然导航路径}
```
### 旅程来源优先级
1. **PRD 用户场景**(最高优先级) — PRD 中描述的用户故事和使用场景
2. **Epic/Story 验收标准组合** — 多个 Story 的验收标准串联成完整流程
3. **已实现的路由/导航逻辑** — 从代码中提取的页面跳转关系
### 最低覆盖要求
- 每个非基础设施 Epic 至少 1 条旅程
- 纯基础设施 Epic如 Epic 0可豁免
- 每条旅程必须跨越至少 2 个页面
- 每条旅程必须包含至少 1 个数据状态变化
---
## 子模式 2旅程验证
### 流程
```
1. 读取所有 epic-N-journeys.md
1.5 执行前校验与自动修复(⛔ 强制)
**Read fully and follow: ./journey-authenticity-rules.md**
- 按统一规则 R1-R5 + R7 校验所有旅程文件
- R7 约束一致性校验:对含"可选/可跳过/选填"关键词的步骤grep 对应源码验证逻辑
- 不一致 → 自动修复旅程定义(使其准确反映代码)→ 重新校验
- 违规 → 自动修复旅程文件 → 重新校验max 3x
- 环境适配:读取 pipeline-context.md 确定当前环境,按 R3 适配
1.8 生成步骤级验证清单(⛔ 强制 — 写入 verification-checklist.yaml
- 解析每个旅程的「技术验证步骤」→ 为每个步骤生成 step 条目
- 提取验收标准 → 生成 acceptance_criteria 条目
- 写入/追加到 verification-checklist.yaml 的 journeys 部分:
```yaml
journeys:
epic_N:
journey_M:
name: "{旅程名称}"
steps:
- id: "jN-M-s{S}"
action: "{操作描述}"
expected: "{预期结果}"
screenshot_required: true
screenshot_path: "tests/e2e/screenshots/journey-epicN-M-stepS.png"
analyze_image_required: true
status: "pending"
acceptance_criteria:
- criterion: "{验收标准}"
status: "pending"
```
- 如 verification-checklist.yaml 已存在 → 跳过已 pass 的步骤,从 pending 步骤恢复
2. 询问: 验证全部 Epic 还是指定 Epic?(确定验证范围)
1.9 创建旅程任务清单(⛔ 强制 — 根据范围筛选,每条旅程一个 Task
- 为每条待验证旅程**创建独立的 Task 任务**,使用 `TaskCreate` 工具:
- 每个任务记录Epic 编号、旅程名称、旅程文件路径、前置条件
- 便于独立追踪每条旅程的验证进度
- 避免单个 agent 上下文过大导致污染或遗漏
任务格式示例:
- **主题**: `验证旅程 {旅程名称} (Epic {N})`
- **描述**:
```
执行用户旅程验证:
- Epic: {N}
- 旅程: {旅程名称}
- 文件: {旅程文件路径}
- 前置条件: {前置条件描述}
严格按照 journey-mode.md 执行模板执行完整验证流程。
```
1.10 启动逐个任务验证(每条旅程独立 agent
- 对**每个任务**启动一个**独立的 agent**,按照后续「执行模板」执行验证
- 独立 agent 避免上下文污染,执行更精准
⛔ **强制规则:禁止在主 agent 中一次性串行执行多条旅程**
3. 汇总所有任务结果 → 生成旅程验证报告
4. 更新 pipeline-state.yaml 最终状态
```
---
## 旅程验证核心原则
⛔ **核心原则:每条旅程独立 agent 执行,禁止一次性串行执行所有旅程。**
**最佳实践:每个旅程启动一个独立 agent分批并行执行避免上下文污染和 Playwright MCP 配额超限,执行更精准。**
所有旅程验证任务创建完成后,由独立 agent 按照后续「执行铁律」和「执行模板」依次执行单条旅程的完整验证。
---
## 执行模板(单条旅程验证)
> 单条旅程验证的执行模板。每条旅程由独立 agent 按照此文档执行
```
前置已创建独立任务任务包含Epic 编号、旅程名称、旅程文件路径、前置条件
```
### ⛔ 执行铁律
## ⛔ 执行铁律
**规则 E0定义先行校验⛔ 最高优先级)**
- 执行旅程前必须先校验旅程定义(步骤 1.5
@@ -362,7 +85,7 @@ Story 验证全部通过 ≠ 用户能正常使用系统。旅程模式弥补这
**⛔ 如果以上回退链全部失败且源码无 console.log → FAIL #14 → AUTO-FIX**
(详见 auto-fix-engine.md AUTO-FIX #14)
(详见 ../../rules/auto-fix-engine.md AUTO-FIX #14)
**规则 E4: 数据断言必须使用操作前后的实际值**
```
@@ -376,13 +99,13 @@ Story 验证全部通过 ≠ 用户能正常使用系统。旅程模式弥补这
断言: "有返回就算通过" → 这是 Story 级验证,不是旅程验证
```
### ⛔ 工具选择守卫Tool Selection Guard
## ⛔ 工具选择守卫Tool Selection Guard
**核心原则:用户步骤 = Playwright 工具,数据验证 = Playwright + curl 补充**
旅程验证的本质是**模拟真实用户通过浏览器操作页面**。任何用户可见的操作(点击、填写、导航、查看)都必须通过 Playwright MCP 工具执行。curl 仅用于数据状态的补充验证,绝不替代用户交互。
#### 工具映射表
### 工具映射表
| 步骤类型 | 必须使用的工具 | 禁止使用的工具 | 说明 |
|---------|-------------|-------------|------|
@@ -396,7 +119,7 @@ Story 验证全部通过 ≠ 用户能正常使用系统。旅程模式弥补这
| 保存证据 | browser_take_screenshot | — | ⛔ 每个用户步骤完成后必须截图。filename 必须以 "tests/e2e/screenshots/" 开头且以 ".png" 结尾 |
| 检查网络请求 | browser_network_requests | — | 每条旅程至少 1 次检查 |
#### 禁止行为(⛔ 检测即阻断)
### 禁止行为(⛔ 检测即阻断)
- ❌ 用户步骤中使用 curl 替代 browser_click / browser_type / browser_navigate
- ❌ 用 `curl GET /api/xxx` 替代 browser_snapshot 验证页面内容
@@ -407,10 +130,25 @@ Story 验证全部通过 ≠ 用户能正常使用系统。旅程模式弥补这
- ❌ browser_take_screenshot 的 filename 不以 "tests/e2e/screenshots/" 开头或不以 ".png" 结尾
- ❌ 跳过 browser_network_requests 检查
- ❌ 整条旅程只用 curl 而不用任何 Playwright 工具
- ❌ 两个或以上步骤使用相同的 screenshot_path⛔ 截图路径必须唯一,每步一图 — 每个步骤的 UI 变化不同,截图必须反映差异)
**违反任一项 → 旅程标记 FAIL不得记录为 pass。必须使用 Playwright 重做。**
#### 执行前自检清单
### 交互后验证规则(⛔ 强制 — 每次交互操作后必须执行)
| 操作类型 | 必须验证 | 禁止行为 |
|---------|---------|---------|
| 点击 checkbox/radio/toggle | browser_snapshot 确认 checked/selected 状态变化 | ❌ 只验证 API 返回值不检查 UI |
| 点击提交/发布按钮 | browser_snapshot 确认页面有变化Toast/跳转/列表更新) | ❌ curl POST 200 就标 PASS |
| 点击弹窗按钮(如 Use This Frame | browser_snapshot + browser_take_screenshot 确认弹窗关闭+主界面更新 | ❌ 只检查 API 不截图 |
| 拖动滑块/输入值 | browser_snapshot 确认值已变化 | ❌ 只验证 API 不看 UI |
| 勾选/取消勾选 | browser_snapshot 确认勾选状态 + disabled 状态变化 | ❌ 跳过或标记"不可交互" |
**⛔ 核心原则API 返回值只证明后端处理了请求,不证明前端正确展示了结果。**
任何涉及 UI 变化的操作,必须通过 browser_snapshot + browser_take_screenshot 确认界面实际变化。
curl 只用于补充数据验证(如确认数据库状态),**永远不能替代 UI 验证**。
### 执行前自检清单
执行任何旅程之前AI 必须逐项确认:
@@ -422,13 +160,13 @@ Story 验证全部通过 ≠ 用户能正常使用系统。旅程模式弥补这
6. ✅ browser_take_screenshot 的 filename 格式为 "tests/e2e/screenshots/journey-epic-{N}-{M}-step{S}.png"
7. ✅ 旅程结束时 browser_network_requests
### ⛔ 真实用户完成规则Real User Completion Rule
## ⛔ 真实用户完成规则Real User Completion Rule
**Read fully and follow: ./auto-fix-engine.md 第 3 节"真实用户完成规则"**
**Read fully and follow: ../../rules/auto-fix-engine.md 第 3 节"真实用户完成规则"**
- 核心原则browser_type/click 失败 = Bug → AUTO-FIX禁止 evaluate/run_code 绕过
- browser_type 失败后必须执行 FAIL #6 诊断子步骤(含完整修复流程)
### 执行模板(每条旅程 — 规定式,不得偏离)
## 执行模板(每条旅程 — 规定式,不得偏离)
**执行前必须对照检查清单**(违反 = 错误,必须纠正后继续):
- [ ] `browser_snapshot` = DOM 结构快照(找元素用),**不是**视觉验证
@@ -455,7 +193,7 @@ Story 验证全部通过 ≠ 用户能正常使用系统。旅程模式弥补这
- browser_snapshot → 验证起始页面(⛔ 禁止用 curl GET 替代)
- ⛔ **零交互检查**: 如果 snapshot 显示页面有文字但无任何 button/input/a/form
- 标记步骤 FAIL用户无法从此页面继续操作
- `browser_evaluate` 执行 FAIL #5 诊断(检查 interactiveCount / frameworkMounted — 见 auto-fix-engine.md
- `browser_evaluate` 执行 FAIL #5 诊断(检查 interactiveCount / frameworkMounted — 见 ../../rules/auto-fix-engine.md
- 按诊断结果分流 → AUTO-FIX 或 AUTO-IMPLEMENT
- ⛔ **起始页视觉验证**: browser_take_screenshot → filename: "tests/e2e/screenshots/journey-epic-{N}-{M}-step0.png", type: "png" + analyze_image
- 循环每个用户步骤(步骤编号 S = 1, 2, 3...:
@@ -463,12 +201,12 @@ Story 验证全部通过 ≠ 用户能正常使用系统。旅程模式弥补这
b. browser_click / browser_type / browser_run_code → 执行操作(⛔ 禁止用 curl 替代)
c. browser_wait_for → 等待响应/跳转
d. browser_snapshot → 验证操作结果(⛔ 禁止用 curl GET 替代)
e. ⛔ **视觉验证关卡**(⛔ 强制 — Read fully and follow: ./visual-verification.md
e. ⛔ **视觉验证关卡**(⛔ 强制 — Read fully and follow: ../../rules/visual-verification.md
此关卡为独立步骤,不是子步骤。每个用户步骤完成后必须通过此关卡才能继续。
1. browser_take_screenshot → filename: "tests/e2e/screenshots/journey-epic-{N}-{M}-step{S}.png", type: "png"
2. analyze_image → 使用 visual-verification.md 中的标准提示词
3. 结果记录到 pipeline-state.yaml 的 verification_detail含 analyze_image_executed: true
4. 视觉验证 FAIL → 按分流规则处理(见 auto-fix-engine.md + iron-laws.md 检测即阻断表)
4. 视觉验证 FAIL → 按分流规则处理(见 ../../rules/auto-fix-engine.md + ../../rules/iron-laws.md 检测即阻断表)
5. ⛔ **步骤级跟踪**(每个用户步骤完成后强制执行):
a. 更新 verification-checklist.yaml 对应 step 的 status
b. 追加 step_results 到 pipeline-state.yaml 的 user_journeys:
@@ -506,11 +244,14 @@ Story 验证全部通过 ≠ 用户能正常使用系统。旅程模式弥补这
│ - 检测失败 → **立即重新截图**,不得累积到最后批量修复
│ - 检测通过 → 才允许继续下一步骤
│ - 目的:防止出现"扩展名 .png 但内容是 YAML 文本"的错误
├── G7: screenshot_path_unique — 当前步骤的 screenshot_path 不与同旅程其他步骤重复
│ 检查方式: grep verification-checklist.yaml 同 journey 下所有 step 的 screenshot_path
│ 发现重复 → ❌ FAIL → 自动修正为唯一路径 → 重新截图 → 重新校验 G1-G7
4.5. ⛔ **源码 SVG data URI 扫描**(视觉验证关卡内 — 每次 snapshot 后强制执行):
- Bash: `grep -rn "data:image/svg+xml" app/mini-program/src/`(扫描小程序源码目录)
- 发现匹配 → svg_data_uri_check.found = FOUND → 记录文件列表
- → 按检测即阻断表 "SVG data URI 充当图标/装饰" 条目处理
- → AUTO-IMPLEMENT: 完整安装 Iconify + 替换所有 SVG data URI参见 ./reference/platform-uni-app.md §1
- → AUTO-IMPLEMENT: 完整安装 Iconify + 替换所有 SVG data URI参见 ../../reference/platform-uni-app.md §1
5. ⛔ **视觉验证修复必须内联执行**(不得推迟到步骤 4
- 视觉 FAIL 后,必须在当前关卡内**立即**执行 AUTO-FIX/AUTO-IMPLEMENT
- 修复后重测:重新 browser_take_screenshot + analyze_image 确认问题已修复
@@ -518,7 +259,7 @@ Story 验证全部通过 ≠ 用户能正常使用系统。旅程模式弥补这
- 步骤 4修复阶段仅处理功能断言 FAIL不处理视觉验证 FAIL
f. 如涉及数据变化 → browser_evaluate 或 curl 验证数据(✅ 允许 curl 补充)
6. ⛔ **旅程步骤原型/Pencil 视觉对比验证**(⛔ 强制 — 针对操作时产生的动态状态):
6. ⛔ **旅程步骤原型/Pencil 视觉对比验证**(⛔ 强制 — 针对操作时产生的动态状态)
目的: 捕获并验证操作时才会出现的视觉状态hover、选中、弹窗、展开、加载中、错误提示等这些状态在静态原型对比中无法覆盖
触发条件(满足任一即执行):
@@ -626,7 +367,7 @@ Story 验证全部通过 ≠ 用户能正常使用系统。旅程模式弥补这
触发条件(操作被拦截 + 声明方说"可选":
- 操作后 Toast 出现且含"请上传/请填写/请选择/不能为空/不能为空"
- 且满足以下任一:
a. 旅程定义中该步骤描述含"可跳过/可选/选填/optional/skip/跳过"
a. 旅程定义中该步骤描述含"可跳过/可选/选填/optional/skip/跳过/使用占位图"
b. browser_snapshot 页面文本含"(选填)/(可选)"标记
满足 → Constraint Mismatch (FAIL #16):
- ❌ 不得静默补填继续
@@ -646,16 +387,38 @@ Story 验证全部通过 ≠ 用户能正常使用系统。旅程模式弥补这
- 常见 404 原因:资源路径错误、文件未上传
- 记录到 pipeline-state.yaml 的 `verification_detail.resource_status_check`
3.5 截图覆盖率汇总检查(⛔ 强制 — 每条旅程完成后必须执行):
a. 读取 verification-checklist.yaml 当前 journey 的所有步骤
b. 统计 S_required = screenshot_required: true 的步骤数
c. 统计 S_actual = tests/e2e/screenshots/ 下匹配 journey-epic{N}-{M}-step*.png 的文件数
d. 覆盖率 = S_actual / S_required
e. 门控:
- 100% → ✅ PASS → 继续步骤 4
- < 100% FAIL:
1. 列出缺失截图的步骤 IDS_required 中的路径在 S_actual 中找不到对应文件)
2. 对每个缺失步骤回退执行: browser 操作 → browser_take_screenshot
3. 重新统计覆盖率
4. 仍 < 100% 标记 journey FAIL + 记录缺失步骤到 pipeline-state.yaml
3.6 步骤与技术验证步骤覆盖率门控(⛔ 强制 — 旅程完成后必须执行):
a. 统计旅程定义文件中「技术验证步骤」总数 T_total编号步骤列表
b. 统计实际截取的截图数 S_actualtests/e2e/screenshots/journey-epic-{N}-{M}-step*.png
c. 覆盖率 = S_actual / T_total
d. 门控:
- 100% → ✅ PASS
- < 100% FAIL: 列出缺失步骤回退补截
- 3 次补截后仍 < 100% 旅程标记 FAIL + 记录缺失步骤
4. 修复阶段(⛔ 以下任一条件满足时必须执行,不得跳过):
**Read fully and follow: ./auto-fix-engine.md**
**Read fully and follow: ../../rules/auto-fix-engine.md**
(包含: PASS/FAIL 判定标准 → FAIL 分类表 → 真实用户完成规则 → AUTO-FIX/IMPLEMENT/DATA-FIX 流程 → GATE-CHECK
**触发条件(⛔ 明确化 — 以下任一即触发)**:
- `steps_failed > 0`(功能断言失败)
- `constraint_mismatches` 非空R7 约束不一致检测到 — 即使 steps_passed == steps_executed
- 跨轮次累计的视觉问题 ≥ 1emoji_as_icons / english_enum / broken_images 等 — 检测到即修复)
- 前一次验证的 `pending_fixes` 中有未修复项(⛔ 即使是其他 EPIC 范围的问题,也必须在本轮修复 — 参见 auto-fix-engine.md "已知问题不豁免"规则)
- 前一次验证的 `pending_fixes` 中有未修复项(⛔ 即使是其他 EPIC 范围的问题,也必须在本轮修复 — 参见 ../../rules/auto-fix-engine.md "已知问题不豁免"规则)
- `verification_detail` 中任一检查项为 FOUND 且非设计系统主观视觉评价WARN
**⛔ 禁止的"记录但不修复"模式**:
@@ -684,12 +447,12 @@ Story 验证全部通过 ≠ 用户能正常使用系统。旅程模式弥补这
| 6⃣ | 流水线状态 | `_bmad-output/implementation-artifacts/pipeline-state.yaml``_bmad-output/implementation-artifacts/pipeline-report.md` | `ci(pipeline): update journey verification status` |
- 提交前 `git diff --stat` 确认变更范围
- 排除 `.env``node_modules/``.next/``dist`
- 排除 `.env``node_modules/``.next/``dist/`
- 所有分类提交完成后: `git push origin main`
- 推送失败 → 记录到 error_log不中断
```
### 结果记录格式
## 结果记录格式
```yaml
user_journeys:
@@ -719,36 +482,3 @@ user_journeys:
all_issues_resolved: true # 所有问题是否全部修复
details: "完整执行日志"
```
---
## 与回归验证模式的关系
| 维度 | 回归验证模式 | 旅程验证模式 |
|------|------------|------------|
| 粒度 | 逐 Story | 跨 Story/Epic |
| 目标 | 验证功能点存在且正确 | 验证用户能完成目标 |
| 类比 | 单元测试 | 集成测试/E2E |
| 入口 | 直接 navigate 到目标页面 | 从自然入口开始 |
- 两种模式**独立运行**,互不依赖
- ⛔ **推荐顺序:先回归验证再旅程验证**。功能不存在时测旅程无意义(用户点不到不存在的东西)
- 回归验证全部 PASS 后,建议进入旅程验证模式
## 续跑逻辑
- 读取 `pipeline-state.yaml``user_journeys` 部分
- 已 `pass` 的旅程跳过
- 从第一个非 `pass` 的旅程继续
- **步骤级恢复**(⛔ 增强):
- 读取 `verification-checklist.yaml` → 找到当前旅程中第一个 `status: pending` 的 step
- 读取 `pipeline-state.yaml``step_results` → 确认最后一个已完成步骤
- 从下一个步骤继续执行(跳过已完成的步骤,不重复截图/分析)
- 如无 pending step → 该旅程验证已完成,继续下一个旅程
### 任务级续跑增强(独立任务模式)
如果任务清单已创建:
- 读取所有任务状态,跳过 `status: completed` 的旅程
- 仅对 `status: pending``status: in_progress` 的旅程创建任务并启动验证
- 支持从上次中断处恢复执行

View File

@@ -0,0 +1,75 @@
# 旅程模式
> 专用用户旅程定义与验证模式。与验证模式并行,聚焦"真实用户行为"而非"功能点存在性"。
## 为什么需要旅程模式
**用户旅程 ≠ 单元测试 ≠ Story 级验证**
| 维度 | Story 验证 | 用户旅程 |
|------|-----------|---------|
| 目标 | 验证功能点存在且正确 | 验证用户能完成目标 |
| 入口 | 直接 navigate 到目标页面 | 从用户自然入口开始 |
| 范围 | 单个功能点 | 跨页面完整流程 |
| 断言 | API 返回 200 | 数据状态变化符合预期 |
| 失败模式 | "功能不存在" | "用户找不到入口/流程断了" |
Story 验证全部通过 ≠ 用户能正常使用系统。旅程模式弥补这个盲区。
## 旅程模式入口
用户选择"旅程模式"后,询问子模式:
1. **旅程定义** — 为所有 Epic 生成/重写 `epic-N-journeys.md`
2. **旅程验证** — 按真实用户行为执行每个 Epic 的旅程
### 子模式 1旅程定义
**Read fully and follow: ./journey-definition.md**
为所有 Epic 生成用户旅程文件,包含:
- 从自然入口开始的完整用户操作流程
- FR 覆盖度评估 + 组件级覆盖校验
- 旅程真实性原则 R1-R5 校验
### 子模式 2旅程验证
**Read fully and follow: ./journey-validation.md**
编排并执行每条用户旅程的自动化验证:
- 执行前校验(真实性规则 + [C] 覆盖缺口门控 + 组件交叉校验)
- 每条旅程独立 agent 执行(按 `./journey-execution.md` 执行模板)
- 汇总结果 → 生成验证报告 → 更新 pipeline-state.yaml
---
## 与回归验证模式的关系
| 维度 | 回归验证模式 | 旅程验证模式 |
|------|------------|------------|
| 粒度 | 逐 Story | 跨 Story/Epic |
| 目标 | 验证功能点存在且正确 | 验证用户能完成目标 |
| 类比 | 单元测试 | 集成测试/E2E |
| 入口 | 直接 navigate 到目标页面 | 从自然入口开始 |
- 两种模式**独立运行**,互不依赖
-**推荐顺序:先回归验证再旅程验证**。功能不存在时测旅程无意义(用户点不到不存在的东西)
- 回归验证全部 PASS 后,建议进入旅程验证模式
## 续跑逻辑
- 读取 `pipeline-state.yaml``user_journeys` 部分
-`pass` 的旅程跳过
- 从第一个非 `pass` 的旅程继续
- **步骤级恢复**(⛔ 增强):
- 读取 `verification-checklist.yaml` → 找到当前旅程中第一个 `status: pending` 的 step
- 读取 `pipeline-state.yaml``step_results` → 确认最后一个已完成步骤
- 从下一个步骤继续执行(跳过已完成的步骤,不重复截图/分析)
- 如无 pending step → 该旅程验证已完成,继续下一个旅程
### 任务级续跑增强(独立任务模式)
如果任务清单已创建:
- 读取所有任务状态,跳过 `status: completed` 的旅程
- 仅对 `status: pending``status: in_progress` 的旅程创建任务并启动验证
- 支持从上次中断处恢复执行

View File

@@ -0,0 +1,115 @@
# 旅程验证编排
> 旅程模式子模式 2编排并执行每条用户旅程的自动化验证。
## 旅程验证核心原则
**核心原则:每条旅程独立 agent 执行,禁止一次性串行执行所有旅程。**
**最佳实践:每个旅程启动一个独立 agent分批并行执行避免上下文污染和 Playwright MCP 配额超限,执行更精准。**
所有旅程验证任务创建完成后,由独立 agent 按照后续「执行铁律」和「执行模板」依次执行单条旅程的完整验证。
## 流程
```
1. 读取所有 epic-N-journeys.md
1.5 执行前校验与自动修复(⛔ 强制)
**Read fully and follow: ../../rules/journey-authenticity-rules.md**
- 按统一规则 R1-R5 + R7 校验所有旅程文件
- R7 约束一致性校验:对含"可选/可跳过/选填"关键词的步骤grep 对应源码验证逻辑
- 不一致 → 自动修复旅程定义(使其准确反映代码)→ 重新校验
- 违规 → 自动修复旅程文件 → 重新校验max 3x
- 环境适配:读取 pipeline-context.md 确定当前环境,按 R3 适配
1.6 [C] 覆盖缺口门控(⛔ 强制 — 检查即阻断)
a. grep 所有 epic-N-journeys.md 中的 [C] 标记(差异标注但未覆盖)
b. [C] 计数 > 0 → ❌ FAIL:
- 列出所有未覆盖的交互元素(文件名 + 步骤位置 + [C] 内容)
- 自动补充旅程步骤覆盖缺失元素max 3x
- 补充后重新校验(重新 grep [C]
- 3 次后仍有 [C] → ❌ FAIL + 输出详细报告,阻断验证
c. [C] 计数 = 0 → ✅ PASS → 继续
⛔ 旅程文件中不允许遗留 [C] 标记。[C] 是临时标注,必须在验证前解决。
1.7 组件交互元素交叉校验(⛔ 强制 — 源码 vs 旅程步骤对比)
a. 从旅程定义提取所有「技术验证步骤」涉及的交互元素click/type/upload/navigate
b. 读取对应页面/组件源码,提取所有用户交互元素:
- 按钮: onClick / handleClick / button 元素
- 输入框: input / textarea
- 弹窗/模态框触发: dialog / modal / open
- 文件上传: file upload / input[type=file]
c. 比对: 旅程步骤覆盖的元素 vs 源码中实际存在的交互元素
d. 发现未覆盖的交互元素 → 自动补充旅程步骤max 3x
e. 门控: 100% 覆盖才能进入验证执行
1.8 生成步骤级验证清单(⛔ 强制 — 写入 verification-checklist.yaml
- 解析每个旅程的「技术验证步骤」→ 为每个步骤生成 step 条目
- 提取验收标准 → 生成 acceptance_criteria 条目
- 写入/追加到 verification-checklist.yaml 的 journeys 部分:
```yaml
journeys:
epic_N:
journey_M:
name: "{旅程名称}"
steps:
- id: "jN-M-s{S}"
action: "{操作描述}"
expected: "{预期结果}"
screenshot_required: true
screenshot_path: "tests/e2e/screenshots/journey-epicN-M-stepS.png"
analyze_image_required: true
status: "pending"
acceptance_criteria:
- criterion: "{验收标准}"
status: "pending"
```
- 如 verification-checklist.yaml 已存在 → 跳过已 pass 的步骤,从 pending 步骤恢复
1.8.1 截图路径唯一性与覆盖率校验(⛔ 强制 — checklist 生成后必须执行):
a. 提取当前 journey 下所有步骤的 screenshot_path:
- 过滤 screenshot_required: true 的步骤
- 收集所有 screenshot_path 值
b. 唯一性检查:
- 如发现 N > 1 个步骤共享同一路径 → ❌ FAIL
- 自动修复为每个重复步骤生成独立路径journey-epic{N}-{M}-step{S}-{suffix}.png
- suffix 从步骤 action 描述中提取关键词(如 dashboard / player / cover
- 重新校验max 3x
c. 覆盖率检查:
- browser 交互步骤action 含 click/type/upload/navigate/snapshot必须有 screenshot_required: true
- 发现 browser 步骤为 false → 自动修正为 true + 生成独立路径
d. 门控:
- 100% 唯一 + 100% browser 步骤覆盖 → ✅ PASS
- 否则 → ❌ FAIL → 自动修正 → 重新校验
2. 询问: 验证全部 Epic 还是指定 Epic?(确定验证范围)
1.9 创建旅程任务清单(⛔ 强制 — 根据范围筛选,每条旅程一个 Task
- 为每条待验证旅程**创建独立的 Task 任务**,使用 `TaskCreate` 工具:
- 每个任务记录Epic 编号、旅程名称、旅程文件路径、前置条件
- 便于独立追踪每条旅程的验证进度
- 避免单个 agent 上下文过大导致污染或遗漏
任务格式示例:
- **主题**: `验证旅程 {旅程名称} (Epic {N})`
- **描述**:
```
执行用户旅程验证:
- Epic: {N}
- 旅程: {旅程名称}
- 文件: {旅程文件路径}
- 前置条件: {前置条件描述}
严格按照 journey-execution.md 执行模板执行完整验证流程。
```
1.10 启动逐个任务验证(每条旅程独立 agent
- 对**每个任务**启动一个**独立的 agent**,按照 `./journey-execution.md` 执行模板执行验证
- 独立 agent 避免上下文污染,执行更精准
⛔ **强制规则:禁止在主 agent 中一次性串行执行多条旅程**
3. 汇总所有任务结果 → 生成旅程验证报告
4. 更新 pipeline-state.yaml 最终状态
```

View File

@@ -1,8 +1,8 @@
# 验证模式
> 参见 ./e2e-testing.md 了解 Playwright MCP 测试序列详情。
> 参见 ./iron-laws.md 了解四维验证检查清单。
> 参见 ./auto-fix-engine.md 了解统一修复引擎FAIL分类标准 + 修复流程 + GATE-CHECK
> 参见 ../rules/e2e-testing.md 了解 Playwright MCP 测试序列详情。
> 参见 ../rules/iron-laws.md 了解四维验证检查清单。
> 参见 ../rules/auto-fix-engine.md 了解统一修复引擎FAIL分类标准 + 修复流程 + GATE-CHECK
## 续跑逻辑
@@ -177,7 +177,7 @@ Phase 0V: 批量创建 Task + 读取 Story 规格文档
> 跨 Epic 的用户旅程验证已独立为「旅程验证模式」,不在此模式中执行。
> 回归验证模式只负责逐 Story 功能点验证。完成所有 Story 后建议进入旅程验证模式。
> AUTO-FIX/AUTO-IMPLEMENT/AUTO-DATA-FIX 的完整分类标准和修复流程见 ./auto-fix-engine.md
> AUTO-FIX/AUTO-IMPLEMENT/AUTO-DATA-FIX 的完整分类标准和修复流程见 ../rules/auto-fix-engine.md
```
### 与完整模式的区别
@@ -295,14 +295,14 @@ echo "localhost_fallback=$LOCALHOST_COUNT inline_api=$INLINE_COUNT"
- 全部为 0 → **PASS**
**检查 2: 图标方案合规(小程序/移动端 Story 强制)**
> 完整检测命令和判定规则见 **./reference/platform-uni-app.md 第 6 节**。
> 完整检测命令和判定规则见 **../reference/platform-uni-app.md 第 6 节**。
**判定**
- `tabbar_iconpath_empty=true`**FAIL (未实现)** → AUTO-IMPLEMENT
- mini-program 缺 Tailwind/Iconify → **WARN (未实现)** → AUTO-IMPLEMENT
**检查 3: Emoji 充当功能图标(所有前端强制)**
> 完整检测命令和判定规则见 **./reference/platform-uni-app.md 第 6 节**。
> 完整检测命令和判定规则见 **../reference/platform-uni-app.md 第 6 节**。
**判定**
- `EMOJI_COUNT > 0`**FAIL (未实现)** → AUTO-IMPLEMENT
@@ -320,7 +320,7 @@ echo "localhost_fallback=$LOCALHOST_COUNT inline_api=$INLINE_COUNT"
**⛔ AUTO-FIX/IMPLEMENT 失败阻断**:源码三重检查 AUTO-FIX/AUTO-IMPLEMENT 重试 3 次后仍 FAIL → Story 标记为 `failed`,记录到 `error_log`,继续下一个 Story。不得反复重试或跳过。
> 完整的 AUTO-FIX/IMPLEMENT/DATA-FIX 流程和重试上限见 ./auto-fix-engine.md 第 4 节
> 完整的 AUTO-FIX/IMPLEMENT/DATA-FIX 流程和重试上限见 ../rules/auto-fix-engine.md 第 4 节
**检查 4: 未实现功能占位符(所有前端强制)**
```bash
@@ -381,7 +381,21 @@ echo "placeholder_functions=$PLACEHOLDER_COUNT"
- 管理后台:必须填写表单、点击按钮、验证提交结果
- 小程序:必须模拟用户交互流程(登录/浏览/报名等)
- 切换前端目标时必须 `browser_resize` 到正确视口
- **⛔ 视觉验证关卡**(⛔ 强制 — Read fully and follow: ./visual-verification.md
**⛔ 交互后 UI 验证规则(不可省略)**
每个交互操作click/type/upload完成后必须按以下顺序验证
1. browser_snapshot → 确认 DOM 状态变化checked/selected/disabled/value 变化)
2. browser_take_screenshot → 保存视觉证据
3. 与操作前 snapshot 对比 → 确认 UI 有可观察的变化
4. 如无变化 → 标记 FAIL + 进入诊断流程
禁止:
- ❌ 只调用 API 验证curl POST → 200 → PASS不检查 UI 是否更新
- ❌ 点击按钮后不检查按钮状态disabled→enabled? loading? error?
- ❌ 勾选框点击后不确认 checked 属性变化
- ❌ 弹窗关闭后不确认主界面是否更新
- **⛔ 视觉验证关卡**(⛔ 强制 — Read fully and follow: ../rules/visual-verification.md
- 每个关键操作后必须通过视觉验证关卡(独立步骤,不可跳过)
- 关卡 = browser_take_screenshot + analyze_image使用 visual-verification.md 标准提示词)
- 关卡未通过 → 按分流规则处理,不得进入下一个操作
@@ -462,7 +476,7 @@ auto_fixes:
- 此步骤保留作为最终证据归档(中间步骤截图已在步骤 4 中完成)
#### 步骤 6: AI 视觉验证Story 涉及前端页面时)
- **⛔ 详细规则和标准提示词见 ./visual-verification.md**
- **⛔ 详细规则和标准提示词见 ../rules/visual-verification.md**
- 对最终截图强制调用 `analyze_image`
- **不调用 analyze_image 等于未完成该 Story 的验证**GATE-CHECK 会验证 `analyze_image_called: true`
- 注:中间步骤的视觉验证已在步骤 4 逐步完成(视觉验证关卡),此步骤是最终确认

View File

@@ -8,7 +8,7 @@
> | **Pencil MCP 直接版**(推荐) | `.pen` 设计源文件 | 有 `.pen` 文件时首选100% 设计稿保真度 |
> | **HTML 原型版** | `prototype/pages/*.html` | 无 `.pen` 文件或需要 HTML 交互时 |
>
> Pencil MCP 直接版文档:**[visual-diff-mode-pencil.md](./visual-diff-mode-pencil.md)**
> Pencil MCP 直接版文档:**[visual-diff-mode-pencil.md](./visual-diff-pencil.md)**
>
> **与其他模式的关系**
> - 回归验证模式 → 检查功能点存在且正确(类比单元测试)

View File

@@ -59,9 +59,10 @@ Phase PVD-1: 逐页对比循环
├── C. 结构校验(.pen节点树+ AI 视觉对比
├── D. 差异分级 + 强制执行计数
└── E. PAGE GATE-CHECK 门禁检查
├── 🟢 通过 → G. 记录 → NEXT PAGE
└── 🔴/🟡 未通过 → F. AUTO-FIX → 重截 → 重比 → 重新 GATE-CHECK
G. 记录结果到 pipeline-state.yaml
Phase PVD-2: 汇总报告
├── 生成 visual-diff-pencil-report.md
└── 输出差异统计和修复建议
```
---
@@ -203,8 +204,8 @@ PVD-1 PER-PAGE LOOP:
C. 结构校验 + AI 视觉对比
D. 差异分级
E. PAGE GATE-CHECK ⛔
├── 🟢 通过 → G. 记录 → NEXT PAGE
└── 🔴/🟡 未通过 → F. AUTO-FIX → 重截 → 重比 → 重新 GATE-CHECK
├── 🟢 通过 → G. 记录 → NEXT PAGE
└── 🔴/🟡 未通过 → F. AUTO-FIX → 重截 → 重比 → 重新 GATE-CHECK
G. 记录结果到 pipeline-state.yaml
```
@@ -298,27 +299,31 @@ PVD-1 PER-PAGE LOOP:
结果包含所有层级topBar, topBar.topLeft, topBar.topRight, tabSection, tabSection.tabLeft, barCard1, barCard1.ratingBadge, barCard1.activitySnippet 等等(深度嵌套没问题,全部提取)。
示例: topBar.topLeft / tabSection.tabLeft / availableCard / amountInput / ...
3. **检查全局配置关联**: 如果设计帧包含 name=bottomNav/BottomNav 且是 ref 组件
- 读取 app/mini-program/src/pages.json → 获取当前 tabBar 配置
- 对比设计中 bottomNav.children.length vs 实际 tabBar.list.length
- 对比每个 item 文字描述是否匹配(如果可匹配)
- 数量不匹配 → critical_count += 1底部导航结构错误是严重差异
- 读取 app/mini-program/src/pages.json → 获取当前 tabBar 配置
- 对比设计中 bottomNav.children.length vs 实际 tabBar.list.length
- 对比每个 item 文字描述是否匹配(如果可匹配)
- 数量不匹配 → critical_count += 1底部导航结构错误是严重差异
4. 读取实际页面源码app/mini-program/src/pages/{page}/index.vue双向检查每个必需组件:
- **必需组件检查**: 按路径节点整个区块缺失 → 直接判定为 🔴 严重差异 → critical_count += 1
**强制规则**: 无论层级多深,**只要设计节点有 name 就必须存在**,缺失必须计数
- **文字样式一致性检查**: **任意设计节点 type=text 且有 name** → 检查 fill 颜色 + fontSize + fontWeight 与实际CSS不符 → 🟡 中等差异 → moderate_count += 1
- **布局对齐检查**: 设计节点声明 `justifyContent: space_between` → 检查实际CSS是否正确设置 `display: flex; justify-content: space-between;` → 如果右侧元素未靠右对齐 → 🟡 中等差异 → moderate_count += 1
4. 读取实际页面源码app/mini-program/src/pages/{page}/index.vue双向检查每个必需组件:
- **必需组件检查**: 按路径节点整个区块缺失 → 直接判定为 🔴 严重差异 → critical_count += 1
- **文字样式一致性检查**: **任意设计节点 type=text 且有 name** → 检查 fill 颜色 + fontSize + fontWeight 与实际CSS不符 → 🟡 中等差异 → moderate_count += 1
- **布局对齐检查**: 设计节点声明 `justifyContent: space_between` → 检查实际CSS是否正确设置 `display: flex; justify-content: space-between;` → 如果右侧元素未靠右对齐 → 🟡 中等差异 → moderate_count += 1
5. 结构校验通过后,使用 Read 工具分别查看设计截图和实际截图AI 综合分析视觉差异:
- **必需组件检查**: 节点整个区块缺失 → 直接判定为 🔴 严重差异 → critical_count += 1
- **多余组件检查**: 实际页面存在设计稿中没有的顶层区块 → 🟡 中等差异 → moderate_count += 1
- **组件类型一致性检查**: 设计是 `icon_font` 但实现用纯文本字符 → 🟡 中等差异 → moderate_count += 1
- **必需组件检查**: 节点整个区块缺失 → 直接判定为 🔴 严重差异 → critical_count += 1
- **多余组件检查**: 实际页面存在设计稿中没有的顶层区块 → 🟡 中等差异 → moderate_count += 1
- **组件类型一致性检查**: 设计是 `icon_font` 但实现用纯文本字符 → 🟡 中等差异 → moderate_count += 1
6. 结构校验通过后,使用 Read 工具分别查看设计截图和实际截图AI 综合分析视觉差异:
- 布局结构(网格/弹性/定位、对齐方式)
- 组件排列(导航栏、卡片、按钮、图标)
- 颜色Neon Pulse 规范:#000000 背景、#ffb3b5 粉色、#e8b3ff 紫色、#00dce5 青色)
- 间距(内边距、外边距、元素间距)
- 字体(大小、粗细、颜色、对齐方式)
- 图标(是否存在、形状是否正确、是否 emoji 替代)
- 设计规范(是否违反 Neon Pulse 原则:如存在不必要的 1px 边框)
- 布局结构(网格/弹性/定位、对齐方式)
- 组件排列(导航栏、卡片、按钮、图标)
- 颜色Neon Pulse 规范:#000000 背景、#ffb3b5 粉色、#e8b3ff 紫色、#00dce5 青色)
- 间距(内边距、外边距、元素间距)
- 字体(大小、粗细、颜色、对齐方式)
- 图标(是否存在、形状是否正确、是否 emoji 替代)
- 设计规范(是否违反 Neon Pulse 原则:如存在不必要的 1px 边框)
```
**优势**:
@@ -333,14 +338,14 @@ PVD-1 PER-PAGE LOOP:
设计稿 (.pen) 中标记 `reusable: true` 的组件为**全局可复用组件**,必须抽取为 Vue 全局组件在 `app/mini-program/src/components/` 目录,所有页面使用 import 导入,禁止在每个页面重复手写完整实现。
**检查规则**:
**检查规则**
1. 先通过 Pencil MCP `batch_get` 扫描 `.pen` 中所有标记 `reusable: true` 的节点 → 获取全局可复用组件列表
2. 对每个需要使用该组件的页面:
- 如果页面**完整手写实现了可复用组件代码**(未 import 使用全局组件)→ 🟡 中等差异 `moderate_count += 1`
- 如果使用了全局组件但样式(背景色/尺寸)不符合设计规范 → 🟡 中等差异 `moderate_count += 1`
- 正确使用了全局组件且样式符合规范 → 不计数
**当前已识别可复用组件**:
**当前已识别可复用组件**
- `NavigationBarPrimary` (一级页面通用导航栏) → 要求:背景 `#000000` 不透明
- `NavigationBarWithBack` (二级页面带返回导航栏) → 要求:背景 `#000000cc` 半透明 + `backdrop-filter: blur(20px)`

View File

@@ -1,6 +1,6 @@
# Phase 0: SETUP初始化
> 参见 ./iron-laws.md 了解铁律五(上下文压缩后自愈)的详细说明。
> 参见 ../rules/iron-laws.md 了解铁律五(上下文压缩后自愈)的详细说明。
## SETUP 步骤
@@ -76,7 +76,7 @@
pm2 stop app && pm2 delete app
pm2 start "npx next start --port 3001" --name app
```
详见 `./reference/platform-nextjs.md` §7.1
详见 `../reference/platform-nextjs.md` §7.1
4.5. **外网域名发现与连通性验证NPM MCP**
- project-slug 推导规则取项目根目录名basename of pwd追加 `-group` 后缀
@@ -216,7 +216,7 @@
pm2 restart vividspark
```
详见 `./reference/platform-nextjs.md` §10
详见 `../reference/platform-nextjs.md` §10
4.9. **MinIO 外网地址注入(⛔ 强制)**
@@ -299,11 +299,11 @@
# 检测 uni-app 项目
[ -f "app/mini-program/src/pages.json" ] && echo "PLATFORM=uniapp"
```
- **Next.js 平台**:按 `./reference/platform-nextjs.md` 逐项检测
- **Next.js 平台**:按 `../reference/platform-nextjs.md` 逐项检测
- NextAuth trustHost 配置(第 1 节)
- Prisma 7 adapter 配置(第 2 节)
- 检测不通过 → 自动修复并记录到 `pipeline-context.md` 修复记录
- **uni-app 平台**:按 `./reference/platform-uni-app.md` 逐项检测(已有流程不变)
- **uni-app 平台**:按 `../reference/platform-uni-app.md` 逐项检测(已有流程不变)
---

View File

@@ -11,8 +11,8 @@
- Dev server 状态:`pm2 list` 检查服务是否 `online`
- 未运行则启动并等待 ready
- 失败时自动修复:创建数据库、运行迁移、重启 pm2 服务
- **Next.js 平台检查**:按 `./reference/platform-nextjs.md` 逐项检测NextAuth trustHost、Prisma 7 adapter 等)
- **uni-app 平台检查**:按 `./reference/platform-uni-app.md` 逐项检测(图标、导航栏等)
- **Next.js 平台检查**:按 `../reference/platform-nextjs.md` 逐项检测NextAuth trustHost、Prisma 7 adapter 等)
- **uni-app 平台检查**:按 `../reference/platform-uni-app.md` 逐项检测(图标、导航栏等)
2. **加载原型参考**
- 从 Story 规格文件中读取关联的原型文件路径
@@ -58,12 +58,12 @@
grep -rn "const.*API_BASE.*=" app/mini-program/src/pages/ | grep -v "import" || echo "PASS: 无独立 API 常量"
```
5. **图标方案****Read fully and follow: ./reference/platform-uni-app.md 第 1 节(⛔ 强制)**
5. **图标方案****Read fully and follow: ../reference/platform-uni-app.md 第 1 节(⛔ 强制)**
- 含 Admin (Next.js) 和 Mini-program (uni-app) 两条路径的完整安装配置
- 含使用方式、TabBar 图标方案、禁止方案列表
- **所有前端项目必须使用 Iconify 图标方案,禁止 emoji 充当功能图标**
6. **布局防溢出规则****参见 ./reference/platform-uni-app.md 第 5 节(⛔ 强制,小程序页面尤其重要)**
6. **布局防溢出规则****参见 ../reference/platform-uni-app.md 第 5 节(⛔ 强制,小程序页面尤其重要)**
- 含防溢出规则、TabBar 遮挡处理、布局溢出检测 JS 代码
#### 3B: Epic 0 特殊实现

View File

@@ -1,8 +1,8 @@
# Phase 4: TEST测试
> 参见 ./auto-fix-engine.md 了解统一修复引擎FAIL分类标准 + 修复流程 + GATE-CHECK
> 参见 ../rules/auto-fix-engine.md 了解统一修复引擎FAIL分类标准 + 修复流程 + GATE-CHECK
> 参见 ./e2e-testing.md 了解 Playwright MCP 测试序列详情。
> 参见 ../rules/e2e-testing.md 了解 Playwright MCP 测试序列详情。
### Phase 4: TEST测试
@@ -177,5 +177,5 @@ REVIEW attempt < 3?
继续下一个 Story
```
> 完整的 AUTO-FIX/IMPLEMENT/DATA-FIX 分类标准和修复流程见 ./auto-fix-engine.md 第 2-4 节
> 完整的 AUTO-FIX/IMPLEMENT/DATA-FIX 分类标准和修复流程见 ../rules/auto-fix-engine.md 第 2-4 节

View File

@@ -1,6 +1,6 @@
# Phase 5-7: REVIEW + EPIC-DONE + COMPLETE
> 参见 ./auto-fix-engine.md 了解统一修复引擎FAIL分类标准 + 修复流程 + GATE-CHECK
> 参见 ../rules/auto-fix-engine.md 了解统一修复引擎FAIL分类标准 + 修复流程 + GATE-CHECK
> 参见 ./iron-laws.md 了解质量关卡规则。
@@ -156,5 +156,5 @@ echo "journey_results=$JOURNEY_COUNT"
- 阻断: 仅在 d8d-iterate 编排模式下生效d8d-dev 独立运行时记录为 WARN
- 修复: 调用 d8d-prototype --incremental 更新原型
> 完整的 FAIL 分类标准、GATE-CHECK 和修复流程见 ./auto-fix-engine.md
> 完整的 FAIL 分类标准、GATE-CHECK 和修复流程见 ../rules/auto-fix-engine.md

View File

@@ -46,8 +46,8 @@
| 15 | UI 直接输出英文枚举值(如 APPROVED/REJECTED/PENDING/PAID/CANCELLED 等)而非本地化中文标签 | BugUI 本地化缺失)| AUTO-FIX | 任何前端页面(管理后台/小程序/H5状态字段显示英文枚举而非中文 |
| 16 | 约束声明与代码行为不一致Constraint Mismatch: 旅程描述/UI 文案说"可选/可跳过/选填"但代码实际必填,或 UI 标记"选填"但接口必填 | 约束不一致 | JOURNEY-FIX / AUTO-FIX | 旅程说"可跳过上传证件"但代码 `if (!idCardFront)` Toast "请上传所有证件照片" |
| 17 | 前端代码 CSS/style 含 `url("data:image/svg+xml")``url('data:image/svg+xml')`SVG data URI 充当图标/背景/装饰) | Bug(平台不兼容) | AUTO-IMPLEMENT | 微信小程序不支持 SVG data URI。⛔ 必须按 platform-uni-app.md §1 完整安装 Iconify + tailwindcss-icons + weapp-tailwindcss将所有 SVG data URI 替换为 Iconify 类名。**禁止用另一种 SVG data URI 替代原来的** |
| 18 | 页面同时有系统导航栏pages.json navigationBarTitleText 非 custom和自定义 fixed header导致双层标题栏 | Bug(双重导航栏) | AUTO-FIX | 截图中顶部出现两层标题(系统导航+自定义头部),参见 ./reference/platform-uni-app.md §3 |
| 19 | Tab 页面下拉刷新方式不一致scroll-view refresher / onPullDownRefresh / 无 混用),或使用列表级 scroll-view refresher | Bug(UX 不一致) | AUTO-FIX | 首页用 scroll-view refresher其他 Tab 无刷新,参见 ./reference/platform-uni-app.md §7 |
| 18 | 页面同时有系统导航栏pages.json navigationBarTitleText 非 custom和自定义 fixed header导致双层标题栏 | Bug(双重导航栏) | AUTO-FIX | 截图中顶部出现两层标题(系统导航+自定义头部),参见 ../reference/platform-uni-app.md §3 |
| 19 | Tab 页面下拉刷新方式不一致scroll-view refresher / onPullDownRefresh / 无 混用),或使用列表级 scroll-view refresher | Bug(UX 不一致) | AUTO-FIX | 首页用 scroll-view refresher其他 Tab 无刷新,参见 ../reference/platform-uni-app.md §7 |
| 20 | API route handler 无 try-catch 包裹,导致未处理异常直接返回原始 500 且无日志 | Bug(健壮性) | AUTO-FIX | Admin 提现审批 PUT 返回 500 但状态仍更新(异常被吞) |
| 21 | uni-app 页面使用 `onMounted` 获取数据,但该页面是 `uni.navigateBack()` 的返回目标,导致回退时数据不刷新 | Bug(数据陈旧) | AUTO-FIX | 提现后返回收益页余额未刷新onMounted 不再触发) |
| **99** | **以上都不匹配的任何 FAIL** | **默认: Bug** | **AUTO-FIX** | **兜底规则,确保无遗漏** |
@@ -104,7 +104,7 @@
- 即时使用数据(验证码)仅通过 Toast 显示且源码无 console.log → Bug(#14) → AUTO-FIX添加 console.log + 自动填充)
- UI 显示英文枚举值APPROVED/REJECTED/PENDING/PAID/CANCELLED 等)→ Bug(#15) → AUTO-FIX添加中文映射函数适用于所有前端管理后台 statusLabel / 小程序 computed 映射)
- 前端代码含 `data:image/svg+xml`SVG data URI`grep -rn "data:image/svg+xml" app/mini-program/src/` 扫描所有 `.vue` 文件 → 发现 → 平台不兼容(#17) → AUTO-IMPLEMENT⛔ 必须按 platform-uni-app.md §1 完整安装 Iconify + 替换所有 SVG data URI**禁止用另一种 SVG data URI 替代原来的**
- Tab 页面下拉刷新方式不一致scroll-view refresher / onPullDownRefresh / 无 混用)→ Bug(#19) → AUTO-FIX参见 ./reference/platform-uni-app.md §7 统一为 onPullDownRefresh
- Tab 页面下拉刷新方式不一致scroll-view refresher / onPullDownRefresh / 无 混用)→ Bug(#19) → AUTO-FIX参见 ../reference/platform-uni-app.md §7 统一为 onPullDownRefresh
- 无法归类的 FAIL → 默认 Bug(#99) → AUTO-FIX
- API 返回 500 + `Read` 源码发现 handler 无 try-catch → Bug(#20) → AUTO-FIX添加 try-catch 包裹 + console.error + JSON 500 响应)
- `uni.navigateBack()` 返回后 `browser_snapshot` 数据未刷新 + 源码用 `onMounted``onShow` → Bug(#21) → AUTO-FIX替换 `onMounted``onShow`
@@ -176,7 +176,7 @@
**⛔ FAIL #6 诊断子步骤(`browser_type`/`browser_click` 失败时强制执行)**:
> uni-app/小程序编译特性诊断(如 uni-input height:0px详见 **./reference/platform-uni-app.md 第 3.1 节**。
> uni-app/小程序编译特性诊断(如 uni-input height:0px详见 **../reference/platform-uni-app.md 第 3.1 节**。
1. `browser_evaluate` 检查目标元素的 DOM 结构和计算样式:
```javascript
@@ -248,17 +248,17 @@
**Emoji → Iconify 替换方案(检测到 emoji 充当功能图标时使用 ⛔ 强制)**:
⛔ **完整安装配置、使用方式、禁止方案列表见 ./reference/platform-uni-app.md 第 1 节。禁止自行发明替代方案。**
⛔ **完整安装配置、使用方式、禁止方案列表见 ../reference/platform-uni-app.md 第 1 节。禁止自行发明替代方案。**
适用条件: icon/btn 元素内含 emoji 字符(如 🔍🔔💬🪪💳📷🏠📱)
执行步骤:
1. **Read fully and follow: ./reference/platform-uni-app.md 第 1 节**(⛔ 不可跳过 — 含 Admin/Mini-program 两条路径完整安装步骤)
1. **Read fully and follow: ../reference/platform-uni-app.md 第 1 节**(⛔ 不可跳过 — 含 Admin/Mini-program 两条路径完整安装步骤)
2. **替换源码**: 将所有 emoji 字符替换为 Iconify 类名(如 🔍 → `class="i-lucide-search"`
3. **Bash** 安装依赖 + 重新构建
4. **重测** 验证图标渲染正常
**禁止的替代方案**(完整列表见 ./reference/platform-uni-app.md 第 1 节"禁止的替代方案"
**禁止的替代方案**(完整列表见 ../reference/platform-uni-app.md 第 1 节"禁止的替代方案"
**手机号+验证码登录实现方案(#11 触发时使用)**:
@@ -349,7 +349,7 @@ uni.showToast({ title: "验证码已发送", icon: "success" });
**适用**: FAIL #19 — Tab 页面下拉刷新方式不一致scroll-view refresher / onPullDownRefresh / 无 混用)
**⛔ 详细修复步骤见 ./reference/platform-uni-app.md §7**
**⛔ 详细修复步骤见 ../reference/platform-uni-app.md §7**
**流程**:
1. `Edit` pages.json → globalStyle 添加 `"enablePullDownRefresh": true`
@@ -602,7 +602,7 @@ AUTO-FIX/AUTO-IMPLEMENT 执行后:
| 文件 | 引用位置 |
|------|---------|
| `journey-mode.md` | 执行模板步骤 4修复阶段`Read fully and follow: ./auto-fix-engine.md` |
| `modes/journey/journey-execution.md` | 执行模板步骤 4修复阶段`Read fully and follow: ./auto-fix-engine.md` |
| `validation-mode.md` | AUTO-FIX/AUTO-IMPLEMENT 分支 → `Read fully and follow: ./auto-fix-engine.md` |
| `phase-04-test.md` | Phase 4.5 AUTO-FIX 循环 → 引用第 4 节修复流程 |
| `phase-05-review.md` | 质量关卡 FAIL 处理 → 引用第 2 节分类标准 |

View File

@@ -96,7 +96,7 @@ echo "inline_api=$INLINE_COUNT"
[ "$INLINE_COUNT" -gt 0 ] && echo "INLINE_FILES:" && echo "$INLINE_FILES"
# 检查 3: 图标方案合规 + Emoji 充当图标
# 完整检测命令见 ./reference/platform-uni-app.md 第 6 节
# 完整检测命令见 ../reference/platform-uni-app.md 第 6 节
```
**判定规则**
@@ -116,7 +116,7 @@ echo "inline_api=$INLINE_COUNT"
3. 重启前端服务 → 重新执行步骤 9.5 验证
**AUTO-IMPLEMENT未实现类型**
按照 `./reference/platform-uni-app.md` 第 1 节(图标方案)和第 2 节TabBar 方案)执行完整实现:
按照 `../reference/platform-uni-app.md` 第 1 节(图标方案)和第 2 节TabBar 方案)执行完整实现:
1. 安装依赖Tailwind + Iconify + weapp-tailwindcss
2. 创建配置文件tailwind.config.js, vite.config.ts
3. 创建组件(自定义 TabBar
@@ -182,8 +182,8 @@ verification_detail:
**目的**:小程序页面在真实移动设备上经常出现宽度/高度溢出视口、底部 TabBar 被遮挡的问题。此步骤通过 JavaScript 检测这类布局问题。
**检测方法**
> 完整的检测 JS 代码和 TabBar CSS 选择器见 **./reference/platform-uni-app.md 第 5.2 节**。
> 防溢出规则见 **./reference/platform-uni-app.md 第 5.1 节**。
> 完整的检测 JS 代码和 TabBar CSS 选择器见 **../reference/platform-uni-app.md 第 5.2 节**。
> 防溢出规则见 **../reference/platform-uni-app.md 第 5.1 节**。
在步骤 8analyze_image之后、步骤 9network_requests之前执行。
@@ -216,7 +216,7 @@ verification_detail:
### 用户旅程测试Epic 级集成验证)
**⛔ 工具选择强制规则**:执行旅程测试时,每个用户步骤必须遵循上述 Playwright MCP 测试序列(步骤 0-9。**禁止使用 curl 替代 browser_click / browser_type / browser_snapshot / browser_navigate**。curl 仅用于数据状态的前后对比验证(补充,非替代用户交互)。详见 `journey-mode.md` 的"工具选择守卫"部分。
**⛔ 工具选择强制规则**:执行旅程测试时,每个用户步骤必须遵循上述 Playwright MCP 测试序列(步骤 0-9。**禁止使用 curl 替代 browser_click / browser_type / browser_snapshot / browser_navigate**。curl 仅用于数据状态的前后对比验证(补充,非替代用户交互)。详见 `../modes/journey/journey-execution.md` 的"工具选择守卫"部分。
**核心理念**:技能文档只定义"如何做用户旅程测试"的方法论和步骤,**不定死具体旅程**。具体旅程由 AI 根据项目自身的 PRD/需求文档/Epic+Story 定义自主识别。
@@ -225,7 +225,7 @@ verification_detail:
**用户旅程 ≠ 单元测试。必须模拟真实用户从自然入口开始的行为路径。**
**规则 1起始页必须是自然入口**
- 小程序:起始页 = 用户打开网址看到的第一个页面(参见 ./reference/platform-uni-app.md §4 入口页面)
- 小程序:起始页 = 用户打开网址看到的第一个页面(参见 ../reference/platform-uni-app.md §4 入口页面)
- 管理后台:起始页 = 根 URL `/`(通常重定向到登录或 Dashboard
- ❌ `browser_navigate("/pages/login/index")` — 用户不会直接输入登录页 URL
- ✅ `browser_navigate("http://mini-xxx.dev.d8d.fun/")` → 用户看到首页 → 自然触发登录流程

View File

@@ -217,14 +217,14 @@ Epic N+1 完成
| 检测项 | FAIL 条件 | 分类 | 修复动作 |
|--------|----------|------|---------|
| 布局溢出 | `horizontal_overflow === true` | Bug | AUTO-FIX: CSS 修复 |
| TabBar 图标缺失 | 只有文本无图标 | 未实现 | AUTO-IMPLEMENT: 实现自定义 TabBar参见 ./reference/platform-uni-app.md §2 |
| TabBar 图标缺失 | 只有文本无图标 | 未实现 | AUTO-IMPLEMENT: 实现自定义 TabBar参见 ../reference/platform-uni-app.md §2 |
| API 内联声明 | 任何前端代码有独立 `const API_BASE =` | Bug/未实现 | 集中模块存在→AUTO-FIX否则→AUTO-IMPLEMENT |
| API 目标错误 | 外网模式下发现 localhost | Bug | AUTO-FIX: 替换 fallback 值 |
| 源码 localhost fallback | grep 发现 `localhost:[port]` | Bug | AUTO-FIX: 替换为外网域名 |
| TabBar iconPath 为空 | `pages.json` iconPath 是空字符串 | 未实现 | AUTO-IMPLEMENT: 自定义 TabBar + Iconify参见 ./reference/platform-uni-app.md §1+§2 |
| Emoji 充当功能图标 | icon/btn 元素内含 emoji 字符 | 未实现 | AUTO-IMPLEMENT: **⛔ 必须按 ./reference/platform-uni-app.md §1 完整安装 Iconify + tailwindcss-icons + weapp-tailwindcss小程序禁止 SVG data URI 等不支持的替代方案** |
| SVG data URI 充当图标/装饰 | `grep -rn "data:image/svg+xml" app/mini-program/src/` 在 CSS/style 中发现 `url("data:image/svg+xml...")``url('data:image/svg+xml...')` | Bug(平台不兼容) | AUTO-IMPLEMENT: **⛔ 必须按 ./reference/platform-uni-app.md §1 完整安装 Iconify + tailwindcss-icons + weapp-tailwindcss/vite将所有 SVG data URI 替换为 Iconify 类名,⛔ 禁止用另一种 SVG data URI 替代原来的** |
| Tailwind/Iconify 未配置 | mini-program 无 tailwindcss-icons | 未实现 | AUTO-IMPLEMENT: 完整安装配置(参见 ./reference/platform-uni-app.md §1 |
| TabBar iconPath 为空 | `pages.json` iconPath 是空字符串 | 未实现 | AUTO-IMPLEMENT: 自定义 TabBar + Iconify参见 ../reference/platform-uni-app.md §1+§2 |
| Emoji 充当功能图标 | icon/btn 元素内含 emoji 字符 | 未实现 | AUTO-IMPLEMENT: **⛔ 必须按 ../reference/platform-uni-app.md §1 完整安装 Iconify + tailwindcss-icons + weapp-tailwindcss小程序禁止 SVG data URI 等不支持的替代方案** |
| SVG data URI 充当图标/装饰 | `grep -rn "data:image/svg+xml" app/mini-program/src/` 在 CSS/style 中发现 `url("data:image/svg+xml...")``url('data:image/svg+xml...')` | Bug(平台不兼容) | AUTO-IMPLEMENT: **⛔ 必须按 ../reference/platform-uni-app.md §1 完整安装 Iconify + tailwindcss-icons + weapp-tailwindcss/vite将所有 SVG data URI 替换为 Iconify 类名,⛔ 禁止用另一种 SVG data URI 替代原来的** |
| Tailwind/Iconify 未配置 | mini-program 无 tailwindcss-icons | 未实现 | AUTO-IMPLEMENT: 完整安装配置(参见 ../reference/platform-uni-app.md §1 |
| Phase 衔接跳步 | Phase 0V 未完成就进入 Story 验证 | 阻断 | 不得开始 Story 验证直到 Phase 0V COMPLETE GATE 通过 |
| 三写不一致 | pipeline-state 和 pipeline-context 的 done 计数不匹配 | 阻断 | 不得标记 Story 完成,必须定位漏写的文件 |
| 用户旅程未执行 | `pipeline-state` user_journeys 为空 | 阻断 | 不得标记 complete必须回退执行 |
@@ -237,9 +237,12 @@ Epic N+1 完成
| UI 硬编码英文枚举值 | `browser_evaluate` 检测页面可见文本含 APPROVED/REJECTED/PENDING/PAID/CANCELLED/REFUNDED/DRAFT/ONGOING/COMPLETED 等英文大写枚举(适用于所有前端页面,不限于管理后台) | Bug(#15) | AUTO-FIX: 添加中文映射函数(管理后台 statusLabel / 小程序 computed |
| 约束声明与代码行为不一致 | 旅程描述含"可选/可跳过/选填"或页面 UI 含"(选填)/(可选)"标记但代码实际有必填验证Toast 含"请上传/请填写/不能为空"或源码 `if (!field)` 拦截) | 约束不一致(#16) | JOURNEY-FIX: 修复旅程定义 / AUTO-FIX: 修复代码或 UI 文案,使声明与行为一致 |
| analyze_image 视觉验证未执行 | pipeline-state 无 `analyze_image_called: true` 或 verification_detail.design_check 缺失 | 阻断 | 必须回退执行 analyze_image 后才能标记完成(见 ./visual-verification.md |
| 双重导航栏 | 页面在 pages.json 中有 `navigationBarTitleText`(非 custom且页面源码含 `position:fixed` 的自定义 header 元素,导致系统导航栏与自定义头部同时显示(截图中可见两层标题) | Bug(#18) | AUTO-FIX: pages.json 该页面添加 `navigationStyle: "custom"` + 页面 header CSS 添加 safe-area padding参见 ./reference/platform-uni-app.md §3 |
| 双重导航栏 | 页面在 pages.json 中有 `navigationBarTitleText`(非 custom且页面源码含 `position:fixed` 的自定义 header 元素,导致系统导航栏与自定义头部同时显示(截图中可见两层标题) | Bug(#18) | AUTO-FIX: pages.json 该页面添加 `navigationStyle: "custom"` + 页面 header CSS 添加 safe-area padding参见 ../reference/platform-uni-app.md §3 |
| API route 无 try-catch | API 返回 500 + `Read` 源码发现 handler 函数无 try-catch 包裹(异常直接返回原始 500 且无日志) | Bug(#20) | AUTO-FIX: 添加 try-catch 包裹 + console.error + JSON 500 响应(参见 ./auto-fix-engine.md #20 |
| 页面 navigateBack 后数据陈旧 | `uni.navigateBack()` 返回目标页后 `browser_snapshot` 数据未更新 + 源码用 `onMounted``onShow` | Bug(#21) | AUTO-FIX: 替换 `onMounted``onShow`from `@dcloudio/uni-app`,参见 ./auto-fix-engine.md #21 |
| 交互元素状态未变化 | browser_click 点击 checkbox/radio/toggle 后 browser_snapshot 确认 checked/selected 状态未改变 | Bug(#22) | AUTO-FIX: 修复事件绑定或状态更新逻辑 |
| 按钮永久 disabled | 旅程定义中要求点击的按钮(如 Next/Submit/Publish处于 disabled 状态且无法通过前置操作解除 | Bug(#23) | AUTO-FIX: 修复 disabled 条件或连接正确的状态源 |
| API 成功但 UI 未更新 | curl/API 返回成功但 browser_snapshot + browser_take_screenshot 确认界面无变化(如封面预览未刷新、列表未新增) | Bug(#24) | AUTO-FIX: 添加 refetch/状态同步/乐观更新 |
> 完整的 FAIL 分类标准(含兜底规则 #99)和修复流程见 ./auto-fix-engine.md 第 2-4 节
@@ -262,6 +265,9 @@ Epic N+1 完成
- ❌ 页面 UI 含"(选填)/(可选)"标记但后端/前端实际必填(不标记 UX Mismatch
- ❌ API 返回 500 但未检查源码 try-catch 就标记"环境问题"或"已知问题"
- ❌ 页面 navigateBack 后数据未刷新但标记"已通过 API 验证"(必须检查 onShow
- ❌ API 返回 200 但未截图确认 UI 实际更新就标记 PASSAPI 状态 ≠ UI 状态)
- ❌ 点击 checkbox/radio/toggle 后不验证 checked 状态是否变化
- ❌ 按钮处于 disabled 状态时不记录为 FAIL 而是跳过
## 铁律六:页面变更必须同步原型

View File

@@ -1,6 +1,6 @@
# 旅程真实性规则(⛔ 统一规则集 — 定义和验证共享)
> **Read fully and follow** when referenced by journey-mode.md.
> **Read fully and follow** when referenced by ../modes/journey/journey-definition.md or ../modes/journey/journey-validation.md.
>
> 被以下流程引用:
> - 子模式 1 步骤 3.2(旅程生成后自检)

View File

@@ -3,7 +3,7 @@
> **⛔ 所有模式共享**旅程验证模式、回归验证模式、E2E 测试、Phase 4 测试均引用此文件。
>
> **被引用位置**
> - `journey-mode.md` 执行模板步骤 2e
> - `../modes/journey/journey-execution.md` 执行模板步骤 2e
> - `validation-mode.md` Story 验证流程
> - `e2e-testing.md` 步骤 8
> - `phase-04-test.md` 测试流程
@@ -105,7 +105,7 @@
- 步骤 2: 对每个 DUAL_NAV_RISK 页面,检查源码是否有 `position:fixed` 的自定义 header
](step 2)
- 发现匹配 → 标记 dual_nav_check.found = FOUND → 记录文件列表
- → 按检测即阻断表 "双重导航栏" 条目处理AUTO-FIX #18,参见 ./reference/platform-uni-app.md §3
- → 按检测即阻断表 "双重导航栏" 条目处理AUTO-FIX #18,参见 ../reference/platform-uni-app.md §3
@@ -132,7 +132,7 @@
grep -l "class=\"header" app/mini-program/src/pages/{page-path}/*.vue
```
- 发现匹配 → 标记 dual_nav_check.found = FOUND → 记录文件列表
- → 按检测即阻断表 "双重导航栏" 条目处理AUTO-FIX #18,参见 ./reference/platform-uni-app.md §3
- → 按检测即阻断表 "双重导航栏" 条目处理AUTO-FIX #18,参见 ../reference/platform-uni-app.md §3
**源码扫描优先规则**适用于所有源码扫描检测项dual_nav、svg_data_uri、emoji 等):
- 当源码扫描检测到 FOUND → **必须标记为 FOUND**,按对应修复流程处理
@@ -149,7 +149,7 @@
- 无上述代码 → NONE
- 步骤 3: tabBar 页面间刷新方式不一致(混用 LIST_LEVEL/PAGE_LEVEL/NONE或存在 LIST_LEVEL
→ 标记 refresh_check.found = INCONSISTENT → 记录各页面刷新方式
- → 按检测即阻断表 "下拉刷新方式不一致" 条目处理AUTO-FIX #19,参见 ./reference/platform-uni-app.md §7
- → 按检测即阻断表 "下拉刷新方式不一致" 条目处理AUTO-FIX #19,参见 ../reference/platform-uni-app.md §7
4. **布局质量**(⛔ 逐一检查以下每一项,不得跳过):
a. 溢出检测:无水平溢出,内容不超出视口
@@ -271,10 +271,10 @@ step_results:
| 发现的问题 | 分类 | 修复动作 | 铁律依据 |
|-----------|------|---------|---------|
| TabBar 图标缺失(只有文本无图标) | 未实现 | AUTO-IMPLEMENT: 自定义 TabBar + Iconify参见 ./reference/platform-uni-app.md §1+§2 | iron-laws L223, L227 |
| Emoji 充当功能图标 | 未实现 | AUTO-IMPLEMENT: **⛔ 必须按 ./reference/platform-uni-app.md §1 完整安装 Iconify + tailwindcss-icons小程序需 weapp-tailwindcss/vite禁止 SVG data URI** | iron-laws L228 |
| Tailwind/Iconify 未配置 | 未实现 | AUTO-IMPLEMENT: 完整安装配置(参见 ./reference/platform-uni-app.md §1 | iron-laws L229 |
| SVG data URI 充当图标/装饰 | Bug(平台不兼容 #17) | AUTO-IMPLEMENT: **⛔ 必须按 ./reference/platform-uni-app.md §1 完整安装 Iconify + tailwindcss-icons + weapp-tailwindcss/vite** | iron-laws L223 |
| TabBar 图标缺失(只有文本无图标) | 未实现 | AUTO-IMPLEMENT: 自定义 TabBar + Iconify参见 ../reference/platform-uni-app.md §1+§2 | iron-laws L223, L227 |
| Emoji 充当功能图标 | 未实现 | AUTO-IMPLEMENT: **⛔ 必须按 ../reference/platform-uni-app.md §1 完整安装 Iconify + tailwindcss-icons小程序需 weapp-tailwindcss/vite禁止 SVG data URI** | iron-laws L228 |
| Tailwind/Iconify 未配置 | 未实现 | AUTO-IMPLEMENT: 完整安装配置(参见 ../reference/platform-uni-app.md §1 | iron-laws L229 |
| SVG data URI 充当图标/装饰 | Bug(平台不兼容 #17) | AUTO-IMPLEMENT: **⛔ 必须按 ../reference/platform-uni-app.md §1 完整安装 Iconify + tailwindcss-icons + weapp-tailwindcss/vite** | iron-laws L223 |
| 英文枚举值显示 | Bug(#15) | AUTO-FIX: 添加中文映射函数 | iron-laws L239 |
| Broken image | Bug | AUTO-FIX: 修复图片路径/占位符 | — |
| 图片/视频资源 403/404 | Bug | AUTO-FIX: 使用 presigned URL403或修复路径404 | — |

View File

@@ -161,30 +161,30 @@
### 完整模式 / 续跑模式 / 单 Story 模式 / 单 Epic 模式
```
Read fully and follow: ./phase-00-setup.md
Read fully and follow: ./phases/phase-00-setup.md
Read fully and follow: ./phase-01-plan.md
Read fully and follow: ./phases/phase-01-plan.md
逐 Story 循环:
Read fully and follow: ./phase-02-create-spec.md
Read fully and follow: ./phase-03-implement.md
Read fully and follow: ./phase-04-test.md
Read fully and follow: ./phase-05-review.md
Read fully and follow: ./phases/phase-02-create-spec.md
Read fully and follow: ./phases/phase-03-implement.md
Read fully and follow: ./phases/phase-04-test.md
Read fully and follow: ./phases/phase-05-review.md
所有 Epic 完成:
→ 生成 pipeline-report.md参见 ./phase-05-review.md COMPLETE 部分)
→ 生成 pipeline-report.md参见 ./phases/phase-05-review.md COMPLETE 部分)
```
### 回归验证模式
```
Read fully and follow: ./validation-mode.md
Read fully and follow: ./modes/validation-mode.md
```
### 旅程验证模式
```
Read fully and follow: ./journey-mode.md
Read fully and follow: ./modes/journey/journey-index.md
```
### 原型对比验证模式
@@ -192,10 +192,10 @@ Read fully and follow: ./journey-mode.md
```
自动检测并选择:
├── 存在 .pen 设计文件(如 VividSpark1.2.pen
│ └── Read fully and follow: ./visual-diff-mode-pencil.md # Pencil MCP 直接版
│ └── Read fully and follow: ./modes/visual-diff/visual-diff-pencil.md # Pencil MCP 直接版
└── 不存在 .pen 文件,但存在 prototype/pages/*.html
└── Read fully and follow: ./visual-diff-mode.md # HTML 原型版
└── Read fully and follow: ./modes/visual-diff/visual-diff-html.md # HTML 原型版
```
**手动指定子模式**
@@ -208,11 +208,11 @@ Read fully and follow: ./journey-mode.md
## 质量关卡
> 参见 ./iron-laws.md 了解五大铁律和验证检查清单。
> 参见 ./rules/iron-laws.md 了解五大铁律和验证检查清单。
## E2E 测试
> 参见 ./e2e-testing.md 了解 Playwright MCP 测试序列和视口规则。
> 参见 ./rules/e2e-testing.md 了解 Playwright MCP 测试序列和视口规则。
## 实战经验