diff --git a/.claude/skills/d8d-dev/auto-fix-engine.md b/.claude/skills/d8d-dev/auto-fix-engine.md index f48ad12..ca299a9 100644 --- a/.claude/skills/d8d-dev/auto-fix-engine.md +++ b/.claude/skills/d8d-dev/auto-fix-engine.md @@ -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 | diff --git a/.claude/skills/d8d-dev/visual-diff-mode.md b/.claude/skills/d8d-dev/visual-diff-mode.md new file mode 100644 index 0000000..f46f45b --- /dev/null +++ b/.claude/skills/d8d-dev/visual-diff-mode.md @@ -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` 获取: +- 实际应用 URL(API_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. 样式 class:Tailwind 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 次,仍失败则标记为需手动修复 diff --git a/.claude/skills/d8d-dev/workflow.md b/.claude/skills/d8d-dev/workflow.md index 403236c..3299c91 100644 --- a/.claude/skills/d8d-dev/workflow.md +++ b/.claude/skills/d8d-dev/workflow.md @@ -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 中的相关部分。