Based on real execution review (shandong-intent-sync), apply phase suffered from 4-5 rework cycles due to insufficient upfront research. Changes: - grill: add technical implementation dimension to question pool - apply: add mandatory pre-apply checkpoint (15-20min research) - read reference implementations thoroughly - grep key tech stack patterns - form tech stack checklist in decisions.md - apply: add incremental implementation guidance - apply: add first-module alignment check - apply: add fast-fail rule (≥2 rework → pause) Expected impact: - Rework: 4-5 cycles → 0-1 cycle (-80%) - Core feature empty impl: 100% → 0% - ROI: 200% (invest 20min, save 60min) Complexity: +55 lines to phase-contracts.md (+20%) Approach: simplified version (plan B) to balance value vs overhead Docs: - phase-contracts.md: updated grill + apply phases - workflow.md: added v4.1 evolution chapter - phase-contracts-v4.1-changelog.md: detailed change log - sm-flow-execution-review-shandong-intent-sync.md: source review
293 lines
8.8 KiB
Markdown
293 lines
8.8 KiB
Markdown
# SM Flow 执行复盘 - 山东商客意向单同步接口
|
||
|
||
> 项目: yingke-platform
|
||
> 需求: 385 山东公司商机信息同步接口
|
||
> 执行日期: 2026-06-23
|
||
> 复盘人: Claude Code
|
||
|
||
---
|
||
|
||
## 执行概况
|
||
|
||
- **需求规模**: 中等(3个接口 + Kafka消费 + 数据库变更)
|
||
- **总耗时**: 约 2 小时(含多次返工)
|
||
- **返工次数**: 4-5 次重大返工
|
||
- **最终状态**: 核心代码完成,但验签/解密/查询接口未实现
|
||
|
||
---
|
||
|
||
## 发现的问题
|
||
|
||
### 1. 前置调研不足,导致多次返工
|
||
|
||
#### 问题表现
|
||
|
||
| 返工点 | 初次实现(错误) | 返工后(正确) | 浪费时间 |
|
||
|--------|------------------|----------------|----------|
|
||
| RequestMsg 结构 | 自创 `SyncIntentOrderReq/Resp` | 使用项目标准 `RequestMsg<T>` | 15 分钟 |
|
||
| Kafka 发送方式 | `SendMessageTunnel` + `TaskTypeEnum` | `ykMqTemplate` + `@YkMsg` | 20 分钟 |
|
||
| Consumer 模块位置 | order-service 模块 | web 模块(参考案例位置) | 10 分钟 |
|
||
| 透传字段结构 | Map → DTO → 最终平铺 | 应一次到位平铺到 Msg | 15 分钟 |
|
||
|
||
**根本原因**: apply 阶段直接开始写代码,没有充分调研现有代码模式。
|
||
|
||
#### 改进建议
|
||
|
||
**在 apply 阶段前增加强制调研步骤**(pre-apply research checkpoint):
|
||
|
||
1. **阅读所有参考实现**(设计文档中明确提到的)
|
||
- 完整阅读参考代码,而不是凭想象
|
||
- 提取关键模式:请求结构、Kafka 使用、模块划分
|
||
|
||
2. **Grep 关键技术栈**
|
||
```bash
|
||
grep -r "@YkMsg" --include="*.java"
|
||
grep -r "ykMqTemplate" --include="*.java"
|
||
grep -r "RequestMsg<" --include="*.java"
|
||
```
|
||
|
||
3. **形成"技术栈清单"文档**(临时产物)
|
||
```markdown
|
||
- 项目使用 RequestMsg<T> 作为统一请求包装
|
||
- Kafka 消息使用 @YkMsg + MsgData + ykMqTemplate.sendAsync()
|
||
- Consumer 统一放在 web 模块的 manager/stream/consumer
|
||
```
|
||
|
||
4. **调研时间要求**: 不少于 15 分钟,复杂需求可延长至 30 分钟
|
||
|
||
---
|
||
|
||
### 2. 设计文档与实现偏离,缺少一致性检查
|
||
|
||
#### 问题表现
|
||
|
||
| 设计文档要求 | 实际实现 | 偏离程度 |
|
||
|--------------|----------|----------|
|
||
| Controller 层 SM3 验签 | 只有 TODO 注释 | ❌ 核心功能缺失 |
|
||
| Service 层 AES256-GCM 解密 | 只有 TODO 注释 | ❌ 核心功能缺失 |
|
||
| queryIntentOrder 调用一体化客服 | 空实现 | ❌ 核心功能缺失 |
|
||
| syncIntentOrder 同步调用 | 改为 Kafka 异步 | ⚠️ 架构差异(可能合理) |
|
||
|
||
**根本原因**: apply 阶段没有"设计-实现对齐检查点"。
|
||
|
||
#### 改进建议
|
||
|
||
**在 apply 阶段中增加对齐检查点**(alignment checkpoint):
|
||
|
||
1. **每完成 1 个接口/模块,立即对比设计文档**
|
||
- 逐条核对设计文档的任务清单
|
||
- 标记"已完成/部分完成/TODO"
|
||
|
||
2. **核心功能不允许"TODO 占位"直接通过**
|
||
- 加密/解密、验签、核心业务逻辑必须实现或明确标注"待联调"
|
||
- 区分"框架完整但待联调"(✅) vs "空实现"(❌)
|
||
|
||
3. **架构差异必须显式记录并询问用户**
|
||
- 设计说同步,实现改异步 → 必须记录原因并确认
|
||
- 创建 `decisions.md` 记录所有偏离设计的架构决策
|
||
|
||
---
|
||
|
||
### 3. 分步验证不足,一次写太多代码
|
||
|
||
#### 问题表现
|
||
|
||
- 一次性写完 Controller + Service + Kafka + Consumer,然后发现 RequestMsg 结构错了
|
||
- 没有"写一点 → 编译 → 确认方向"的小步迭代
|
||
|
||
#### 改进建议
|
||
|
||
**强制分步验证**(incremental validation):
|
||
|
||
1. **Controller 层先行**
|
||
- 只写 Controller + 最小 Service 骨架
|
||
- 确认请求/响应结构正确
|
||
- 编译通过后再继续
|
||
|
||
2. **Kafka 发送独立验证**
|
||
- 写完发送逻辑,先打印 JSON 确认消息格式
|
||
- 再写 Consumer
|
||
|
||
3. **Consumer 最后实现**
|
||
- 基于已确认的消息格式实现
|
||
|
||
---
|
||
|
||
### 4. 参考案例利用不充分
|
||
|
||
#### 问题表现
|
||
|
||
- 设计文档明确提到"参考 AddIntentOrderOutSystemDealTunnel"
|
||
- 但实际执行时,直到用户提醒才去看参考实现
|
||
- 之前都在凭想象写,导致返工
|
||
|
||
#### 改进建议
|
||
|
||
**强制参考案例优先**(reference-first approach):
|
||
|
||
1. **grill 阶段就应该找出所有参考案例**
|
||
- 不要只记录"参考 XXX",而是实际阅读并提取模式
|
||
|
||
2. **apply 前必须完整阅读参考实现**
|
||
- 不是"扫一眼",而是逐行理解关键逻辑
|
||
- 提取可复用的代码片段
|
||
|
||
3. **参考案例模式提取清单**(临时文档)
|
||
```markdown
|
||
## AddIntentOrderOutSystemDealTunnel 关键模式
|
||
|
||
1. Consumer 方法签名: `public void onXXX(XXXMsg msgBO)`
|
||
2. 调用链: msg → AES加密 → OnlineOpportunityApi → 回填状态
|
||
3. 异常处理: try-catch → updateStatus(EXCEPTION) → throw
|
||
4. 成功判断: isSyncSuccess() 三层校验
|
||
```
|
||
|
||
---
|
||
|
||
### 5. grill 阶段澄清不够深入
|
||
|
||
#### 问题表现
|
||
|
||
- grill 阶段问了业务问题(省份校验、透传字段),但没有问技术实现问题
|
||
- 导致后续实现时才发现技术栈不熟悉
|
||
|
||
#### 改进建议
|
||
|
||
**grill 阶段增加技术实现澄清**:
|
||
|
||
除了业务澄清,还应该包括:
|
||
|
||
1. **技术栈确认问题**
|
||
- "项目现有的 Kafka 消息怎么定义和发送?"
|
||
- "RequestMsg/ResponseMsg 的标准用法是什么?"
|
||
- "类似接口的 Controller/Service 是怎么写的?"
|
||
|
||
2. **参考实现确认**
|
||
- "设计文档提到的参考实现是哪些文件?"
|
||
- "这些参考实现的核心模式是什么?"
|
||
|
||
3. **技术风险识别**
|
||
- "有哪些技术点我不熟悉,需要先调研?"
|
||
|
||
---
|
||
|
||
## 改造建议汇总
|
||
|
||
### 方案 A: 在现有 9 阶段中增强(保守)
|
||
|
||
```
|
||
clarify → context → propose → grill+ → specify → audit → commit → pre-apply+ → apply+ → archive
|
||
↑ ↑ ↑
|
||
增加技术澄清 增加调研 增加检查点
|
||
```
|
||
|
||
**修改点**:
|
||
|
||
1. **grill 阶段**:增加技术实现澄清问题模板
|
||
2. **apply 阶段前**:增加 pre-apply research checkpoint(15-30分钟)
|
||
3. **apply 阶段中**:增加 alignment checkpoint(每完成1个模块对比设计文档)
|
||
|
||
### 方案 B: 新增独立调研阶段(激进)
|
||
|
||
```
|
||
clarify → context → propose → grill → research → specify → audit → commit → apply → archive
|
||
↑
|
||
新增独立调研阶段
|
||
```
|
||
|
||
**新阶段 research**:
|
||
|
||
- **输入**: proposal + 参考实现列表
|
||
- **输出**: 技术栈清单 + 参考模式提取 + 风险评估
|
||
- **时间**: 15-30 分钟
|
||
- **产物**: `research.md`(临时文档,archive 时删除)
|
||
|
||
**research.md 结构**:
|
||
|
||
```markdown
|
||
# 技术调研 - [需求名称]
|
||
|
||
## 参考实现分析
|
||
|
||
### AddIntentOrderOutSystemDealTunnel
|
||
- 文件位置: web/manager/stream/consumer/...
|
||
- 关键模式:
|
||
- Consumer 定义: @YkMqConsumer + MsgData 子类
|
||
- 调用链: ...
|
||
|
||
## 技术栈清单
|
||
|
||
- 请求结构: RequestMsg<T> / ResponseMsg<T>
|
||
- Kafka: @YkMsg + ykMqTemplate.sendAsync()
|
||
- 加密: AESUtil.encryptAES() (AES-128 ECB)
|
||
|
||
## 风险点
|
||
|
||
- AES256-GCM 工具类不存在,需要新建
|
||
- 验签逻辑没有现成拦截器,需要在 Service 层实现
|
||
```
|
||
|
||
### 推荐方案
|
||
|
||
**方案 A**(渐进增强):
|
||
|
||
1. 对现有流程影响小
|
||
2. 实施成本低
|
||
3. 可以立即生效
|
||
|
||
**具体实施**:
|
||
|
||
- 修改 `phase-contracts.md` 的 grill 和 apply 阶段规范
|
||
- 增加 checkpoint 描述
|
||
- 更新 question pool 增加技术澄清问题
|
||
|
||
---
|
||
|
||
## 其他建议
|
||
|
||
### 1. 增加"快速失败"机制
|
||
|
||
当发现以下情况,立即暂停并询问用户:
|
||
|
||
- 需要创建的类/接口在参考实现中有类似的(防止重复造轮)
|
||
- 实现方式与设计文档明显偏离
|
||
- 连续返工超过 2 次(说明方向可能错了)
|
||
|
||
### 2. 产物可观测性增强
|
||
|
||
在 apply 阶段,定期输出:
|
||
|
||
```markdown
|
||
## 实现进度(每 30 分钟更新)
|
||
|
||
✅ Controller 层(已完成)
|
||
- ShandongSyncController.syncIntentOrder
|
||
- 请求结构使用 RequestMsg<ShandongIntentOrderData>
|
||
|
||
🚧 Service 层(进行中)
|
||
- ShandongSyncService 接口完成
|
||
- 实现类 70% 完成
|
||
- ⚠️ 验签解密未实现(TODO)
|
||
|
||
⏳ Kafka 层(待开始)
|
||
```
|
||
|
||
### 3. 设计文档质量要求
|
||
|
||
设计文档应该包含:
|
||
|
||
- ✅ 参考实现的具体文件路径(而不是只说"参考 XXX")
|
||
- ✅ 关键技术栈的使用示例(而不是只说"使用 Kafka")
|
||
- ✅ 数据流图(清晰展示同步/异步边界)
|
||
|
||
---
|
||
|
||
## 总结
|
||
|
||
**核心问题**: apply 阶段"想当然"开始写代码,缺少充分调研和分步验证。
|
||
|
||
**解决方向**: 在 apply 前增加强制调研步骤,在 apply 中增加对齐检查点。
|
||
|
||
**预期效果**: 返工次数从 4-5 次降低到 0-1 次,实现质量与设计文档一致性提升。
|
||
|
||
**立即可做**: 修改 `phase-contracts.md` 的 grill 和 apply 阶段规范即可生效。 |