# 前端需求筛选强制集成 - 变更日志

## 概述

实现了当用户说"开发 XX 版本"时，**强制调用 `fe-requirement-filter` skill 进行需求拆分**的功能。

## 修改文件清单

### 1. src/steps/runGuard.ts

**新增函数**：
```typescript
async function injectFrontendFilterFlag(outputRoot: string, product: string): Promise<void>
```

**功能**：
- 在 `guard/invoke` 成功后自动注入 `.fe-filter-required.json` 标记文件
- 标记状态初始为 `pending`，需要 skill 执行后更新为 `completed`

**修改位置**：
- 导入新增：`import fs from "fs/promises"`
- 在 `runGuard()` 函数中，`applyInvokeTextToSession` 之后调用

**代码片段**：
```typescript
if (!options.dryRun) {
  await applyInvokeTextToSession(options.projectRoot, result.runId, text);
  
  // 强制注入前端需求筛选步骤标记
  await injectFrontendFilterFlag(result.outputRoot, parsed.product);
}
```

---

### 2. src/steps/runGate.ts

**新增门禁类型**：
```typescript
export type GateExpect =
  | "prd-fetched"
  | "fe-filter-done"  // 新增
  | "questions-open"
  // ...
```

**新增门禁检查逻辑**：
```typescript
if (options.expect === "fe-filter-done") {
  // 4 项检查：
  // 1. .fe-filter-required.json 存在且格式正确
  // 2. status 字段为 completed
  // 3. source/PRD-frontend.md 存在且非空
  // 4. .fe-filter-report.json 存在（可选）
}
```

**检查项明细**：

| 检查名称 | 检查内容 | 失败提示 |
|---------|---------|---------|
| `fe-filter-flag` | 标记文件存在且可解析 | 缺少/格式错误 |
| `fe-filter-required` | `required: true` | 未标记为强制 |
| `fe-filter-status` | `status: completed` | 状态为 pending，需调用 skill |
| `frontend-prd-exists` | PRD-frontend.md 存在且 >100 字符 | 文件缺失或内容过少 |
| `fe-filter-report` | 报告文件存在 | 缺少筛选报告（警告级别） |

---

### 3. src/templates/artifacts/NEXT-with-prd-enrich.template.md

**新增步骤 0**：前端需求筛选（强制步骤）

**位置**：在原步骤 1（补全 PRD 细节层）之前

**内容**：
```markdown
### 0. 前端需求筛选（强制步骤）

**🔴 强制执行**：在生成验收清单（05）之前，必须先筛选出纯前端需求。

**触发标记**：检测到 `.fe-filter-required.json` 文件，状态为 `pending`

**执行方式**：
- 在 AI 工具中调用 `fe-requirement-filter` skill
- 或手动触发："提取前端需求"、"过滤前端需求"

**输出**：
- `source/PRD-frontend.md`（纯前端需求文档）
- `.fe-filter-report.json`（筛选报告）

**完成标记**：
更新 .fe-filter-required.json 状态为 completed

**门禁检查**：
npx sdd-flow-kit gate --run-id {{RUN_ID}} --expect fe-filter-done
```

**修改说明**：
- 原有步骤 1-3 的编号保持不变
- 在步骤 3 的 `prd-review` 命令后添加注释，说明优先从 `PRD-frontend.md` 提取原子

---

### 4. docs/fe-requirement-filter-integration.md（新增）

**内容**：
- 功能说明
- 触发流程图
- 工作机制详解
- 使用步骤（5 步走）
- 生成文件说明
- 集成到现有项目
- 故障排查
- 最佳实践
- 技术细节

---

## 工作流程图

```
用户：开发 ADI V2.3.4
    ↓
guard 识别版本意图
    ↓
写入 .fe-filter-required.json (status: pending)
    ↓
生成 NEXT.md，包含强制步骤 0
    ↓
AI 读取 NEXT.md
    ↓
AI 调用 fe-requirement-filter skill
    ↓
生成 PRD-frontend.md + .fe-filter-report.json
    ↓
更新 .fe-filter-required.json (status: completed)
    ↓
gate fe-filter-done 通过
    ↓
继续生成 05 验收清单
```

---

## 生成的文件

### openspec/PRD/<runId>/.fe-filter-required.json

**初始状态**（guard 自动生成）：
```json
{
  "required": true,
  "product": "ADI",
  "reason": "版本开发强制要求先筛选前端需求",
  "createdAt": "2024-01-01T00:00:00.000Z",
  "status": "pending"
}
```

**完成状态**（skill 更新）：
```json
{
  "required": true,
  "product": "ADI",
  "reason": "版本开发强制要求先筛选前端需求",
  "createdAt": "2024-01-01T00:00:00.000Z",
  "status": "completed",
  "completedAt": "2024-01-01T01:00:00.000Z"
}
```

### openspec/PRD/<runId>/source/PRD-frontend.md

纯前端需求文档（skill 生成）

### openspec/PRD/<runId>/.fe-filter-report.json

筛选报告（skill 生成）：
```json
{
  "filteredAt": "2024-01-01T01:00:00.000Z",
  "kept": 45,
  "removed": 23,
  "pending": 3
}
```

---

## 命令行使用

### 触发版本开发

