sync: 添加d8d-inc-plan技能 + 增强旅程验证流程 + PNG格式验证 + 递归组件检查 + 图标检查规范
This commit is contained in:
@@ -191,11 +191,10 @@ Epic N+1 完成
|
||||
(即使上一个 Story 也是管理后台,也要确认当前视口正确)
|
||||
|
||||
验证小程序页面之前:
|
||||
browser_resize → width: 390, height: 844, deviceScaleFactor: 2
|
||||
browser_resize → width: 375, height: 812
|
||||
(即使上一个 Story 也是小程序,也要确认当前视口正确)
|
||||
- 390x844 = 现代 iPhone (12/13/14/15) 标准视口
|
||||
- deviceScaleFactor: 2 → 像素密度 2x,匹配 Pencil 设计稿导出 scale=2
|
||||
- 旧款 iPhone 是 375x812,现代设计稿普遍使用 390 宽度
|
||||
- 375x812 = 旧款 iPhone 标准视口
|
||||
- 现代设计稿普遍使用 390 宽度,可根据设计稿调整匹配
|
||||
```
|
||||
|
||||
### 禁止行为列表
|
||||
|
||||
@@ -55,59 +55,59 @@ Story 验证全部通过 ≠ 用户能正常使用系统。旅程模式弥补这
|
||||
- <80% → ❌ FAIL(必须补充旅程后才能进入验证子模式)
|
||||
f. 输出覆盖度报告到 `_bmad-output/implementation-artifacts/journey-coverage-report.md`
|
||||
↓
|
||||
3.6 组件级覆盖校验(⛔ 强制 — FR 检查通过后必须执行):
|
||||
⛔ 目的:FR 级检查是二值判断("提到就算覆盖"),无法发现"1 步路过式覆盖"的问题。
|
||||
此步骤深入到组件交互元素粒度,确保每个用户可操作的元素都被旅程验证。
|
||||
3.6 组件级覆盖校验(⛔ 强制 — FR 检查通过后必须执行):
|
||||
⛔ 目的:FR 级检查是二值判断("提到就算覆盖"),无法发现"1 步路过式覆盖"的问题。
|
||||
此步骤深入到组件交互元素粒度,确保每个用户可操作的元素都被旅程验证。
|
||||
|
||||
a. 识别应用的所有主要视图/页面:
|
||||
- 从 app-client.tsx 或路由配置提取视图列表(如 batch-list / batch-dashboard / batch-results)
|
||||
- 从 src/app/ 目录结构提取独立页面路由
|
||||
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
|
||||
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 条旅程的某个步骤覆盖
|
||||
- 计算每个组件的覆盖深度 = 被旅程步骤覆盖的交互元素数 / 总交互元素数
|
||||
c. 比对交互元素 vs 所有旅程的技术验证步骤:
|
||||
- 每个交互元素必须被至少 1 条旅程的某个步骤覆盖
|
||||
- 计算每个组件的覆盖深度 = 被旅程步骤覆盖的交互元素数 / 总交互元素数
|
||||
|
||||
d. 覆盖深度门控(⛔ 100% 覆盖强制 — 任何缺口必须自动补旅程):
|
||||
| 组件交互元素数 | 最低覆盖要求 | 不满足时 |
|
||||
|--------------|-------------|---------|
|
||||
| 1-2 个 | 至少 1 步涉及 | ❌ FAIL → 自动补旅程 |
|
||||
| 3-5 个 | 至少 1 条旅程含 ≥2 步专门操作该视图 | ❌ FAIL → 自动补旅程 |
|
||||
| ≥6 个 | 必须有 1 条专门旅程(以该视图为主场景) | ❌ FAIL → 自动补旅程 |
|
||||
| 任何数量 | 每个交互元素必须被覆盖 | 未覆盖元素 → 自动补到已有旅程或新建旅程步骤 |
|
||||
d. 覆盖深度门控(⛔ 100% 覆盖强制 — 任何缺口必须自动补旅程):
|
||||
| 组件交互元素数 | 最低覆盖要求 | 不满足时 |
|
||||
|--------------|-------------|---------|
|
||||
| 1-2 个 | 至少 1 步涉及 | ❌ FAIL → 自动补旅程 |
|
||||
| 3-5 个 | 至少 1 条旅程含 ≥2 步专门操作该视图 | ❌ FAIL → 自动补旅程 |
|
||||
| ≥6 个 | 必须有 1 条专门旅程(以该视图为主场景) | ❌ FAIL → 自动补旅程 |
|
||||
| 任何数量 | 每个交互元素必须被覆盖 | 未覆盖元素 → 自动补到已有旅程或新建旅程步骤 |
|
||||
|
||||
e. 输出组件覆盖矩阵到覆盖度报告:
|
||||
| 组件 | 交互元素数 | 被覆盖数 | 覆盖深度 | 旅程来源 | 状态 |
|
||||
|------|-----------|---------|---------|---------|------|
|
||||
e. 输出组件覆盖矩阵到覆盖度报告:
|
||||
| 组件 | 交互元素数 | 被覆盖数 | 覆盖深度 | 旅程来源 | 状态 |
|
||||
|------|-----------|---------|---------|---------|------|
|
||||
|
||||
f. 门控汇总(⛔ 100% 强制 — 无 WARN,只有 PASS 或自动补):
|
||||
- 所有组件所有交互元素 100% 覆盖 → ✅ PASS
|
||||
- 有任何交互元素未被覆盖 → ❌ FAIL → 自动补充旅程步骤(见下方 g)
|
||||
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%"
|
||||
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%"
|
||||
```
|
||||
|
||||
### ⛔ 用户旅程真实性原则
|
||||
@@ -178,7 +178,7 @@ Story 验证全部通过 ≠ 用户能正常使用系统。旅程模式弥补这
|
||||
### 验收标准
|
||||
- [ ] {具体可量化的断言1}
|
||||
- [ ] {具体可量化的断言2}
|
||||
- [ ] 全程使用自然导航路径
|
||||
- [ ] {全程使用自然导航路径}
|
||||
```
|
||||
|
||||
### 旅程来源优先级
|
||||
@@ -204,17 +204,17 @@ Story 验证全部通过 ≠ 用户能正常使用系统。旅程模式弥补这
|
||||
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 适配
|
||||
**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 部分:
|
||||
- 解析每个旅程的「技术验证步骤」→ 为每个步骤生成 step 条目
|
||||
- 提取验收标准 → 生成 acceptance_criteria 条目
|
||||
- 写入/追加到 verification-checklist.yaml 的 journeys 部分:
|
||||
```yaml
|
||||
journeys:
|
||||
epic_N:
|
||||
@@ -232,12 +232,10 @@ Story 验证全部通过 ≠ 用户能正常使用系统。旅程模式弥补这
|
||||
- criterion: "{验收标准}"
|
||||
status: "pending"
|
||||
```
|
||||
- 如 verification-checklist.yaml 已存在 → 跳过已 pass 的步骤,从 pending 步骤恢复
|
||||
- 如 verification-checklist.yaml 已存在 → 跳过已 pass 的步骤,从 pending 步骤恢复
|
||||
↓
|
||||
2. 询问: 验证全部 Epic 还是指定 Epic?(确定验证范围)
|
||||
↓
|
||||
1.9 创建旅程任务清单(⛔ 强制 — 根据范围筛选,每条旅程一个 Task)
|
||||
- 为每条待验证旅程**创建独立的 Task 任务**,使用 `TaskCreate` 工具:
|
||||
1.9 创建旅程任务清单(⛔ 强制 — 根据范围筛选,每条旅程一个 Task)
|
||||
- 为每条待验证旅程**创建独立的 Task 任务**,使用 `TaskCreate` 工具:
|
||||
- 每个任务记录:Epic 编号、旅程名称、旅程文件路径、前置条件
|
||||
- 便于独立追踪每条旅程的验证进度
|
||||
- 避免单个 agent 上下文过大导致污染或遗漏
|
||||
@@ -255,15 +253,17 @@ Story 验证全部通过 ≠ 用户能正常使用系统。旅程模式弥补这
|
||||
严格按照 journey-mode.md 执行模板执行完整验证流程。
|
||||
```
|
||||
↓
|
||||
1.10 启动逐个任务验证(每条旅程独立 agent)
|
||||
- 对**每个任务**启动一个**独立的 agent**,按照后续「执行模板」执行验证
|
||||
- 独立 agent 避免上下文污染,执行更精准
|
||||
1.10 启动逐个任务验证(每条旅程独立 agent)
|
||||
- 对**每个任务**启动一个**独立的 agent**,按照后续「执行模板」执行验证
|
||||
- 独立 agent 避免上下文污染,执行更精准
|
||||
|
||||
⛔ **强制规则:禁止在主 agent 中一次性串行执行多条旅程**
|
||||
⛔ **强制规则:禁止在主 agent 中一次性串行执行多条旅程**
|
||||
↓
|
||||
3. 汇总所有任务结果 → 生成旅程验证报告
|
||||
2. 询问: 验证全部 Epic 还是指定 Epic?(确定验证范围)
|
||||
↓
|
||||
4. 更新 pipeline-state.yaml 最终状态
|
||||
3. 汇总所有任务结果 → 生成旅程验证报告
|
||||
↓
|
||||
4. 更新 pipeline-state.yaml 最终状态
|
||||
```
|
||||
|
||||
---
|
||||
@@ -277,6 +277,12 @@ Story 验证全部通过 ≠ 用户能正常使用系统。旅程模式弥补这
|
||||
|
||||
---
|
||||
|
||||
## 执行模板(单条旅程验证)
|
||||
|
||||
```
|
||||
前置:已创建独立任务,任务包含:Epic 编号、旅程名称、旅程文件路径、前置条件
|
||||
```
|
||||
|
||||
### ⛔ 执行铁律
|
||||
|
||||
**规则 E0:定义先行校验(⛔ 最高优先级)**
|
||||
@@ -331,12 +337,14 @@ Story 验证全部通过 ≠ 用户能正常使用系统。旅程模式弥补这
|
||||
|
||||
**规则 E3.6:即时使用数据必须可回溯(⛔ 强制)**
|
||||
|
||||
操作产生的数据如果**下一步骤立即需要**(如验证码需输入到表单),且该数据**仅通过 Toast 传递**,Toast 消失后旅程无法获取 → 流程卡死。
|
||||
操作成功后产生的即时使用数据(验证码等),如果仅通过 Toast 传递,下一步骤无法获取 → 流程卡死。
|
||||
|
||||
**即时使用数据回退链(按优先级尝试)**:
|
||||
这不是所有 Toast 都是问题,仅当三条件同时满足时才触发修复。
|
||||
|
||||
**回退链(按优先级尝试)**:
|
||||
|
||||
```
|
||||
触发操作(如 sendCode)→ Toast 显示数据
|
||||
触发即时使用数据操作后:
|
||||
↓
|
||||
1. browser_snapshot → 如果 Toast 包含关键数据 → 立即记录
|
||||
↓ (Toast 已消失)
|
||||
@@ -349,8 +357,7 @@ Story 验证全部通过 ≠ 用户能正常使用系统。旅程模式弥补这
|
||||
4. 回退: curl/API 直接查询(如重新请求 send-code)
|
||||
```
|
||||
|
||||
注意:**订单号、支付结果**等后续页面自然显示的数据不属于"即时使用数据",范畴 — 旅程不需要从 Toast 中提取这些数据。
|
||||
|
||||
注意:**订单号、支付结果**等后续页面自然显示的数据不属于"即时使用数据"范畴 — 旅程不需要从 Toast 中提取这些数据。
|
||||
此回退链仅在 Toast 消失后且下一步骤需要数据时使用。
|
||||
|
||||
**⛔ 如果以上回退链全部失败且源码无 console.log → FAIL #14 → AUTO-FIX**
|
||||
@@ -485,8 +492,8 @@ Story 验证全部通过 ≠ 用户能正常使用系统。旅程模式弥补这
|
||||
result: "pass|fail"
|
||||
- check: "all_issues_resolved"
|
||||
result: "pass|fail"
|
||||
- check: "file_format_validation"
|
||||
result: "pass|fail"
|
||||
executed_at: "{ISO timestamp}"
|
||||
note: "{备注}"
|
||||
```
|
||||
c. 步骤级 GATE 检查(6 项,任一 FAIL → 阻断):
|
||||
├── G1: screenshot_consistency — screenshot_path 文件存在
|
||||
@@ -499,7 +506,6 @@ Story 验证全部通过 ≠ 用户能正常使用系统。旅程模式弥补这
|
||||
│ - 检测失败 → **立即重新截图**,不得累积到最后批量修复
|
||||
│ - 检测通过 → 才允许继续下一步骤
|
||||
│ - 目的:防止出现"扩展名 .png 但内容是 YAML 文本"的错误
|
||||
|
||||
4.5. ⛔ **源码 SVG data URI 扫描**(视觉验证关卡内 — 每次 snapshot 后强制执行):
|
||||
- Bash: `grep -rn "data:image/svg+xml" app/mini-program/src/`(扫描小程序源码目录)
|
||||
- 发现匹配 → svg_data_uri_check.found = FOUND → 记录文件列表
|
||||
@@ -511,10 +517,10 @@ Story 验证全部通过 ≠ 用户能正常使用系统。旅程模式弥补这
|
||||
- 修复失败 → 标记 journey-step-fail → 继续下一步骤
|
||||
- 步骤 4(修复阶段)仅处理功能断言 FAIL,不处理视觉验证 FAIL
|
||||
f. 如涉及数据变化 → browser_evaluate 或 curl 验证数据(✅ 允许 curl 补充)
|
||||
|
||||
6. ⛔ **旅程步骤原型/Pencil 视觉对比验证**(⛔ 强制 — 针对操作时产生的动态状态):
|
||||
|
||||
6. ⛔ **旅程步骤原型/Pencil 视觉对比验证**(⛔ 强制 — 针对操作时产生的动态状态)
|
||||
目的: 捕获并验证操作时才会出现的视觉状态(hover、选中、弹窗、展开、加载中、错误提示等),这些状态在静态原型对比中无法覆盖
|
||||
|
||||
|
||||
触发条件(满足任一即执行):
|
||||
- 当前步骤操作后出现了弹窗/Modal/对话框
|
||||
- 下拉菜单/Select/日期选择器展开
|
||||
@@ -525,48 +531,48 @@ Story 验证全部通过 ≠ 用户能正常使用系统。旅程模式弥补这
|
||||
- 页面切换/跳转后的首屏渲染完成
|
||||
- 出现了错误提示/Toast/Notification
|
||||
- 折叠面板展开/收起状态变化
|
||||
|
||||
|
||||
执行流程:
|
||||
a. 等待状态稳定(动画/过渡完成):
|
||||
- browser_wait_for → time=1-2s(等待动画完成)
|
||||
|
||||
|
||||
b. 捕获实际状态截图:
|
||||
- browser_take_screenshot → 保存为 journey-epic{N}-{M}-step{S}-state.png
|
||||
|
||||
|
||||
c. 搜索匹配的设计帧(双模式支持):
|
||||
**Pencil MCP 模式(优先)**:
|
||||
- 读取 pipeline-context.md 获取设计文件路径(如 VividSpark1.2.pen)
|
||||
- mcp__pencil__batch_get → 搜索与当前状态匹配的帧
|
||||
- 搜索关键词: "{Page}-{State}" 如 "Dashboard-Modal", "Login-Error"
|
||||
- 或按 frame 类型和名称模式匹配
|
||||
- 搜索关键词: "{Page}-{State}" 如 "Dashboard-Modal", "Login-Error", "Upload-Loading"
|
||||
- 或按 frame 类型和名称模式匹配
|
||||
- 如找到匹配帧 → mcp__pencil__export_nodes 导出设计截图
|
||||
|
||||
|
||||
**HTML 原型模式(回退)**:
|
||||
- 检查 prototype/pages/{group}/{page}-{state}.html 是否存在
|
||||
- 如存在 → 启动原型服务 → Playwright 截图
|
||||
|
||||
|
||||
设计帧未找到处理:
|
||||
- 标记 prototype_found: false
|
||||
- 记录 actual_screenshot 路径
|
||||
- 不阻断旅程,但记录到 pipeline-report.md 建议补充设计帧
|
||||
|
||||
|
||||
d. 执行视觉对比(如找到设计帧):
|
||||
- ui_diff_check:
|
||||
- expected_image_source: 设计帧截图(或原型截图)
|
||||
- actual_image_source: 当前状态截图 (journey-epic{N}-{M}-step{S}-state.png)
|
||||
- prompt: "对比设计原型和实际实现。这是用户操作后出现的动态交互状态(如弹窗、hover、选中、加载中、错误提示等)。
|
||||
|
||||
|
||||
重点关注:
|
||||
1) 组件布局和结构是否一致(弹窗位置、按钮排列等)
|
||||
2) 颜色/样式是否匹配(背景色、边框、阴影等)
|
||||
3) 文字内容是否正确(标题、提示信息、按钮文字等)
|
||||
4) 交互状态是否准确(hover 效果、选中状态、focus 样式等)
|
||||
5) 图标和装饰元素是否一致
|
||||
|
||||
|
||||
注意:忽略动态数据(如用户名、时间戳等),只关注 UI 结构和样式。
|
||||
|
||||
|
||||
按严重程度列出所有视觉差异:"
|
||||
|
||||
|
||||
e. 差异分级与处理:
|
||||
记录到 pipeline-state.yaml:
|
||||
```yaml
|
||||
@@ -599,22 +605,22 @@ Story 验证全部通过 ≠ 用户能正常使用系统。旅程模式弥补这
|
||||
auto_fix_type: "AUTO-FIX" # 修复类型
|
||||
auto_fix_result: "PASS" # 修复结果
|
||||
```
|
||||
|
||||
|
||||
差异处理规则:
|
||||
- 🔴 严重差异(布局错误、关键组件缺失、文字错误)→ 立即触发 AUTO-FIX
|
||||
- 🟡 中等差异(颜色、间距偏差)→ 记录到 pipeline-report.md,建议修复
|
||||
- 🟢 轻微差异(微小像素偏移)→ 记录但不阻断旅程
|
||||
- ✅ 无差异 → 标记状态正常
|
||||
|
||||
f. 自动修复与重测(如触发):
|
||||
- AUTO-FIX 触发后:
|
||||
1. 定位相关源码文件(根据差异类型确定)
|
||||
2. 执行修复(如调整 CSS、修改组件样式等)
|
||||
3. 重新截图: browser_take_screenshot
|
||||
4. 重新对比: ui_diff_check
|
||||
5. 修复成功 → 标记 auto_fix_result: "PASS"
|
||||
6. 修复失败 → 标记 auto_fix_result: "FAIL",记录原因
|
||||
|
||||
|
||||
f. 自动修复与重测(如触发):
|
||||
- AUTO-FIX 触发后:
|
||||
1. 定位相关源码文件(根据差异类型确定)
|
||||
2. 执行修复(如调整 CSS、修改组件样式等)
|
||||
3. 重新截图: browser_take_screenshot
|
||||
4. 重新对比: ui_diff_check
|
||||
5. 修复成功 → 标记 auto_fix_result: "PASS"
|
||||
6. 修复失败 → 标记 auto_fix_result: "FAIL",记录原因
|
||||
|
||||
6. ⛔ **源码 SVG data URI 扫描**(视觉验证关卡内 — 每次 snapshot 后强制执行):
|
||||
g. ⛔ **约束一致性检查**(每个用户步骤首次执行时 — R7 执行时强制检测):
|
||||
触发条件(操作被拦截 + 声明方说"可选"):
|
||||
@@ -721,7 +727,8 @@ user_journeys:
|
||||
| 维度 | 回归验证模式 | 旅程验证模式 |
|
||||
|------|------------|------------|
|
||||
| 粒度 | 逐 Story | 跨 Story/Epic |
|
||||
| 目标 | 验证功能点存在 | 验证用户能完成目标 |
|
||||
| 目标 | 验证功能点存在且正确 | 验证用户能完成目标 |
|
||||
| 类比 | 单元测试 | 集成测试/E2E |
|
||||
| 入口 | 直接 navigate 到目标页面 | 从自然入口开始 |
|
||||
|
||||
- 两种模式**独立运行**,互不依赖
|
||||
|
||||
@@ -161,6 +161,7 @@ visual_diff_pencil_mapping:
|
||||
```
|
||||
|
||||
这样可以确保**代码中有的页面一定会被对比**,不会因为名称提取问题漏掉。
|
||||
|
||||
### 0.6 创建截图输出目录
|
||||
|
||||
```bash
|
||||
@@ -298,18 +299,20 @@ 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 就必须存在**,缺失必须计数
|
||||
- **必需组件检查**: 按路径节点整个区块缺失 → 直接判定为 🔴 严重差异 → 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
|
||||
5. 结构校验通过后,使用 Read 工具分别查看设计截图和实际截图,AI 综合分析视觉差异:
|
||||
- **必需组件检查**: 节点整个区块缺失 → 直接判定为 🔴 严重差异 → critical_count += 1
|
||||
- **多余组件检查**: 实际页面存在设计稿中没有的顶层区块 → 🟡 中等差异 → moderate_count += 1
|
||||
- **组件类型一致性检查**: 设计是 `icon_font` 但实现用纯文本字符 → 🟡 中等差异 → moderate_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 综合分析视觉差异:
|
||||
4. 结构校验通过后,使用 Read 工具分别查看设计截图和实际截图,AI 综合分析视觉差异:
|
||||
- 布局结构(网格/弹性/定位、对齐方式)
|
||||
- 组件排列(导航栏、卡片、按钮、图标)
|
||||
- 颜色(Neon Pulse 规范:#000000 背景、#ffb3b5 粉色、#e8b3ff 紫色、#00dce5 青色)
|
||||
@@ -319,6 +322,14 @@ PVD-1 PER-PAGE LOOP:
|
||||
- 设计规范(是否违反 Neon Pulse 原则:如存在不必要的 1px 边框)
|
||||
```
|
||||
|
||||
**优势**:
|
||||
- 利用设计文件本身的结构信息,比纯视觉分析更可靠
|
||||
- 确保不会漏检"整个区块缺失"(如支付结果页订单信息卡片整个不见了)
|
||||
- 帮助 AI 聚焦到每个具体组件,差异分析更准确
|
||||
- **递归检查所有层级** → 确保不会漏检顶层存在但内部子区块缺失(如 topBar 存在但 topLeft 缺失)
|
||||
- **自动检查全局 tabBar 配置** → 设计稿显示的 bottomNav 结构必须与实际配置一致
|
||||
- **所有文字节点都检查** → 正文/meta/操作计数等颜色不符不会漏检
|
||||
|
||||
### 可复用组件检查(通用规则)
|
||||
|
||||
设计稿 (.pen) 中标记 `reusable: true` 的组件为**全局可复用组件**,必须抽取为 Vue 全局组件在 `app/mini-program/src/components/` 目录,所有页面使用 import 导入,禁止在每个页面重复手写完整实现。
|
||||
@@ -342,30 +353,30 @@ PVD-1 PER-PAGE LOOP:
|
||||
|
||||
**正确 HTML 结构:**
|
||||
```vue
|
||||
<!-- ✅ 正确:容器嵌套独立图标元素 -->
|
||||
<view class="action-icon pink">
|
||||
<view class="i-lucide-flame"></view>
|
||||
</view>
|
||||
<!-- ✅ 正确:容器嵌套独立图标元素 -->
|
||||
<view class="action-icon pink">
|
||||
<view class="i-lucide-flame"></view>
|
||||
</view>
|
||||
|
||||
<!-- ❌ 错误:图标类直接放在容器 -->
|
||||
<view class="action-icon pink i-lucide-flame"></view>
|
||||
<!-- ❌ 错误:图标类直接放在容器 -->
|
||||
<view class="action-icon pink i-lucide-flame"></view>
|
||||
```
|
||||
|
||||
**正确 CSS 规则:**
|
||||
```css
|
||||
/* 必须添加确保SVG继承颜色 */
|
||||
.action-icon > view svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
fill: currentColor;
|
||||
}
|
||||
/* 必须添加确保SVG继承颜色 */
|
||||
.action-icon > view svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
fill: currentColor;
|
||||
}
|
||||
```
|
||||
|
||||
**图标命名规则:**
|
||||
|
||||
项目 tailwind.config.js 已启用三个图标集合:
|
||||
```js
|
||||
collections: getIconCollections(["mdi", "lucide", "material-symbols"]);
|
||||
collections: getIconCollections(["mdi", "lucide", "material-symbols"]);
|
||||
```
|
||||
|
||||
| 图标库 | 类名前缀 | 适用场景 |
|
||||
@@ -387,48 +398,40 @@ collections: getIconCollections(["mdi", "lucide", "material-symbols"]);
|
||||
| `chevron_right` | `chevron-right` | 向右箭头 |
|
||||
|
||||
**差异定级规则:**
|
||||
- 结构错误(图标类在容器上)→ 🟡 中等差异 `moderate_count += 1`
|
||||
- 缺少 `fill: currentColor` → 🟡 中等差异 `moderate_count += 1`
|
||||
- 图标名称不匹配(按上表)→ 🟡 中等差异 `moderate_count += 1`
|
||||
- **使用 emoji 替代图标** → 🔴 严重差异 `critical_count += 1` **(微信小程序不兼容emoji,强制修复)**
|
||||
- 结构错误(图标类在容器上)→ 🟡 中等差异 `moderate_count += 1`
|
||||
- 缺少 `fill: currentColor` → 🟡 中等差异 `moderate_count += 1`
|
||||
- 图标名称不匹配(按上表)→ 🟡 中等差异 `moderate_count += 1`
|
||||
- **使用 emoji 替代图标** → 🔴 严重差异 `critical_count += 1` **(微信小程序不兼容emoji,强制修复)**
|
||||
|
||||
### 布局对齐检查
|
||||
|
||||
对于设计节点使用 `justifyContent: space_between` 的水平排列容器:
|
||||
- 检查实际CSS是否正确设置 `display: flex; justify-content: space-between; align-items: flex-start;`
|
||||
- 如果左侧元素挤在一起,右侧元素没有靠右对齐 → 🟡 中等差异 `moderate_count += 1`
|
||||
- 检查实际CSS是否正确设置 `display: flex; justify-content: space-between; align-items: flex-start;`
|
||||
- 如果左侧元素挤在一起,右侧元素没有靠右对齐 → 🟡 中等差异 `moderate_count += 1`
|
||||
|
||||
对于设计节点声明的对齐方式:
|
||||
- 实际实现对齐方式不符 → 🟡 中等差异 `moderate_count += 1`
|
||||
- 实际实现对齐方式不符 → 🟡 中等差异 `moderate_count += 1`
|
||||
|
||||
### 防御性编程提醒
|
||||
|
||||
当 API 数据可能返回 `null` 时(未登录/加载失败),确保代码使用**可选链操作符 `?.`**访问属性避免渲染崩溃:
|
||||
|
||||
```vue
|
||||
<!-- 正确 -->
|
||||
<template>{{ earnings?.totalAmount }}</template>
|
||||
<!-- 正确 -->
|
||||
<template>{{ earnings?.totalAmount }}</template>
|
||||
|
||||
<!-- 错误 -> 页面渲染崩溃 -->
|
||||
<template>{{ earnings.totalAmount }}</template>
|
||||
<!-- 错误 -> 页面渲染崩溃 -->
|
||||
<template>{{ earnings.totalAmount }}</template>
|
||||
```
|
||||
|
||||
如果发现源码缺少可选链,在 AUTO-FIX 阶段应当添加。
|
||||
|
||||
**优势**:
|
||||
- 利用设计文件本身的结构信息,比纯视觉分析更可靠
|
||||
- **递归检查所有层级** → 确保不会漏检顶层存在但内部子区块缺失(如 topBar 存在但 topLeft 缺失)
|
||||
- **自动检查全局 tabBar 配置** → 设计稿显示的 bottomNav 结构必须与实际配置一致
|
||||
- **所有文字节点都检查** → 正文/meta/操作计数等颜色不符不会漏检
|
||||
- 确保不会漏检"整个区块缺失"(如支付结果页订单信息卡片整个不见了)
|
||||
- 帮助 AI 聚焦到每个具体组件,差异分析更准确
|
||||
|
||||
### 1.D 差异分级
|
||||
|
||||
| 级别 | 标准 | 示例 |
|
||||
|------|------|------|
|
||||
| 🔴 严重 | 布局结构不同、关键组件缺失 | 原型有两列布局实际一列;整个设计区块在源码中缺失 |
|
||||
| 🟡 中等 | 颜色/间距偏差、图标不一致、文本对齐方式不符、圆角尺寸差异、多余顶层区块、违反设计规范、组件类型不匹配、文字标签颜色/字体大小不符 | 卡片圆角不一致;图标形状与设计不符;设计左对齐实际居中;设计稿没有的多余提示文字;存在不必要的1px边框违反无边界线原则;设计是icon-font实际用纯文本;设计区块标题要求白色不透明实际半透灰色 |
|
||||
| 🔴 严重 | 布局结构不同、**任意层级**关键组件缺失、bottomNav 配置与设计不匹配 (Tab数量/文字) | 原型有两列布局实际一列;整个设计区块在源码中缺失 |
|
||||
| 🟡 中等 | 颜色/间距偏差、图标不一致、文本对齐方式不符、圆角尺寸差异、多余顶层区块、违反Neon Pulse设计规范、组件类型不匹配、**任意命名文字节点颜色/字体大小不符** | 卡片圆角不一致;图标形状与设计不符;设计左对齐实际居中;设计稿没有的多余提示文字;存在不必要的1px边框违反无边界线原则;设计是icon-font实际用纯文本 |
|
||||
| 🟢 轻微 | 微小像素差异 | 1-2px 偏移 |
|
||||
|
||||
### 强制执行清单(必须严格遵守,不得跳过)
|
||||
@@ -521,22 +524,6 @@ visual_diff_pencil:
|
||||
|
||||
---
|
||||
|
||||
## 复查阶段(必须)
|
||||
|
||||
> **第一轮 PVD-1 验证完成成后,必须启动一轮专门的复查阶段**
|
||||
|
||||
原因:
|
||||
- 初始验证时,很多需要登录/参数的页面因未登录/缺少参数导致截图不正确,但代码对齐检查已通过
|
||||
- 必须逐个页面确认**截图内容实际正确**
|
||||
- 只有**所有页面截图都正确**,整个验证任务才算完成
|
||||
|
||||
操作:
|
||||
1. 为每个 `status: active` 页面创建独立的**复查 Task**
|
||||
2. 逐个检查:截图文件存在 → 内容显示正确目标页面 → 布局与设计对齐
|
||||
3. 如果不正确:修复问题(注入token/添加URL参数/修复代码bug)→ 重新截图
|
||||
|
||||
---
|
||||
|
||||
## Phase PVD-2: 汇总报告
|
||||
|
||||
### 2.1 生成报告
|
||||
@@ -602,6 +589,22 @@ visual_diff_pencil:
|
||||
|
||||
---
|
||||
|
||||
## 复查阶段(必须)
|
||||
|
||||
> **第一轮 PVD-1 验证完成成后,必须启动一轮专门的复查阶段**
|
||||
|
||||
原因:
|
||||
- 初始验证时,很多需要登录/参数的页面因未登录/缺少参数导致截图不正确,但代码对齐检查已通过
|
||||
- 必须逐个页面确认**截图内容实际正确**
|
||||
- 只有**所有页面截图都正确**,整个验证任务才算完成
|
||||
|
||||
操作:
|
||||
1. 为每个 `status: active` 页面创建独立的**复查 Task**
|
||||
2. 逐个检查:截图文件存在 → 内容显示正确目标页面 → 布局与设计对齐
|
||||
3. 如果不正确:修复问题(注入token/添加URL参数/修复代码bug)→ 重新截图
|
||||
|
||||
---
|
||||
|
||||
## 附录:与 HTML 原型版对比速查
|
||||
|
||||
| 步骤 | Pencil MCP 直接版 | HTML 原型版 |
|
||||
|
||||
@@ -248,7 +248,6 @@ phases:
|
||||
| create-prd | 页面导航流程 + 功能区域 + 组件概览 |
|
||||
| validate-prd | (不注入,验证已有PRD) |
|
||||
| create-ux-design | 完整设计系统:变量、组件、页面布局 |
|
||||
| **design-sync (built-in)** | 检查 UX 文档是否新增页面 → 创建页面 → **截图验证 + 自动优化循环** → 更新设计上下文 |
|
||||
| create-architecture | 组件层级 + 数据流模式 |
|
||||
| create-epics | 页面级功能分解 |
|
||||
| check-readiness | (不注入,验证已有产物) |
|
||||
|
||||
Reference in New Issue
Block a user