sync: d8d-dev 新增 Phase VD-3 视觉差异自动修复 + VISUAL-FIX 修复类别

- visual-diff-mode.md: 新增 Phase VD-3 全量自动修复流程(全局修复→逐页修复→二次对比→最终报告)
- workflow.md: 更新模式流转逻辑,原型对比后自动修复;新增 visual_diff 状态判断
- auto-fix-engine.md: 新增 VISUAL-FIX 类别 V1-V5(主题/布局/品牌/组件/样式)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
yourname
2026-04-09 00:57:59 +00:00
parent b583d577c7
commit b08676bdce
3 changed files with 675 additions and 8 deletions

View File

@@ -51,6 +51,11 @@
| 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** | **兜底规则,确保无遗漏** |
| **V1** | 页面主题/配色与原型不一致(深色→浅色、主色调偏差) | 视觉差异 | VISUAL-FIX | 原型深色主题但实际浅色;按钮颜色不一致 |
| **V2** | 页面布局结构与原型不同(顶部导航↔侧边栏、网格↔列表、卡片↔表格) | 视觉差异 | VISUAL-FIX | 原型顶部水平导航但实际左侧边栏;原型卡片网格但实际列表 |
| **V3** | 品牌标识与原型不同Logo 图标、标题文字、副标题) | 视觉差异 | VISUAL-FIX | 原型闪电图标+"VividSpark"但实际 "V" 字母+"Welcome back" |
| **V4** | 原型存在的 UI 组件在实际页面中缺失Remember me、FAQ、过滤器、标签页等 | 视觉差异 | VISUAL-FIX | 原型有 FAQ 区域但实际缺失;原型有 Remember me 但实际无 |
| **V5** | 按钮/输入框/卡片样式与原型不一致padding、圆角、边框、字号等 | 视觉差异 | VISUAL-FIX | 原型圆角 16px 但实际 8px原型按钮 padding 16/32 但实际 12/24 |
### "可接受"严格限定(⛔ 仅以下 2 种,其余一律必须修复)
@@ -557,5 +562,6 @@ GATE-CHECK:
| `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 节分类标准 |
| `visual-diff-mode.md` | Phase VD-3 逐页修复 → VISUAL-FIX (V1-V5) 分类引用 |
| `e2e-testing.md` | 步骤 9.5 判定规则 → 引用第 2 节分类标准 |
| `iron-laws.md` | 检测即阻断规则 → 引用第 2 节分类标准 + 第 5 节 GATE-CHECK |

View File

@@ -0,0 +1,643 @@
# 原型对比验证模式Visual Diff Mode
> **定位**:在回归验证和旅程验证之后,将实际页面实现与原型 HTML 页面做逐页视觉对比,发现布局偏差、组件遗漏、交互方式差异等视觉问题。
>
> **与其他模式的关系**
> - 回归验证模式 → 检查功能点存在且正确(类比单元测试)
> - 旅程验证模式 → 检查用户流程完整性(类比 E2E 测试)
> - **原型对比验证模式** → 检查视觉还原度(类比视觉回归测试)
>
> **触发时机**
> - 旅程验证模式完成后建议进入
> - 手动触发:`/d8d-dev visual-diff` 或 `/d8d-dev visual-diff epic-3`
> - 流水线自动触发:每个 Epic 完成后(可配置)
---
## 前置条件
```
检查清单(任一不满足 → 报错并终止):
├── prototype/ 目录存在且含 pages/ 子目录
├── prototype/server.js 存在(原型预览服务)
├── pipeline-context.md 存在(含实际应用 URL 和凭据)
├── pm2 服务运行中(实际应用可访问)
└── 至少有一个 Epic 的 Story 已 verified
```
---
## 核心流程
```
Phase VD-0: 准备
├── 发现原型页面 → 建立页面清单
├── 读取 pipeline-context.md → 获取实际应用 URL
├── 启动原型服务 → node prototype/server.js (port 8080)
└── 构建页面映射表(原型页面 ↔ 实际路由)
Phase VD-1: 逐页对比循环
对每个映射页面:
├── A. 截取原型页面截图
├── B. 截取实际页面截图
├── C. UI 差异对比(三层对比法)
└── D. 差异分级 + 记录
Phase VD-2: 汇总报告
├── 生成 visual-diff-report.md
└── 输出差异统计和修复建议
```
---
## Phase VD-0: 准备
### 0.1 发现原型页面
```bash
# 列出所有原型页面
find prototype/pages -name "*.html" | sort
```
从输出中提取页面清单,分类为 frontend 和 admin。
### 0.2 读取实际应用信息
读取 `_bmad-output/implementation-artifacts/pipeline-context.md` 获取:
- 实际应用 URLAPI_URL, ADMIN_URL
- 认证凭据
- 已实现的路由
### 0.3 启动原型服务
```bash
# 检查 8080 端口是否已被占用
lsof -i :8080 || true
# 启动原型服务(后台运行)
cd prototype && node server.js &
# 验证服务可用
curl -sf --max-time 5 http://localhost:8080/ && echo "OK"
```
如果 8080 端口被占用,使用其他端口并记录。
### 0.4 构建页面映射表
**自动映射规则**
```
对每个原型页面 prototype/pages/{group}/{name}.html:
1. 提取 group (app/admin) 和 name
2. 在实际路由中查找匹配:
- name=login → /login 或 /admin/login
- name=dashboard → / 或 /dashboard
- name=register → /register
- 其他 → /{name} 或 /admin/{name}
3. 验证实际路由可访问curl 检查非 404
4. 不可访问的页面标记为 skipped
```
**映射输出格式**(记录到 pipeline-state.yaml
```yaml
visual_diff_mapping:
- prototype: "pages/app/login.html"
actual_route: "/login"
group: "frontend"
status: "active" # active / skipped / error
- prototype: "pages/app/dashboard.html"
actual_route: "/"
group: "frontend"
status: "active"
```
---
## Phase VD-1: 逐页对比循环
对映射表中每个 `status: active` 的页面执行以下流程。
### 1.0 创建截图目录
```bash
mkdir -p tests/e2e/screenshots/visual-diff
```
### 1.A 截取原型页面截图
```
1. browser_navigate → http://localhost:8080/pages/{group}/{name}.html
2. browser_resize → 1440x900 (桌面端) 或 375x812 (移动端)
3. browser_wait_for → time=2 (等待页面渲染)
4. browser_take_screenshot(fullPage=false)
→ tests/e2e/screenshots/visual-diff/{name}-prototype-viewport.png
5. browser_take_screenshot(fullPage=true)
→ tests/e2e/screenshots/visual-diff/{name}-prototype-full.png
```
### 1.B 截取实际页面截图
```
1. browser_navigate → {实际 URL}{route}
2. browser_resize → 同上视口(必须与原型一致)
3. 处理认证:
- 如果页面需要登录 → 从 pipeline-context.md 读取凭据
- browser_navigate → 登录页 → 填写凭据 → 提交 → 等待跳转
- 如果已登录(直接访问无跳转)→ 继续
4. browser_wait_for → time=3 (等待数据加载)
5. browser_take_screenshot(fullPage=false)
→ tests/e2e/screenshots/visual-diff/{name}-actual-viewport.png
6. browser_take_screenshot(fullPage=true)
→ tests/e2e/screenshots/visual-diff/{name}-actual-full.png
```
### 1.C 三层对比法
**判断页面长度**
```javascript
// browser_evaluate
() => {
return {
pageHeight: document.documentElement.scrollHeight,
viewportHeight: window.innerHeight,
isLongPage: document.documentElement.scrollHeight > window.innerHeight * 1.5
};
}
```
**如果 isLongPage === false短页面**
```
直接对比首屏:
ui_diff_check(
expected_image_source = "{name}-prototype-viewport.png",
actual_image_source = "{name}-actual-viewport.png",
prompt = "对比这两张截图:第一张是设计原型,第二张是实际实现。列出所有视觉差异,包括布局结构、组件排列、颜色、间距、字体、图标等。按严重程度排序。"
)
```
**如果 isLongPage === true长页面**
执行三层对比法:
#### 层 1首屏对比viewport 截图)
```
ui_diff_check(
expected_image_source = "{name}-prototype-viewport.png",
actual_image_source = "{name}-actual-viewport.png",
prompt = "对比这两张首屏截图:第一张是设计原型,第二张是实际实现。首屏是最重要的视觉区域。列出所有差异,按严重程度排序。"
)
```
#### 层 2全页面对比fullPage 截图)
```
ui_diff_check(
expected_image_source = "{name}-prototype-full.png",
actual_image_source = "{name}-actual-full.png",
prompt = "对比这两张完整页面截图:第一张是设计原型,第二张是实际实现。注意页面可能很长,重点关注各区域的布局和组件差异。"
)
```
#### 层 3差异区域精确定位仅当层 1 或层 2 发现差异时执行)
```
对原型和实际页面分别执行分段截图:
1. 计算分段数量 = ceil(pageHeight / viewportHeight)
2. 对每一段:
a. browser_evaluate → window.scrollTo(0, segmentIndex * viewportHeight * 0.8)
// 20% 重叠避免切割区域遗漏
b. browser_wait_for → time=1
c. browser_take_screenshot(fullPage=false)
→ {name}-prototype-section-{N}.png
→ {name}-actual-section-{N}.png
3. 逐段 ui_diff_check 对比
```
**原型页面也需要 scroll**:原型是静态 HTML需要同样执行 scroll + 截图。
### 1.D 差异分级
每页对比完成后,将差异分级:
| 级别 | 标准 | 示例 |
|------|------|------|
| 🔴 严重 | 布局结构不同、关键组件缺失、交互方式不同 | 原型有两列布局实际一列、缺少侧边栏、用标签页代替下拉菜单 |
| 🟡 中等 | 颜色/间距偏差、图标不一致、文字样式差异、非核心组件缺失 | 卡片圆角不一致、间距差 8px+、图标风格不同 |
| 🟢 轻微 | 微小像素差异、动画效果差异、可接受的响应式适配差异 | 1-2px 偏移、hover 效果不同、字体渲染差异 |
### 1.E 即时写入 Context关键
**每完成一个页面的 ui_diff_check 后,必须立即将结果写入 `pipeline-context.md`,防止上下文压缩导致结果丢失。**
```
流程:
1. ui_diff_check 返回差异结果
2. 立即编辑 pipeline-context.md在 "原型对比验证结果" 部分更新该页面的差异摘要
3. 格式:#### N/11 {页面名} — 严重程度 🔴/🟡/🟢/✅
4. 列出关键差异(精简为 3-7 条)
5. 继续下一个页面
```
**为什么必须即时写入?**
- 原型对比流程涉及 11 个页面的截图+对比,对话上下文可能在中途被压缩
- 如果不在每页完成后即时持久化,已完成的对比结果会丢失
- `pipeline-context.md` 是上下文压缩后的恢复锚点
**context 中的记录格式示例**
```markdown
## 原型对比验证结果 (Visual Diff)
### 全局问题(所有页面共通)
- 🔴 问题描述...
### 逐页结果
#### 1/11 Login — 严重 🔴
- 原型: pages/app/login.html → 实际: /login
- 🔴 差异1
- 🔴 差异2
- 🟡 差异3
#### 2/11 Register — 严重 🔴
- ...
```
**差异记录格式pipeline-state.yaml**
```yaml
visual_diff_results:
dashboard:
prototype_page: "pages/app/dashboard.html"
actual_route: "/"
severity: moderate # critical / moderate / minor / match
viewport_compared: true
fullpage_compared: true
sections_compared: 3
differences:
- severity: critical
location: "首屏左侧"
description: "侧边栏缺失,原型有固定侧边栏导航"
section: 1
- severity: moderate
location: "首屏中部"
description: "上传区域卡片圆角:原型 16px实际 8px"
section: 1
- severity: minor
location: "第2段"
description: "卡片间距略宽:原型 16px实际 24px"
section: 2
```
---
## Phase VD-2: 汇总报告
### 2.1 生成报告
生成 `tests/e2e/screenshots/visual-diff/visual-diff-report.md`
```markdown
# Visual Diff Report
生成时间: {timestamp}
对比页面数: {total_pages}
## Summary
| 级别 | 数量 |
|------|------|
| 🔴 严重 | {critical_count} |
| 🟡 中等 | {moderate_count} |
| 🟢 轻微 | {minor_count} |
| ✅ 匹配 | {match_count} |
## 严重差异(需修复)
### 🔴 {page_name}
- 原型截图: `visual-diff/{name}-prototype-viewport.png`
- 实际截图: `visual-diff/{name}-actual-viewport.png`
- 差异:
1. {具体差异描述}
2. {具体差异描述}
- 修复建议: {auto-fix 建议}
## 中等差异(建议修复)
### 🟡 {page_name}
...
## 轻微差异(可接受)
### 🟢 {page_name}
...
## 完全匹配
### ✅ {page_name}
```
### 2.2 更新 pipeline-state.yaml
```yaml
visual_diff:
status: completed # completed / partial / failed
total_pages: 11
compared_pages: 10
skipped_pages: 1
critical_count: 0
moderate_count: 3
minor_count: 5
match_count: 2
report_path: "tests/e2e/screenshots/visual-diff/visual-diff-report.md"
timestamp: "2026-04-08T10:30:00Z"
```
### 2.3 输出结论
```
═══════════════════════════════════════════
Visual Diff Report 完成
═══════════════════════════════════════════
总页面: 10 对比, 1 跳过
🔴 严重: 0 → 无需修复
🟡 中等: 3 → 建议修复
🟢 轻微: 5 → 可接受
✅ 匹配: 2
报告: tests/e2e/screenshots/visual-diff/visual-diff-report.md
═══════════════════════════════════════════
```
### 2.4 修复决策
```
VD-2 报告完成后:
├── 🔴 严重差异 > 0 → 自动进入 Phase VD-3 全量修复
└── ✅ 无严重差异 → 流程结束
```
---
## Phase VD-3: 全量自动修复
> **定位**:在 Phase VD-2 发现严重差异后,自动修复所有视觉差异,使实际页面还原原型设计。以原型 HTML 为 Source of Truth重写 UI 层。
>
> **核心原则**
> - 先全局后逐页:全局修复(主题、导航、品牌)先做,避免逐页修复被全局问题干扰
> - 保留后端逻辑:只改 UI 层React 组件 + CSS不动 API 路由和数据库
> - 以原型为基准:直接从原型 HTML 提取设计 token 和组件结构
> - 修复后必须验证:重新截图 + ui_diff_check 确认还原度
> - 全程零确认、全自动
### 3.1 全局修复(先修复影响所有页面的共性问题)
从 pipeline-context.md 的"原型对比验证结果"中提取全局问题,按优先级修复:
```
全局问题按优先级:
P0: 主题系统(深色/浅色主题 — 影响 app 组页面)
P0: 品牌标识(图标 + 标题 — 影响所有页面)
P1: 管理后台导航结构(顶部水平导航 — 影响 admin 组页面)
P1: 通用组件样式(按钮 padding/圆角、输入框样式)
```
#### 3.1.1 主题修复
```
1. 读取原型 HTML如 pages/app/login.html提取
- 页面背景色(如 #000000
- 卡片/容器背景色(如 #1E1E1E
- 文字颜色(如 #FFFFFF
- 主色调(如 #FF8400
- 边框颜色(如 #333333
2. 修改全局样式文件:
- globals.css / tailwind.config.ts
- 定义 CSS 变量或 Tailwind theme extend
3. 修改布局组件:
- 背景色 class 对齐
- 确保所有 app 组页面使用新主题
```
#### 3.1.2 品牌标识修复
```
1. 从原型提取品牌元素:
- 图标(如 FontAwesome fa-bolt 闪电图标)
- 标题文字(如 "VividSpark"
- 副标题文字(如页面特有描述)
2. 定位品牌组件文件,替换:
- Logo 组件(图标 + 文字)
- 页面标题区域
```
#### 3.1.3 管理后台导航修复
```
1. 从原型 admin 页面提取导航结构:
- 位置:顶部水平导航栏
- 菜单项:用户管理、内容审核、平台配置、数据分析、系统设置
- 右侧:管理员邮箱 + 登出按钮
2. 修改 admin 布局组件:
- 从左侧边栏 → 顶部水平导航
- 调整所有 admin 页面布局适配
```
#### 3.1.4 全局修复完成后即时写入 context
```
编辑 pipeline-context.md在"原型对比验证结果"下添加:
### 全局修复记录
- ✅/⚠️ 主题修复:{结果摘要}
- ✅/⚠️ 品牌标识修复:{结果摘要}
- ✅/⚠️ 导航结构修复:{结果摘要}
```
### 3.2 逐页修复循环
对 Phase VD-2 报告中每个有差异的页面,执行以下流程:
```
对每个有差异的页面(按严重程度排序,🔴 优先):
├── Step A: 解析原型 HTML
├── Step B: 定位并重写实际源码
├── Step C: 重新截图验证
└── 即时写入 context每页完成后
```
#### Step A: 解析原型 HTML
```
读取 prototype/pages/{group}/{name}.html提取
1. 设计 Token
- 颜色:背景色、卡片色、文字色、主色调、边框色
- 字体font-family、font-size、font-weight
- 间距padding、margin、gap
- 圆角border-radius
- 阴影box-shadow
2. 组件列表:
- 表单字段(类型、标签、占位符、图标)
- 按钮(文字、颜色、大小、圆角)
- 卡片(布局、内容结构)
- 表格(列定义、操作按钮)
- 特殊组件(标签页、进度条、图表区域)
3. 文案:
- 页面标题、副标题
- 占位符文字
- 按钮文字
- 链接文字
4. 布局结构:
- grid/flex 布局
- 列数/行数
- 组件排列顺序
```
#### Step B: 定位并重写实际源码
```
1. 路由 → 源码文件映射:
/login → src/app/(auth)/login/page.tsx
/register → src/app/(auth)/register/page.tsx
/dashboard → src/app/(creator)/dashboard/page.tsx或 src/app/page.tsx
/publish → src/app/(creator)/publish/page.tsx
/pricing → src/app/(creator)/pricing/page.tsx
/settings → src/app/(creator)/settings/page.tsx
/admin/login → src/app/admin/login/page.tsx
/admin/users → src/app/admin/users/page.tsx
/admin/moderation → src/app/admin/moderation/page.tsx
/admin/analytics → src/app/admin/analytics/page.tsx
/admin/platforms → src/app/admin/platforms/page.tsx
/admin/settings → src/app/admin/settings/page.tsx
通用组件:
侧边栏 → src/components/layout/sidebar.tsx
头部导航 → src/components/layout/header.tsx或 admin-header.tsx
2. 以原型为 Source of Truth对齐
a. 组件结构:补全缺失组件(如 Remember me、FAQ、标签页、过滤器
b. 布局结构:对齐网格列数、卡片 vs 列表等
c. 样式 classTailwind class 对齐原型视觉
d. 文案:品牌标题、占位符、按钮文字
e. 数据展示:如原型用图表,引入 chart 库并实现
3. 关键约束:
- 保留后端逻辑不变API 调用、数据处理)
- 只修改 JSX 结构和 Tailwind class
- 新增的 UI 组件使用项目已有的设计系统组件
```
#### Step C: 重新截图验证
```
1. 重跑 Phase VD-1 的截图流程:
a. 截取修复后的实际页面截图
→ tests/e2e/screenshots/visual-diff/{name}-fixed-viewport.png
b. ui_diff_check 对比(修复后 vs 原型)
2. 结果判定:
- PASS无 🔴/🟡)→ 标记 ✅ fixed
- FAIL → 调整修复策略,重试(最多 2 次)
- 仍 FAIL → 标记 ⚠️ needs-manual-fix记录原因
3. 每页修复完成后即时写入 pipeline-context.md
#### N/11 {页面名} — ✅ fixed / ⚠️ needs-manual-fix
- 修复内容: {具体修复了什么}
- 验证结果: {ui_diff_check 摘要}
```
### 3.3 修复后二次对比(全量验证)
```
全局 + 逐页修复完成后:
1. 对所有 11 页重跑 Phase VD-1 截图 + ui_diff_check
2. 生成修复前后对比:
- 修复前: visual-diff/{name}-actual-viewport.png
- 修复后: visual-diff/{name}-fixed-viewport.png
3. 更新 visual-diff-report.md添加修复结果列
4. 更新 pipeline-state.yaml visual_diff 部分
```
### 3.4 最终报告
```yaml
visual_diff:
status: completed # completed / partial / failed
total_pages: 11
compared_pages: 11
fixed_pages: 8 # 新增
manual_fix_needed: 3 # 新增
critical_count: 0 # 修复后的数值
moderate_count: 1
minor_count: 5
match_count: 5
report_path: "tests/e2e/screenshots/visual-diff/visual-diff-report.md"
fix_report_path: "tests/e2e/screenshots/visual-diff/visual-diff-fix-report.md"
timestamp: "2026-04-08T12:00:00Z"
```
输出结论:
```
═══════════════════════════════════════════════
Visual Diff Report + 自动修复 完成
═══════════════════════════════════════════════
总页面: 11 对比, 0 跳过
✅ 已修复: 8
⚠️ 需手动修复: 3见报告
修复前: 🔴 11 🟡 0 🟢 0 ✅ 0
修复后: 🔴 0 🟡 1 🟢 5 ✅ 5
报告: tests/e2e/screenshots/visual-diff/visual-diff-report.md
修复报告: tests/e2e/screenshots/visual-diff/visual-diff-fix-report.md
═══════════════════════════════════════════════
```
---
## 视口配置
| 目标 | 宽度 | 高度 | 用途 |
|------|------|------|------|
| 桌面端(管理后台) | 1440 | 900 | admin 组页面 |
| 桌面端(前端) | 1440 | 900 | app 组页面(如有移动端原型则用移动视口) |
| 移动端 | 375 | 812 | 移动端原型(如有 mobile 目录) |
---
## 错误处理
| 错误场景 | 处理方式 |
|---------|---------|
| 原型服务启动失败 | 检查端口占用,尝试其他端口,报告错误 |
| 实际页面无法访问 | 标记该页面为 error继续下一个 |
| 实际页面需要认证且登录失败 | 标记该页面为 error记录认证错误 |
| ui_diff_check 超时 | 降级为仅 analyze_image 语义分析 |
| 截图文件过大 | fullPage 截图限制最大 8000px 高度 |
| 原型页面无对应实际路由 | 标记为 skipped记录在报告中 |
---
## 注意事项
- **视口必须一致**:原型和实际页面使用完全相同的视口尺寸截图
- **数据状态差异**:原型是静态设计,实际页面有真实数据。对比时忽略因数据内容不同导致的差异(如文字内容、图片内容),只关注布局和组件差异
- **认证页面**login/register 页面不需要登录即可访问,直接截图对比
- **原型静态特性**:原型没有动画和过渡效果,实际页面可能有,这些差异标记为 🟢 轻微
- **自动修复**Phase VD-2 发现严重差异后自动进入 Phase VD-3 全量修复,全程零确认
- **保留后端逻辑**:修复只改 UI 层React 组件 + CSS不动 API 路由和数据库
- **重试上限**:每页最多修复重试 2 次,仍失败则标记为需手动修复

View File

@@ -87,18 +87,19 @@
| **单 Epic 模式** | 执行指定 Epic 的所有 Story | 按模块开发 |
| **回归验证模式** | 不做实现,逐 Story 验证功能点存在且正确 | 代码已实现需回归验证(类比:单元测试) |
| **旅程验证模式** | 专用用户旅程定义+验证(跨页面完整流程) | 跨 Story/Epic 的用户体验验证类比E2E 测试) |
| **原型对比验证模式** | 截取原型和实际页面截图,使用 ui_diff_check + analyze_image 对比差异 | Epic 完成后的视觉还原度检查(类比:视觉回归测试) |
## 模式选择与流转
### 三种核心模式职责对比
| 维度 | 完整模式 | 回归验证模式 | 旅程验证模式 |
|------|---------|------------|------------|
| 粒度 | 全项目 | 逐 Story | 跨 Story/Epic |
| 目标 | 实现代码 | 验证功能点存在且正确 | 验证用户能完成目标 |
| 类比 | 开发 | 单元测试 | 集成测试/E2E |
| 入口 | pages.json 自然入口 | 直接 navigate 到目标页面 | 自然入口 |
| 断言 | N/A | API 返回 200 + 页面渲染 | 数据状态变化 |
| 维度 | 完整模式 | 回归验证模式 | 旅程验证模式 | 原型对比验证模式 |
|------|---------|------------|------------|------------|
| 粒度 | 全项目 | 逐 Story | 跨 Story/Epic | 逐页面 |
| 目标 | 实现代码 | 验证功能点存在且正确 | 验证用户能完成目标 | 验证视觉还原度 |
| 类比 | 开发 | 单元测试 | 集成测试/E2E | 视觉回归测试 |
| 入口 | pages.json 自然入口 | 直接 navigate 到目标页面 | 自然入口 | 原型页面 ↔ 实际路由映射 |
| 断言 | N/A | API 返回 200 + 页面渲染 | 数据状态变化 | ui_diff_check 差异分级 |
### 自动选择逻辑(用户未指定模式时)
@@ -112,6 +113,12 @@
├── status: in_progress → 续跑模式(从中断点恢复)
├── status: completed 且 story_results 全部 verified →
│ 询问: "Story 功能验证已通过。是否进入旅程验证模式?"
├── status: completed 且 journey 验证已通过 且 prototype/ 存在 →
│ 询问: "旅程验证已通过,检测到原型页面。是否进入原型对比验证模式?"
├── visual_diff.status: completed 且 critical_count > 0 且 无 fix_report_path →
│ 自动进入原型对比验证模式 Phase VD-3视觉差异修复
├── visual_diff.status: completed 且 fix_report_path 存在 →
│ 询问: "视觉差异修复已完成。查看修复报告 or 重新验证?"
├── status: completed 且存在 unverified stories →
│ 询问: "有 N 个 Story 未验证。建议先回归验证。"
│ → 回归验证模式
@@ -125,10 +132,15 @@
```
完整模式/续跑模式 完成 → 建议进入回归验证模式
回归验证模式 完成(全部 PASS→ 建议进入旅程验证模式
旅程验证模式 完成 → 输出最终报告
旅程验证模式 完成 → 建议进入原型对比验证模式
原型对比验证模式 完成 →
├── 🔴 严重差异 > 0 → 自动进入 Phase VD-3 全量修复 → 修复后输出最终报告
└── ✅ 无严重差异 → 输出最终报告(含视觉差异报告)
⛔ 不得跳过回归验证直接进入旅程验证。
功能不存在时测旅程无意义(用户点不到不存在的东西)。
⛔ 不得跳过旅程验证直接进入原型对比验证。
页面功能不正确时做视觉对比无意义(功能错了再像也没用)。
```
### 用户指定模式时
@@ -168,6 +180,12 @@ Read fully and follow: ./validation-mode.md
Read fully and follow: ./journey-mode.md
```
### 原型对比验证模式
```
Read fully and follow: ./visual-diff-mode.md
```
### 仅测试模式 / 仅审查模式
直接读取对应 Story 的 phase-04-test.md 或 phase-05-review.md 中的相关部分。