sync: d8d-prototype 新增 step-09-coverage-check 覆盖度检查步骤 #65

Merged
d8dfun merged 1 commits from sync/d8d-skills-20260425-003546 into master 2026-04-25 08:37:18 +08:00

View File

@@ -0,0 +1,413 @@
# Step 9: 需求覆盖度与符合度检查
**Progress: Step 9 (可选增强)** — Next: step-08-commit
## STEP GOAL
自动检测数据源,检查原型的需求覆盖度,生成量化报告。
## ✨ 双模式自适应
本步骤会自动检测项目是否有用户旅程文档,并选择对应的验证模式:
| 场景 | 验证模式 | 数据源 | 精度 |
|------|---------|--------|------|
| ✅ **有用户旅程文档** | 模式 A精准验证 | epic-*-journeys.md + PRD | 高Checklist 验收标准级) |
| ❌ **无用户旅程文档** | 模式 BFR 级验证 | PRD + 关键词匹配 | 中FR 描述级) |
---
## 📝 执行证据规范
本步骤完成后更新状态文件 evidence 字段时,必须包含:
- [ ] 实际处理的文件数量/列表
- [ ] 关键断言/检查的输出结果
- [ ] 使用的方法/算法说明
- [ ] (如有)偏离步骤说明的决策及理由
## ⚡ 数据源断言(必须执行,失败则立即停止)
复制以下命令到终端运行,确认输出全部为 ✅:
```bash
# 断言 1: 找到的 epic journey 文件 ≥ 5 个
JOURNEY_COUNT=$(find _bmad-output/implementation-artifacts -name "epic-*-journeys.md" | wc -l)
echo "找到 $JOURNEY_COUNT 个 epic journey 文件"
[ $JOURNEY_COUNT -ge 5 ] && echo "✅ 断言 1 通过" || { echo "❌ 断言 1 失败:需要 ≥5 个 epic-journeys.md实际 $JOURNEY_COUNT"; exit 1; }
# 断言 2: 第一个 journey 文件格式正确(包含"用户旅程"字样)
head -3 _bmad-output/implementation-artifacts/epic-1-journeys.md | grep -q "用户旅程" \
&& echo "✅ 断言 2 通过" || { echo "❌ 断言 2 失败:文件格式不是 epic-journeys.md"; exit 1; }
# 断言 3: PRD 文件存在
[ -f _bmad-output/planning-artifacts/prd.md ] && echo "✅ 断言 3 通过" || { echo "❌ 断言 3 失败PRD 不存在"; exit 1; }
echo "🎉 全部断言通过!进入模式 A精准验证"
```
**必须将上述命令的输出复制粘贴到状态文件的 evidence 中作为证据。**
---
## 执行序列
### 9.1 数据源检测
**必须按以下顺序执行:**
1. **检查用户旅程文件是否存在**
- Glob 查找 `_bmad-output/implementation-artifacts/epic-*-journeys.md`
- 统计找到的文件数量
2. **检查 PRD 文件是否存在**
- 检查 `_bmad-output/planning-artifacts/prd.md` 是否存在
3. **自动选择验证模式**
- 如果找到 ≥ 5 个旅程文件 + PRD 存在 → **模式 A精准验证**
- 如果只找到 PRD → **模式 BFR 级验证**
- 如果都找不到 → 抛出错误,无法执行覆盖度检查
4. **读取所选模式对应的数据源文件**
---
### 9.2 解析与映射建立
#### 模式 A精准验证流程
1. **解析所有 epic-journeys.md 文件**
- 提取每个 Epic 的名称、FR 范围
- 提取每个 Journey 的 ID、名称、验收标准 Checklist
- 从验收标准中提取带 `[ ]` 的检查项
- 自动提取检查项中的 FR 编号标注(如 `(FR9)`
2. **分类检查项类型**
- 检查项文本包含关键词API、POST、GET、数据库、Cookie、Token → 标记类型为 **backend**
- 检查项文本包含关键词:跳转、导航、访问、路由 → 标记类型为 **navigation**
- 检查项文本包含关键词:点击、选择、展开 → 标记类型为 **behavior**
- 检查项文本包含关键词:样式、颜色、字体、布局 → 标记类型为 **visual**
- 其他 → 标记类型为 **ui-element**
⚠️ **重要Story 文件的角色 - 仅用于映射,不提取验收标准**
Story 文件X-Y-name.md**只用于**读取 `Proto Reference` 字段建立 Journey → 原型页面的映射。
**绝对不能**从 Story 文件提取验收标准 Checklist 作为覆盖度检查的数据源。
验收标准 **只能** 从 epic-*-journeys.md 中提取。
3. **建立 ProtoPage 映射**
- 读取所有 Story 文件中的 `Proto Reference` 字段(仅此用途,不提取任何验收标准)
- 通过 Journey 名称与 Story 名称进行模糊匹配
- 建立 Journey → ProtoPage 的映射关系
#### 模式 BFR 级验证)流程:
1. **解析 prd.md 文件**
- 按模块提取所有 FR功能需求
- 提取 FR ID、描述、优先级P0/P1/P2
- 记录每个 FR 所属模块
2. **关键词匹配建立 FR → ProtoPage 映射**
- "登录、认证、auth" → `pages/admin/login.html``editor/login.html`
- "用户、账号" → `pages/admin/users.html`
- "工作空间、workspace" → `pages/admin/workspaces.html``pages/admin/workspace-detail.html`
- "容器、container" → `pages/admin/containers.html`
- "部署、deploy" → `pages/admin/deployments.html`
- "API、密钥、key" → `pages/admin/api-keys.html`
- "计费、账单、bill" → `pages/admin/ali-bills.html``pages/admin/token-bills.html`
- "套餐、订阅、subscription" → `pages/admin/coding-plans.html``pages/admin/subscriptions.html`
- "配额、quota" → `pages/admin/quota-monitor.html``pages/admin/plan-analytics.html`
- "存储、storage" → `pages/admin/storage.html``pages/admin/storage-rankings.html`
- "Worker、任务" → `pages/admin/workers-monitoring.html``pages/admin/workers-history.html`
- "模板、template" → `pages/admin/templates.html``editor/template-marketplace.html`
- "首页、仪表盘、dashboard" → `pages/admin/dashboard.html``editor/dashboard.html`
- 无法匹配 → 标记为 `无对应页面`
---
### 9.3 分类与过滤
- [ ] 遍历所有检查项,确认类型分类正确
- [ ] 标记 **backend** 类型为 ⏭️ 跳过(无需原型验证)
- [ ] 统计各类型检查项数量,写入临时统计
---
### 9.4 页面存在性检查
- [ ] 对每个有 ProtoPage 映射的需求,检查 `prototype/` 目录下文件是否存在
- [ ] 记录:页面存在 / 缺失 / 路径错误
- [ ] 对页面缺失的检查项,直接标记为 ❌ 不满足
---
### 9.5 Playwright + 视觉验证(自适应)
#### ⚠️ 验证策略(重要):
> **优先使用模型内置视觉能力,非视觉模型才调用外部 MCP**
> - Claude 等视觉模型 → 直接 Read 截图文件进行分析
> - 非视觉模型 → 调用 `mcp__zai-mcp-server__analyze_image`
> - 两种方式使用相同的提示词结构
#### 验证流程:
1. **确保服务器已启动**
```bash
# 检查服务器是否运行
curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/
# 如果不是 200启动服务器
cd prototype/ && nohup node server.cjs &>/dev/null &
```
2. **创建截图目录**(如不存在):
```bash
mkdir -p prototype/screenshots/coverage-check/
```
3. **对每个非 backend 的检查项执行验证**
**第一步:导航与截图**
```
使用 Playwright MCP
- mcp__playwright__browser_navigate
url: http://localhost:8080/{proto_page_path}
- mcp__playwright__browser_take_screenshot
filename: prototype/screenshots/coverage-check/{check_id}.png
fullPage: true
```
**第二步:视觉验证(自适应选择方式)**
> 如果当前是视觉模型(如 Claude
> - 直接 Read 截图文件 `prototype/screenshots/coverage-check/{check_id}.png`
> 如果当前是非视觉模型:
> - 调用 `mcp__zai-mcp-server__analyze_image`
> - image_source: `prototype/screenshots/coverage-check/{check_id}.png`
**统一的视觉验证提示词模板**
```
请分析这张网页截图,判断以下需求是否在页面上得到了体现:
需求描述:{检查项描述}
请按以下格式输出你的判断:
判定结果:[✅通过 / ⚠️部分满足 / ❌不满足]
理由:[用1-2句话简要说明理由]
缺失说明:[如果未通过,说明具体缺少什么元素]
```
**第三步:记录验证结果**
- 从模型输出中提取判定结果、理由、缺失说明
- 将结果与检查项关联存储
4. **对于 behavior 类型的检查项(额外交互验证)**
```
使用 Playwright MCP 执行交互操作:
- 定位交互元素(按钮、链接等)
- 执行点击操作
- 再次截图验证状态变化
- 按上述相同方式进行视觉分析
```
---
### 9.6 结果汇总与覆盖度计算
#### 9.6.1 FR 覆盖状态判定规则
一个 FR 被判定为 ✅ 完整覆盖,当且仅当:
> 所有关联的检查项ui-element + navigation + behavior**≥ 70% 为 ✅ 通过**
判定为 ⚠️ 部分覆盖:
> 30% ~ 70% 的检查项通过
判定为 ❌ 未覆盖:
> < 30% 的检查项通过,或无对应原型页面,或所有 UI 检查项均不通过
#### 9.6.2 统计计算
1. **Checklist 级别统计**(仅模式 A
- 计算各状态(✅/⚠️/❌/⏭️)的检查项数量和占比
- 按模块分组统计每个模块的检查项通过数和通过率
2. **FR 级别统计**(两种模式都需要):
- 将检查结果映射到对应的 FR
- 按上述判定规则计算每个 FR 的覆盖状态
- 统计各状态的 FR 数量和占比
- 按模块分组统计每个模块的 FR 覆盖数和覆盖率
3. **计算总体指标**
- Checklist 总通过率(模式 A
- FR 总体覆盖率
- P0 优先级 FR 的覆盖率(核心指标)
---
### 9.7 生成 COVERAGE-REPORT.md
**报告必须包含以下所有章节,按顺序输出**
#### 报告结构模板:
```markdown
# 需求覆盖度检查报告
## 📋 验证模式信息
- **模式**: {精准验证 / FR 级验证} | 精度: {高 / 中}
- **数据源**: {列出使用的文件19 个 epic-journeys.md + prd.md}
- **检查时间**: {ISO 日期}
---
## 📊 概览统计
{{#if 模式 A}}
### Checklist 级别覆盖度
| 状态 | 数量 | 占比 |
|------|------|------|
| ✅ 通过 | {passed_count} | {passed_pct}% |
| ⚠️ 部分满足 | {partial_count} | {partial_pct}% |
| ❌ 不满足 | {failed_count} | {failed_pct}% |
| ⏭️ 跳过(后端逻辑)| {skipped_count} | {skipped_pct}% |
- 检查模块: {module_count} 个
- 检查旅程: {journey_count} 个
- 验收标准 Checklist: {checklist_total} 项
{{/if}}
### FR 级别覆盖度
| 状态 | 数量 | 占比 |
|------|------|------|
| ✅ 完整覆盖 | {fr_covered_count} | {fr_covered_pct}% |
| ⚠️ 部分覆盖 | {fr_partial_count} | {fr_partial_pct}% |
| ❌ 未覆盖 | {fr_missing_count} | {fr_missing_pct}% |
- 总 FR 数量: 313
- 涉及原型页面: {page_count} 个
## 📈 总体覆盖度可视化
[使用 ASCII 条形图展示前 10 个模块的 FR 覆盖率对比,示例:]
用户认证与授权: ██████████ 90%
多租户工作空间: ████████░░ 80%
...
## 📋 按模块覆盖率排名
| 排名 | 模块 | 检查项总数 | 通过 | 通过率 | FR 总数 | 已覆盖 | FR 覆盖率 | 状态 |
|------|------|-----------|------|--------|---------|--------|-----------|------|
| 1 | {模块名1} | {n} | {m} | {x}% | {y} | {z} | {w}% | ✅ |
| 2 | {模块名2} | {n} | {m} | {x}% | {y} | {z} | {w}% | ✅ |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
## 🔍 未通过检查项详细清单
{{#if 模式 A}}
### Epic {n}: {模块名称}
| Journey | 检查项描述 | 对应 FR | 检查结果 | 缺失说明 |
|---------|-----------|---------|---------|---------|
| {journey_id} {journey_name} | {检查项文本} | {FR 列表} | {✅/⚠️/❌} | {具体缺失说明} |
{{/if}}
{{#if 模式 B}}
### 模块 {n}: {模块名称}
| FR ID | FR 描述 | 优先级 | 覆盖状态 | 缺失说明 |
|-------|---------|--------|---------|---------|
| {FR 编号} | {FR 描述} | {P0/P1} | {✅/⚠️/❌} | {具体缺失说明} |
{{/if}}
## ❌ 未覆盖 / 部分覆盖 FR 清单
### P0 优先级({count} 个)
| FR ID | 需求描述 | 对应模块 | 覆盖状态 | 缺失原因 | 改进建议 |
|-------|---------|---------|---------|---------|---------|
| {FR 编号} | {FR 描述} | {模块名} | {状态} | {原因} | {建议} |
### P1 优先级({count} 个)
[同上格式]
## 🚀 改进建议(按优先级排序)
### 高优先级(阻塞原型评审)
1. **补充页面**: {具体描述Epic X 模块的 Y 功能缺少对应原型页面(影响 Z 个 P0 FR}
2. **完善 UI**: {具体描述,如:登录页补充"获取验证码"倒计时效果FR1}
3. **补充字段**: {具体描述,如:用户管理表格需补充"注册时间"、"最后登录"列}
### 中优先级(建议完善)
1. {具体建议}
2. ...
## ✅ 检查结论
- **总体 Checklist 通过率**: {checklist_pct}%
- **总体 FR 覆盖率**: {fr_pct}%
- **核心模块P0 FR覆盖率**: {p0_pct}%
- **建议补充页面**: {n} 个
- **建议完善 UI 元素**: {m} 项
- **建议补充交互效果**: {k} 项
---
*报告生成基于: {使用的数据源列表19 个 epic-journeys.md + 30 个原型页面}*
```
---
### 9.8 更新状态文件
完成报告生成后,**必须**更新 `prototype/.prototype-state.md`
1. 在 `completed_steps` 中添加:
```yaml
- step: step-09-coverage-check
evidence: "完成需求覆盖度检查,生成了 COVERAGE-REPORT.md。模式{模式},总体 FR 覆盖率:{pct}%"
```
2. 在 YAML 头部新增 `coverage_check` 字段:
```yaml
coverage_check:
completed_at: {ISO 时间戳}
mode: {precise | fr-level}
data_sources: {使用的数据源简要描述}
total_fr: 313
covered_fr: {已覆盖的 FR 数量}
coverage_pct: {百分比数值}
report_path: prototype/COVERAGE-REPORT.md
```
3. 更新 `last_updated` 时间戳
---
## 🔒 门禁条件(必须满足才能标记完成)
### 通用门禁
1. ✅ 已完整 Read 当前步骤文件
2. ✅ PRD 文件存在且成功解析
3. ✅ 至少 70% 的 FR 成功映射到原型页面
4. ✅ 页面存在性检查完成
5. ✅ `prototype/COVERAGE-REPORT.md` 文件已生成
6. ✅ 报告包含所有必要章节和统计数据
7. ✅ 状态文件 `completed_steps` 包含 evidence 字段
8. ✅ 状态文件已更新 `coverage_check` 字段
### 模式 A 额外门禁(精准验证)
1. ✅ 至少解析了 5 个以上 **epic-journeys.md** 文件(来源文件名中必须包含 "epic-"
2. ✅ 至少提取了 100 个以上的 Checklist 检查项
3. ✅ **验证主数据源正确性**:检查项列表前 5 个的来源文件名必须含 "epic-"
4. ✅ 报告中每个检查项都标注了来源文件名
5. ✅ 数据源断言的输出已记录在 evidence 中
### ❌ 禁止的替代行为
- ❌ 只检查文件存在性,不进行视觉验证
- ❌ 跳过图片分析直接声称"覆盖度 100%"
- ❌ 不生成报告文件
- ❌ 不更新状态文件
---
## 下一步
完成所有门禁检查后,加载 `steps/step-08-commit.md` 执行提交。