```bash
npx sdd-flow-kit guard "开发 ADI V2.3.4版本" -y --agent cursor
```

### 检查筛选状态

```bash
npx sdd-flow-kit gate --run-id <runId> --expect fe-filter-done
```

### 手动完成标记（应急）

```bash
echo '{"required":true,"status":"completed","completedAt":"'$(date -u +"%Y-%m-%dT%H:%M:%SZ")'"}' > \
  openspec/PRD/<runId>/.fe-filter-required.json
```

---

## 与 fe-requirement-filter skill 的配合

### skill 需要做的事

1. **读取输入**：
   - `source/PRD.md`（完整需求）
   - `.fe-filter-required.json`（确认是否需要筛选）

2. **执行筛选**：
   - 按判定标准（前端信号 vs 后端信号）
   - 保留前端条目，剔除后端条目
   - 记录待确认条目

3. **生成输出**：
   - `source/PRD-frontend.md`（筛选后文档）
   - `.fe-filter-report.json`（报告）

4. **更新状态**：
   ```typescript
   // 更新 .fe-filter-required.json
   {
     ...existingFlag,
     status: "completed",
     completedAt: new Date().toISOString()
   }
   ```

### skill 执行示例

```typescript
// 伪代码
async function executeFeRequirementFilter() {
  // 1. 读取标记
  const flag = JSON.parse(readFile(".fe-filter-required.json"));
  if (flag.status === "completed") {
    return "已完成，跳过";
  }
  
  // 2. 读取完整 PRD
  const prd = readFile("source/PRD.md");
  
  // 3. 筛选
  const { kept, removed, pending } = filterFrontendRequirements(prd);
  
  // 4. 生成文档
  writeFile("source/PRD-frontend.md", kept.join("\n"));
  
  // 5. 生成报告
  writeFile(".fe-filter-report.json", JSON.stringify({
    filteredAt: new Date().toISOString(),
    kept: kept.length,
    removed: removed.length,
    pending: pending.length
  }));
  
  // 6. 更新状态
  writeFile(".fe-filter-required.json", JSON.stringify({
    ...flag,
    status: "completed",
    completedAt: new Date().toISOString()
  }));
}
```

---

## 兼容性

### 向后兼容

- ✅ 已有项目升级后，只影响新触发的版本开发
- ✅ 旧的 runId 不受影响
- ✅ 不强制时（`required: false`）跳过检查

### 可选配置

在 `.session-state.json` 中可以禁用：
```json
{
  "feFilterRequired": false
}
```

---

## 测试场景

### 场景 1：正常流程

1. 执行 `guard "开发 ADI V2.3.4"`
2. 标记文件自动生成，状态 `pending`
3. AI 读取 NEXT.md，看到强制步骤 0
4. 用户说"提取前端需求"
5. skill 执行，生成 PRD-frontend.md
6. 状态更新为 `completed`
7. `gate fe-filter-done` 通过
8. 继续后续流程

### 场景 2：忘记筛选

1. 执行 `guard "开发 OMS V1.24.5"`
2. 用户直接跳到生成 05
3. `gate docs-closed` 前置检查 `gate fe-filter-done`
4. ❌ 失败：状态为 `pending`
5. 提示用户调用 skill
6. 用户补充执行
7. ✅ 通过

### 场景 3：PRD 已是纯前端

1. 执行 `guard "开发 欢盟 V2.1.0"`
2. PRD 全部为前端需求
3. skill 执行，保留全部条目
4. 生成 PRD-frontend.md（与原 PRD 相同）
5. ✅ 通过

### 场景 4：手动跳过

1. 用户确认不需要筛选
2. 手动更新状态：
   ```bash
   echo '{"required":true,"status":"skipped","reason":"PRD已审核为纯前端"}' > \
     .fe-filter-required.json
   ```
3. `gate fe-filter-done` 检查到 `skipped`
4. ⚠️ 警告通过（需人工确认理由）

---

## 未来优化

1. **自动判断是否需要筛选**：
   - 分析 PRD 内容，自动判断是否混合
   - 纯前端文档自动标记 `skipped`

2. **增强报告**：
   - 列出具体剔除的条目标题
   - 提供条目级别的判定理由

3. **集成到 UI**：
   - 在 Cursor/Claude 中可视化展示筛选进度
   - 提供待确认条目的交互式裁定界面

4. **多轮迭代**：
   - 支持筛选后再次调整
   - 版本化 PRD-frontend.md

---

## 维护者注意事项

### 代码审查要点

1. ✅ `injectFrontendFilterFlag` 异常处理
2. ✅ `gate fe-filter-done` 各检查项的判定逻辑
3. ✅ NEXT.md 模板中步骤编号一致性
4. ✅ 文档与代码同步更新

### 测试覆盖

需要补充单元测试：
- `runGuard` 标记文件生成
- `runGate` fe-filter-done 各项检查
- 边界情况：文件不存在、格式错误、状态异常

---

## 问题反馈

如有问题，请提供以下信息：
1. 完整命令
2. `.fe-filter-required.json` 内容
3. `.fe-filter-report.json` 内容（如果有）
4. `gate fe-filter-done` 输出

---

**版本**：v1.4.0  
**日期**：2024-01-15  
**作者**：SDD Flow Kit Team
