@chenguangyao/devflow-kit 0.1.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +232 -0
- package/LICENSE +21 -0
- package/README.md +539 -0
- package/bin/devflow.js +9 -0
- package/docs/RFC-001-devflow-kit.md +617 -0
- package/docs/RFC-002-workflow-kernel.md +134 -0
- package/docs/enterprise-integration-supplement.md +274 -0
- package/docs/internal-gitlab-setup.md +426 -0
- package/docs/marketplace-skills.md +231 -0
- package/docs/migration-from-arb.md +232 -0
- package/docs/tooling-overview.md +774 -0
- package/docs/workflow-orchestration.md +695 -0
- package/docs/workflow-ui-prototype.html +271 -0
- package/package.json +52 -0
- package/schemas/config.schema.json +51 -0
- package/schemas/delta.schema.json +22 -0
- package/schemas/state.schema.json +130 -0
- package/schemas/status-surface.schema.json +197 -0
- package/schemas/workflow-confirmation-surface.schema.json +70 -0
- package/schemas/workflow-picker.schema.json +94 -0
- package/scripts/postinstall.js +101 -0
- package/scripts/render-workflow-ui-prototype.js +271 -0
- package/skills/apply/SKILL.md +313 -0
- package/skills/apply/references/discipline-checklist.md +145 -0
- package/skills/apply/references/subagent-implementer-prompt.md +113 -0
- package/skills/apply/references/subagent-orchestration.md +150 -0
- package/skills/apply/references/subagent-reviewer-prompt.md +180 -0
- package/skills/apply/references/tdd-loop.md +287 -0
- package/skills/apply/references/when-plan-is-wrong.md +279 -0
- package/skills/apply/references/worktree-swarm.md +292 -0
- package/skills/archive/SKILL.md +229 -0
- package/skills/archive/references/conflict-resolution.md +336 -0
- package/skills/archive/references/knowledge-deposit.md +381 -0
- package/skills/archive/references/spec-merge.md +365 -0
- package/skills/brainstorm/SKILL.md +123 -0
- package/skills/brainstorm/references/proposal-template.md +244 -0
- package/skills/brainstorm/references/question-catalog.md +168 -0
- package/skills/brainstorm/references/session-template.md +184 -0
- package/skills/ci-fix/SKILL.md +63 -0
- package/skills/ci-fix/references/loop.md +25 -0
- package/skills/code-review/SKILL.md +279 -0
- package/skills/code-review/references/escalation-playbook.md +192 -0
- package/skills/code-review/references/language-cheatsheets/go.md +175 -0
- package/skills/code-review/references/language-cheatsheets/java-spring-mybatis.md +246 -0
- package/skills/code-review/references/language-cheatsheets/python.md +170 -0
- package/skills/code-review/references/language-cheatsheets/vue.md +199 -0
- package/skills/code-review/references/output-template.md +275 -0
- package/skills/code-review/references/review-checklist.md +251 -0
- package/skills/complexity-grading/SKILL.md +259 -0
- package/skills/deliver/SKILL.md +271 -0
- package/skills/deliver/references/delivery-modes.md +299 -0
- package/skills/deliver/references/notify.md +359 -0
- package/skills/deliver/references/pr-description.md +319 -0
- package/skills/dependency-upgrade/SKILL.md +57 -0
- package/skills/dependency-upgrade/references/risk-matrix.md +38 -0
- package/skills/df-orchestrator/SKILL.md +407 -0
- package/skills/df-orchestrator/references/complexity-grading.md +177 -0
- package/skills/df-orchestrator/references/escalation-matrix.md +191 -0
- package/skills/df-orchestrator/references/routing-rules.md +290 -0
- package/skills/df-orchestrator/references/workflow-state-machine.md +208 -0
- package/skills/frontend-quality/SKILL.md +61 -0
- package/skills/frontend-quality/references/checklist.md +35 -0
- package/skills/handoff-resume/SKILL.md +59 -0
- package/skills/handoff-resume/references/handoff-template.md +54 -0
- package/skills/plan/SKILL.md +166 -0
- package/skills/plan/references/task-breakdown.md +207 -0
- package/skills/plan/references/task-sequencing.md +143 -0
- package/skills/plan/references/task-template.md +248 -0
- package/skills/requirement-analysis/SKILL.md +499 -0
- package/skills/requirement-analysis/references/acceptance-criteria.md +183 -0
- package/skills/requirement-analysis/references/code-recon.md +151 -0
- package/skills/requirement-analysis/references/edge-case-catalog.md +164 -0
- package/skills/requirement-analysis/references/requirement-template.md +339 -0
- package/skills/requirement-analysis/references/scope-negotiation.md +162 -0
- package/skills/security-hardening/SKILL.md +60 -0
- package/skills/security-hardening/references/checklist.md +42 -0
- package/skills/tech-spec/SKILL.md +388 -0
- package/skills/tech-spec/references/api-contract-design.md +172 -0
- package/skills/tech-spec/references/decision-records.md +110 -0
- package/skills/tech-spec/references/design-template.md +301 -0
- package/skills/tech-spec/references/rollout-and-rollback.md +203 -0
- package/skills/tech-spec/references/spec-delta-conventions.md +250 -0
- package/skills/tech-spec/references/transaction-patterns.md +212 -0
- package/skills/test-spec/SKILL.md +219 -0
- package/skills/test-spec/references/coverage-strategy.md +218 -0
- package/skills/test-spec/references/edge-case-to-test.md +143 -0
- package/skills/test-spec/references/test-case-template.md +276 -0
- package/skills/verify/SKILL.md +232 -0
- package/skills/verify/references/nfr-verification.md +292 -0
- package/skills/verify/references/report-templates.md +510 -0
- package/skills/verify/references/self-test-guide.md +240 -0
- package/skills/verify/references/verify-rollback-map.md +247 -0
- package/src/cli/commands/_helpers.js +108 -0
- package/src/cli/commands/_submit.js +718 -0
- package/src/cli/commands/apply.js +198 -0
- package/src/cli/commands/archive.js +180 -0
- package/src/cli/commands/checkpoint.js +113 -0
- package/src/cli/commands/deliver.js +377 -0
- package/src/cli/commands/deploy.js +504 -0
- package/src/cli/commands/design.js +158 -0
- package/src/cli/commands/disable.js +21 -0
- package/src/cli/commands/doctor.js +178 -0
- package/src/cli/commands/enable.js +21 -0
- package/src/cli/commands/flow.js +645 -0
- package/src/cli/commands/help.js +93 -0
- package/src/cli/commands/ingest.js +602 -0
- package/src/cli/commands/init.js +341 -0
- package/src/cli/commands/knowledge.js +523 -0
- package/src/cli/commands/logs.js +43 -0
- package/src/cli/commands/new.js +202 -0
- package/src/cli/commands/plan.js +49 -0
- package/src/cli/commands/propose.js +27 -0
- package/src/cli/commands/provider.js +698 -0
- package/src/cli/commands/report.js +143 -0
- package/src/cli/commands/requirement.js +227 -0
- package/src/cli/commands/review.js +301 -0
- package/src/cli/commands/skills.js +457 -0
- package/src/cli/commands/status.js +925 -0
- package/src/cli/commands/switch.js +27 -0
- package/src/cli/commands/sync.js +47 -0
- package/src/cli/commands/test.js +366 -0
- package/src/cli/commands/uninstall.js +32 -0
- package/src/cli/commands/update.js +74 -0
- package/src/cli/commands/verify.js +354 -0
- package/src/cli/commands/worktree.js +78 -0
- package/src/cli/index.js +72 -0
- package/src/cli/parse-args.js +102 -0
- package/src/core/autodetect.js +271 -0
- package/src/core/change.js +208 -0
- package/src/core/checkpoint.js +217 -0
- package/src/core/config.js +60 -0
- package/src/core/delta.js +290 -0
- package/src/core/markers.js +59 -0
- package/src/core/paths.js +173 -0
- package/src/core/plan-tasks.js +36 -0
- package/src/core/project-routing.js +285 -0
- package/src/core/projects.js +200 -0
- package/src/core/state.js +200 -0
- package/src/core/workflow-check.js +177 -0
- package/src/core/workflow-init.js +34 -0
- package/src/core/workflow-picker.js +154 -0
- package/src/core/workflow-policy.js +119 -0
- package/src/core/workflow-suggest.js +181 -0
- package/src/core/workflow-verify.js +88 -0
- package/src/core/workflow.js +433 -0
- package/src/core/worktree.js +241 -0
- package/src/knowledge/categories.js +107 -0
- package/src/knowledge/classify.js +125 -0
- package/src/knowledge/deposit.js +414 -0
- package/src/knowledge/migrate.js +149 -0
- package/src/knowledge/mr.js +219 -0
- package/src/knowledge/query.js +131 -0
- package/src/knowledge/registry.js +151 -0
- package/src/knowledge/sync.js +179 -0
- package/src/providers/base.js +74 -0
- package/src/providers/drivers/api-yapi.js +78 -0
- package/src/providers/drivers/ci-jenkins.js +109 -0
- package/src/providers/drivers/intake-confluence.js +544 -0
- package/src/providers/drivers/kb-git.js +549 -0
- package/src/providers/drivers/kb-weknora.js +472 -0
- package/src/providers/drivers/notify-smtp.js +515 -0
- package/src/providers/drivers/observability-oss.js +43 -0
- package/src/providers/drivers/observability-sls.js +50 -0
- package/src/providers/lifecycle.js +135 -0
- package/src/providers/loader.js +132 -0
- package/src/providers/local.js +190 -0
- package/src/providers/userconfig.js +283 -0
- package/src/reports/aggregate.js +185 -0
- package/src/reports/coverage.js +163 -0
- package/src/reports/detect.js +143 -0
- package/src/reports/parse.js +236 -0
- package/src/templates/files/ci/github.yml +38 -0
- package/src/templates/files/ci/gitlab.yml +27 -0
- package/src/templates/files/design.md +63 -0
- package/src/templates/files/ide/devflow-workflow.md +58 -0
- package/src/templates/files/ide/project-overview-reference.md +1 -0
- package/src/templates/files/ide/project-overview.md +27 -0
- package/src/templates/files/knowledge-index.json +17 -0
- package/src/templates/files/knowledge.md +28 -0
- package/src/templates/files/meta.json +8 -0
- package/src/templates/files/plan.md +38 -0
- package/src/templates/files/proposal.md +33 -0
- package/src/templates/files/reports/contract-test.md +40 -0
- package/src/templates/files/reports/e2e-test.md +30 -0
- package/src/templates/files/reports/integration-test.md +36 -0
- package/src/templates/files/reports/joint-test.md +58 -0
- package/src/templates/files/reports/perf.md +24 -0
- package/src/templates/files/reports/regression.md +20 -0
- package/src/templates/files/reports/remote-test.md +55 -0
- package/src/templates/files/reports/self-test.md +43 -0
- package/src/templates/files/reports/smoke-test.md +22 -0
- package/src/templates/files/reports/unit-test.md +36 -0
- package/src/templates/files/requirement.md +51 -0
- package/src/templates/files/review.md +38 -0
- package/src/templates/files/tests.md +36 -0
- package/src/templates/files/verify.md +32 -0
- package/src/templates/index.js +21 -0
- package/src/utils/log.js +37 -0
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
# code-review / output-template
|
|
2
|
+
|
|
3
|
+
`code-review` skill 的三份产物:
|
|
4
|
+
|
|
5
|
+
1. `review.md` — 人类可读,每轮 append 一个 `## Round N` section。
|
|
6
|
+
2. `review.findings.json` — 机器可解析;`state.json.phases.review.rounds[N].findingsPath` 指向它,下一轮 apply 读它做自动定位。
|
|
7
|
+
3. `code-review-report.md` — 最终一次通过后产出,作为 `devflow verify` / `devflow deliver` 的硬前置(审计留档)。
|
|
8
|
+
|
|
9
|
+
`devflow review --round` 保证前两者同步写入;写失败整体 rollback,不留 partial 状态。
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## §1 `review.md` —— 每轮 section 模板
|
|
14
|
+
|
|
15
|
+
```markdown
|
|
16
|
+
---
|
|
17
|
+
round: 1 # 从 1 起算
|
|
18
|
+
reviewer: independent # 固定值,表明 context 隔离
|
|
19
|
+
baseBranch: master # 与 coder 的 worktree 对齐
|
|
20
|
+
commitRange: <base-sha>..<head-sha> # git diff 用到的范围
|
|
21
|
+
diffScope: api-change # data-layer | test-only | api-change | config-only | docs-only | full
|
|
22
|
+
iterationCount: 1 # = round
|
|
23
|
+
mustCount: 3
|
|
24
|
+
shouldCount: 2
|
|
25
|
+
nitCount: 1
|
|
26
|
+
outcome: back_to_apply # pass | back_to_apply | blocked | force-pass
|
|
27
|
+
createdAt: 2026-04-24T09:12:30+08:00
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 第 1 轮
|
|
31
|
+
|
|
32
|
+
### 0. 变更范围摘要
|
|
33
|
+
|
|
34
|
+
- 变更文件: 7 个(5 个 src,2 个 test)
|
|
35
|
+
- 变更范围判定: `api-change`
|
|
36
|
+
- 新增 / 修改 / 删除: +214 / -38 / -0
|
|
37
|
+
- 涉及层级: Controller → Service → Repository → Migration
|
|
38
|
+
|
|
39
|
+
### 1. 上轮问题修复情况(round > 1 时才有;round 1 填 "N/A")
|
|
40
|
+
|
|
41
|
+
| 序号 | 问题 | 本轮状态 |
|
|
42
|
+
| --- | --- | --- |
|
|
43
|
+
| CR-001 | 金额在 SQL 中计算导致精度问题 | 已修复 |
|
|
44
|
+
| CR-002 | TC-002 测试缺失 | 已修复 |
|
|
45
|
+
| CR-003 | 魔法值未定义 | **未修复(继承)** |
|
|
46
|
+
|
|
47
|
+
### 2. 本轮检查结果(按维度)
|
|
48
|
+
|
|
49
|
+
#### 2.1 正确性
|
|
50
|
+
| 检查项 | 结果 | 说明 |
|
|
51
|
+
| --- | --- | --- |
|
|
52
|
+
| 实现符合 design.md | 是 | CouponGrantService 与设计一致 |
|
|
53
|
+
| 业务逻辑正确 | 是 | |
|
|
54
|
+
| 接口契约一致 | **否** | `couponId` 类型不一致(见 CR-101) |
|
|
55
|
+
| 边界条件处理 | 是 | |
|
|
56
|
+
| 并发安全 | **否** | 库存扣减未用原子 UPDATE(见 CR-102) |
|
|
57
|
+
| 事务与幂等 | 是 | |
|
|
58
|
+
|
|
59
|
+
#### 2.2 完整性(需求功能点对照)
|
|
60
|
+
| 需求功能点 | 代码覆盖 | 对应改动点 | 状态 |
|
|
61
|
+
| --- | --- | --- | --- |
|
|
62
|
+
| F-01 用户可领取优惠券 | 是 | CouponController.grant | 已覆盖 |
|
|
63
|
+
| F-02 同一用户同模板不可重复领 | **否** | — | **未覆盖(CR-103)** |
|
|
64
|
+
| F-03 库存耗尽返回友好错误码 | 是 | GrantService.checkStock | 已覆盖 |
|
|
65
|
+
|
|
66
|
+
#### 2.3 安全性
|
|
67
|
+
| 检查项 | 结果 | 说明 |
|
|
68
|
+
| --- | --- | --- |
|
|
69
|
+
| SQL 注入 | 是 | 全部参数化 |
|
|
70
|
+
| 鉴权 | 是 | |
|
|
71
|
+
| 敏感数据脱敏 | **否** | log 里含手机号(见 CR-104) |
|
|
72
|
+
| Secret 落代码 | 是 | |
|
|
73
|
+
|
|
74
|
+
#### 2.4 性能
|
|
75
|
+
(按 §4 review-checklist.md 逐项填)
|
|
76
|
+
|
|
77
|
+
#### 2.5 可维护性
|
|
78
|
+
(按 §5 review-checklist.md 逐项填)
|
|
79
|
+
|
|
80
|
+
#### 2.6 测试 —— tests.md ↔ 测试代码对照
|
|
81
|
+
| 用例 | 对应测试 | 断言有效 | 状态 |
|
|
82
|
+
| --- | --- | --- | --- |
|
|
83
|
+
| TC-001 领券成功 | TestGrantCoupon_Success | 是 | 覆盖 |
|
|
84
|
+
| TC-002 重复领券 | — | — | **缺失(CR-105)** |
|
|
85
|
+
| TC-003 库存耗尽 | TestGrantCoupon_OutOfStock | 否 | **断言无效(CR-106)** |
|
|
86
|
+
|
|
87
|
+
#### 2.7 可观测性 / 数据迁移
|
|
88
|
+
(按 §7 review-checklist.md 逐项填)
|
|
89
|
+
|
|
90
|
+
### 3. 本轮 findings(按严重度)
|
|
91
|
+
|
|
92
|
+
> 同时写进 `review.findings.json`,下游 apply 用 JSON 做自动定位。
|
|
93
|
+
|
|
94
|
+
| ID | 级别 | fixMode | 位置 | 问题 | 建议 |
|
|
95
|
+
| --- | --- | --- | --- | --- | --- |
|
|
96
|
+
| CR-101 | MUST | REVIEW | api/v1/coupon.proto:17 | couponId 在 proto 是 int64,代码里 string | 统一为 string,前后端通过 gen 代码对齐 |
|
|
97
|
+
| CR-102 | MUST | REVIEW | service/grant.go:45 | 先 SELECT 再 UPDATE 有超卖风险 | 改为 `UPDATE stock SET qty=qty-1 WHERE qty>0 AND id=?` 原子更新,检查 RowsAffected |
|
|
98
|
+
| CR-103 | MUST | REVIEW | service/grant.go | F-02 未实现 | 增加 `(userId, templateId)` 唯一约束 + 查询拦截 |
|
|
99
|
+
| CR-104 | MUST | AUTO-FIX | service/grant.go:52 | 日志打印了 user.Phone 原始值 | 使用 `log.WithUser(user)` 统一脱敏 |
|
|
100
|
+
| CR-105 | MUST | REVIEW | test/grant_test.go | TC-002 缺失 | 新增 `TestGrantCoupon_Duplicated` 断言 ErrCodeDuplicate |
|
|
101
|
+
| CR-106 | MUST | REVIEW | test/grant_test.go:88 | 只断言无错,未验证错误码 | 补 `assert.Equal(t, ErrCodeOutOfStock, err.Code)` |
|
|
102
|
+
| CR-201 | SHOULD | REVIEW | service/grant.go:40-95 | 函数过长(> 80 行),职责复杂 | 拆 `validate / deduct / persist` 三段 |
|
|
103
|
+
| CR-202 | SHOULD | AUTO-FIX | service/grant.go:60 | 魔法值 3 | 常量 `STATUS_GRANTED = 3` |
|
|
104
|
+
| CR-301 | NIT | AUTO-FIX | service/grant.go:25 | 变量名 `t` 不表意 | 改为 `template` |
|
|
105
|
+
|
|
106
|
+
### 4. 结论
|
|
107
|
+
|
|
108
|
+
- **outcome: back_to_apply**(MUST=6,SHOULD=2,NIT=1)
|
|
109
|
+
- **下一轮 apply 优先级**:先 AUTO-FIX 类(CR-104, CR-202, CR-301),再 REVIEW 类按 CR-101 → CR-102 → CR-103 → CR-105 → CR-106 → CR-201。
|
|
110
|
+
- **风险提示**:CR-102(并发超卖)若线上已发布要紧急热修。
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**要点**:
|
|
114
|
+
|
|
115
|
+
- 表格行内的 MUST / SHOULD / NIT 才会被 `devflow review --round` 计数;散文里的 "should" / "must" 要小写。
|
|
116
|
+
- findings 的 ID 格式 `CR-<N>xx`:MUST 用 100-199,SHOULD 用 200-299,NIT 用 300-399,方便扫表识别。
|
|
117
|
+
- 本轮 findings 不要编号重用 —— 跨轮 ID 唯一;继承的未修复项沿用原 ID,不创建新 ID。
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## §2 `review.findings.json` —— Schema
|
|
122
|
+
|
|
123
|
+
```json
|
|
124
|
+
{
|
|
125
|
+
"$schema": "https://devflow.dev/schemas/review-findings.v1.json",
|
|
126
|
+
"round": 1,
|
|
127
|
+
"baseBranch": "master",
|
|
128
|
+
"commitRange": "<base-sha>..<head-sha>",
|
|
129
|
+
"diffScope": "api-change",
|
|
130
|
+
"iterationCount": 1,
|
|
131
|
+
"summary": {
|
|
132
|
+
"correctness": "failed",
|
|
133
|
+
"completeness": "failed",
|
|
134
|
+
"security": "failed",
|
|
135
|
+
"performance": "passed",
|
|
136
|
+
"maintainability": "fair",
|
|
137
|
+
"tests": "failed",
|
|
138
|
+
"observability": "passed"
|
|
139
|
+
},
|
|
140
|
+
"counters": { "must": 6, "should": 2, "nit": 1 },
|
|
141
|
+
"outcome": "back_to_apply",
|
|
142
|
+
"findings": [
|
|
143
|
+
{
|
|
144
|
+
"id": "CR-101",
|
|
145
|
+
"level": "MUST",
|
|
146
|
+
"dimension": "correctness",
|
|
147
|
+
"subcheck": "1.3 接口契约一致性",
|
|
148
|
+
"fixMode": "REVIEW",
|
|
149
|
+
"location": { "file": "api/v1/coupon.proto", "line": 17, "symbol": "CouponGrantRequest.couponId" },
|
|
150
|
+
"description": "couponId 在 proto 是 int64,代码使用 string,前后端对接会 type-mismatch",
|
|
151
|
+
"evidence": ["proto 定义 int64", "handler 里 req.CouponId.(string) 断言"],
|
|
152
|
+
"suggestedFix": "统一为 string 或 int64,并通过生成代码保证一致",
|
|
153
|
+
"resolved": false,
|
|
154
|
+
"carriedOverFromRound": null
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"id": "CR-102",
|
|
158
|
+
"level": "MUST",
|
|
159
|
+
"dimension": "correctness",
|
|
160
|
+
"subcheck": "1.5 并发安全",
|
|
161
|
+
"fixMode": "REVIEW",
|
|
162
|
+
"location": { "file": "service/grant.go", "line": 45, "symbol": "grantCoupon" },
|
|
163
|
+
"description": "先 SELECT qty 再 UPDATE 有超卖窗口",
|
|
164
|
+
"suggestedFix": "改原子 UPDATE: UPDATE stock SET qty=qty-1 WHERE qty>0 AND id=?; 检查 RowsAffected==1",
|
|
165
|
+
"resolved": false
|
|
166
|
+
}
|
|
167
|
+
]
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**字段必选**:`id` `level` `dimension` `fixMode` `location.file` `description` `suggestedFix` `resolved`。
|
|
172
|
+
|
|
173
|
+
**`level`**:`MUST` | `SHOULD` | `NIT`(大写)。
|
|
174
|
+
|
|
175
|
+
**`dimension`**:`correctness` | `completeness` | `security` | `performance` | `maintainability` | `tests` | `observability`。
|
|
176
|
+
|
|
177
|
+
**`fixMode`**:
|
|
178
|
+
- `AUTO-FIX` — coder 可直接按 suggestedFix 应用,不需要再设计(如命名、魔法值、日志脱敏装饰器)。
|
|
179
|
+
- `REVIEW` — 需要 coder 人工理解、可能引发 design 修改(如接口契约、并发模型)。
|
|
180
|
+
- `SPEC` — 需要回到 tech-spec / requirement 层(连续 2 轮同类 MUST 往往是这个)。
|
|
181
|
+
|
|
182
|
+
**`location.symbol`**(可选):函数 / 类 / 字段名,给 coder 做模糊匹配,路径漂移后仍能定位。
|
|
183
|
+
|
|
184
|
+
**`carriedOverFromRound`**(可选):非 null 表示本项从第 N 轮继承且仍未修复;跨轮同一 ID 出现 2 次应升级为 `fixMode=SPEC` 并写入 `escalation-playbook.md` 定义的流程。
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## §3 `code-review-report.md` —— 审查通过后才产出
|
|
189
|
+
|
|
190
|
+
只有 outcome 最终是 `pass` 或 `force-pass` 时产出;它是 `devflow verify` / `devflow deliver` 的硬前置(见 workflow gating)。
|
|
191
|
+
|
|
192
|
+
模板:
|
|
193
|
+
|
|
194
|
+
```markdown
|
|
195
|
+
---
|
|
196
|
+
finalRound: 2
|
|
197
|
+
finalOutcome: pass # pass | force-pass
|
|
198
|
+
totalRounds: 2
|
|
199
|
+
totalMustFixed: 6
|
|
200
|
+
totalShouldFixed: 1
|
|
201
|
+
totalNitFixed: 3
|
|
202
|
+
totalMustAccepted: 0 # force-pass 时 >0,需列出 reason
|
|
203
|
+
totalShouldAccepted: 1 # 有 should 被接受放行,列在 "接受与理由" section
|
|
204
|
+
forcePassReason: null # force-pass 时非空
|
|
205
|
+
signedOff: reviewer
|
|
206
|
+
signedAt: 2026-04-24T11:30:00+08:00
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
# 代码审查报告 — <slug>
|
|
210
|
+
|
|
211
|
+
## 1. 审查结论
|
|
212
|
+
|
|
213
|
+
| 项 | 值 |
|
|
214
|
+
| --- | --- |
|
|
215
|
+
| 最终结论 | **pass** |
|
|
216
|
+
| 总轮次 | 2 |
|
|
217
|
+
| 是否允许提测 | **是** |
|
|
218
|
+
| MUST 全部修复 | 是(6/6) |
|
|
219
|
+
| SHOULD 修复 / 接受 | 1/1(1 项接受,见第 4 节)|
|
|
220
|
+
| 待办 NIT | 3(跟踪至 issue,不阻塞) |
|
|
221
|
+
|
|
222
|
+
## 2. 需求功能点覆盖度(requirement.md → 代码)
|
|
223
|
+
|
|
224
|
+
| 需求功能点 | 代码覆盖 | 对应改动点 | 状态 |
|
|
225
|
+
| --- | --- | --- | --- |
|
|
226
|
+
| F-01 | 是 | CouponController.grant | 已覆盖 |
|
|
227
|
+
| F-02 | 是 | GrantService.checkDuplicated | 已覆盖 |
|
|
228
|
+
| F-03 | 是 | GrantService.checkStock | 已覆盖 |
|
|
229
|
+
|
|
230
|
+
## 3. design.md 改动点对照
|
|
231
|
+
|
|
232
|
+
| 改动点 | 涉及文件 | 代码已实现 | 全链路完整 | 备注 |
|
|
233
|
+
| --- | --- | --- | --- | --- |
|
|
234
|
+
| 新增 coupon_grant 表 | migration/0012_coupon_grant.sql | 是 | 是 | |
|
|
235
|
+
| CouponGrantService | service/grant.go | 是 | 是 | |
|
|
236
|
+
| 对外 API GrantCoupon | api/v1/coupon.proto | 是 | 是 | |
|
|
237
|
+
|
|
238
|
+
## 4. 接受与理由(SHOULD / MUST 放行项)
|
|
239
|
+
|
|
240
|
+
> force-pass 时 MUST 放行必须在此列出 reason;合并到 archive 后永久留档。
|
|
241
|
+
|
|
242
|
+
| ID | 级别 | 接受理由 |
|
|
243
|
+
| --- | --- | --- |
|
|
244
|
+
| CR-201 | SHOULD | 函数长度超阈值但职责明确且单测覆盖充分,延后拆分到下个迭代(issue #432) |
|
|
245
|
+
|
|
246
|
+
## 5. 未修复项(NIT)
|
|
247
|
+
|
|
248
|
+
| ID | 内容 | 跟踪 |
|
|
249
|
+
| --- | --- | --- |
|
|
250
|
+
| CR-301 | 变量命名不表意 | issue #433 |
|
|
251
|
+
| CR-302 | README 未更新 | issue #434 |
|
|
252
|
+
| CR-303 | CHANGELOG 待补 | 在 deliver 阶段补 |
|
|
253
|
+
|
|
254
|
+
## 6. 附件
|
|
255
|
+
|
|
256
|
+
- 第 1 轮: [review.md#第-1-轮](./review.md#第-1-轮) / [review.findings.json](./review.findings.json) round=1
|
|
257
|
+
- 第 2 轮: [review.md#第-2-轮](./review.md#第-2-轮) / [review.findings.json](./review.findings.json) round=2
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
**产出路径**:`devflow/changes/<slug>/code-review-report.md`
|
|
261
|
+
|
|
262
|
+
**何时产出**:
|
|
263
|
+
|
|
264
|
+
- `devflow review --round` 判定 outcome ∈ `{pass, force-pass}` 时,自动从 `review.md` 和 `review.findings.json` 聚合生成。
|
|
265
|
+
- 产出后 `state.json.phases.review.reportPath` 指向它。
|
|
266
|
+
- `devflow verify` / `devflow deliver` 启动时读取 `reportPath`;缺失或 `finalOutcome=blocked` 时拒绝放行。
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## §4 写作要点
|
|
271
|
+
|
|
272
|
+
- **不要**在同一 MUST 里描述多个问题,拆成独立 finding —— 否则下一轮 apply 只能部分修复,计数乱掉。
|
|
273
|
+
- **不要**把 suggestedFix 写成"重新审视设计"这样的虚话;写就写具体代码或具体改法。确实需要重新设计的,把 `fixMode` 写成 `SPEC`。
|
|
274
|
+
- **不要**把 fixMode 留空 —— 下游 coder 会退回 NEEDS_INPUT 死循环。
|
|
275
|
+
- **不要**在 findings 之外的散文里写"MUST"这个词 —— 计数会污染。
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
# code-review / review-checklist
|
|
2
|
+
|
|
3
|
+
Reviewer 的核心工作清单(**语言无关骨架**)。按维度逐项扫描,每一项要明确回答"代码里有没有这样做"。每项都带:
|
|
4
|
+
|
|
5
|
+
- **检查点**:reviewer 要回答的具体问题
|
|
6
|
+
- **典型问题(反例)**:最常见的错法
|
|
7
|
+
- **正确做法(正例)**:期望的样子
|
|
8
|
+
- **严重度判定**:什么情况下算 MUST / SHOULD / NIT
|
|
9
|
+
|
|
10
|
+
顺序:先 §1 Correctness(高优先级、高成本) → §7 Observability;然后打开 §严重度速查 校准判定。
|
|
11
|
+
|
|
12
|
+
## 必须配合 language cheatsheet 使用
|
|
13
|
+
|
|
14
|
+
本文只给"语言无关的骨架",真正的踩坑长什么样要看对应语言的 cheatsheet。按 `SKILL.md` 的"按项目语言自动加载 cheatsheet"章节挑 1-2 份一起读:
|
|
15
|
+
|
|
16
|
+
| 语言 / 栈 | cheatsheet |
|
|
17
|
+
| --- | --- |
|
|
18
|
+
| Java + Spring + MyBatis | [`language-cheatsheets/java-spring-mybatis.md`](language-cheatsheets/java-spring-mybatis.md) |
|
|
19
|
+
| Go | [`language-cheatsheets/go.md`](language-cheatsheets/go.md) |
|
|
20
|
+
| Python(Django / FastAPI / Flask) | [`language-cheatsheets/python.md`](language-cheatsheets/python.md) |
|
|
21
|
+
| Vue 3 + TypeScript | [`language-cheatsheets/vue.md`](language-cheatsheets/vue.md) |
|
|
22
|
+
|
|
23
|
+
每个 cheatsheet 末尾都有"快速映射到本文"的章节,说明哪一节对应通用 checklist 的哪一节。
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## §1 Correctness(正确性)
|
|
28
|
+
|
|
29
|
+
### 1.1 实现是否符合 design.md
|
|
30
|
+
|
|
31
|
+
- **检查点**:把 `design.md` 的"实现方案"或"改动点汇总"**逐条**在代码 diff 里找到对应。
|
|
32
|
+
- **反例**:design 写了"并发场景用 Redis 分布式锁",代码用了 `synchronized` / `sync.Mutex` 单机锁。
|
|
33
|
+
- **正例**:代码里有 Redis SET NX PX + lua 释放脚本,并带有超时与重入检查。
|
|
34
|
+
- **判定**:设计方案写了但代码没实现 → **MUST**;代码实现了设计没提的额外能力 → **SHOULD**(范围越权,除非 requirement.md 显式要求)。
|
|
35
|
+
|
|
36
|
+
### 1.2 业务逻辑是否正确
|
|
37
|
+
|
|
38
|
+
- **检查点**:核心计算、状态转移、决策分支是否在所有输入下都产出 requirement.md 里约定的结果。
|
|
39
|
+
- **反例**:优惠券金额 = SQL 里 `SUM(price * discount)` 直接返回给接口 —— 浮点误差 + 无法单元测试。
|
|
40
|
+
- **正例**:金额拉回业务层用 `BigDecimal` / `decimal.Decimal` 计算,SQL 只做原子 UPDATE。
|
|
41
|
+
- **判定**:结果错 → **MUST**;结果对但脆弱(精度、时区、locale) → **SHOULD**。
|
|
42
|
+
|
|
43
|
+
### 1.3 接口契约是否一致
|
|
44
|
+
|
|
45
|
+
- **检查点**:对外接口(HTTP / RPC / gRPC / 消息队列)的字段、类型、命名与 design.md 或"前端接口文档"是否 1:1。
|
|
46
|
+
- **反例**:design 里字段 `couponId: string`,代码里 `coupon_id: number`。
|
|
47
|
+
- **正例**:OpenAPI / Protobuf 自动生成 DTO,代码不手写;若手写则与 API spec 做 linter 校验。
|
|
48
|
+
- **判定**:字段错/类型错/枚举值错 → **MUST**(上下游对接必崩);命名风格不一致(驼峰 vs 下划线)→ **SHOULD**。
|
|
49
|
+
|
|
50
|
+
### 1.4 边界条件处理
|
|
51
|
+
|
|
52
|
+
- **检查点**:null / 空串 / 0 / 负数 / 超大值 / UTF8 / 时区 / DST / leap year / 空集合 / 首尾元素。
|
|
53
|
+
- **反例**:`list.get(0)` 无 `isEmpty` 判断;`strings.Split` 结果直接下标访问。
|
|
54
|
+
- **正例**:入口处早 return + 显式错误类型 `EmptyInputError`,测试里覆盖空集合分支。
|
|
55
|
+
- **判定**:崩溃路径未处理 → **MUST**;只处理主干、边界走兜底 log → **SHOULD**。
|
|
56
|
+
|
|
57
|
+
### 1.5 并发安全
|
|
58
|
+
|
|
59
|
+
- **检查点**:共享状态(map / slice / cache / counter / DB row)是否有原子性或锁保护;goroutine / thread 生命周期是否管理。
|
|
60
|
+
- **反例**:两个请求同时扣库存,都先 SELECT 再 UPDATE,超卖。
|
|
61
|
+
- **正例**:`UPDATE stock SET qty = qty - 1 WHERE qty > 0`(原子),或分布式锁包裹。
|
|
62
|
+
- **判定**:有可观察到的竞态(超卖、重复扣款、重复下发)→ **MUST**;理论有竞态但极低概率(如只做缓存 miss 穿透)→ **SHOULD**。
|
|
63
|
+
|
|
64
|
+
### 1.6 事务与幂等
|
|
65
|
+
|
|
66
|
+
- **检查点**:涉及多表 / 跨系统写入的路径是否有事务;对外调用是否幂等(重试安全)。
|
|
67
|
+
- **反例**:扣库存 + 生成订单不在同一事务;第三方支付回调无 idempotency key。
|
|
68
|
+
- **正例**:`@Transactional` / `WithTransaction`;回调表按支付单号唯一索引。
|
|
69
|
+
- **判定**:可能留下脏数据 / 重复扣款 → **MUST**;只影响可观测性(重复发短信)→ **SHOULD**。
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## §2 Completeness(需求覆盖度)
|
|
74
|
+
|
|
75
|
+
> 本节是 review 的"安全网" —— 防止需求遗漏。不深入查代码质量,只查"有没有做"。L1 无结构化 requirement 可跳过。
|
|
76
|
+
|
|
77
|
+
### 2.1 requirement.md 功能点对照表
|
|
78
|
+
|
|
79
|
+
必须在 `review.md` 的 Round 1 产一份:
|
|
80
|
+
|
|
81
|
+
| 需求功能点(来自 requirement.md) | 代码覆盖 | 对应改动点(来自 design.md) | 状态 |
|
|
82
|
+
| --- | --- | --- | --- |
|
|
83
|
+
| F-01 用户可领取优惠券 | 是 | CouponController.grant | 已覆盖 |
|
|
84
|
+
| F-02 同一用户同模板不可重复领 | **否** | — | **未覆盖(MUST)** |
|
|
85
|
+
| F-03 库存耗尽返回友好错误码 | 是 | GrantService.checkStock | 已覆盖 |
|
|
86
|
+
|
|
87
|
+
**判定规则**:
|
|
88
|
+
- 代码已覆盖 → 通过
|
|
89
|
+
- 代码未覆盖,但 design.md 标注"延后 / 不在本次范围" → 通过,备注原因
|
|
90
|
+
- 代码未覆盖,design.md 也没提 → **MUST**(需求遗漏)
|
|
91
|
+
|
|
92
|
+
### 2.2 EDGE CASES 对照
|
|
93
|
+
|
|
94
|
+
把 requirement.md 的"边界 / 异常 / 反例"段每一条映射到代码路径或测试用例:
|
|
95
|
+
|
|
96
|
+
| 边界场景 | 代码位置 | 测试用例 | 状态 |
|
|
97
|
+
| --- | --- | --- | --- |
|
|
98
|
+
| 库存为 0 | GrantService:45 | TC-003 | 覆盖 |
|
|
99
|
+
| 用户未登录 | 中间件 `AuthMiddleware` | — | **测试缺失(MUST)** |
|
|
100
|
+
|
|
101
|
+
### 2.3 delta/ spec 变更一致性(L2/L3)
|
|
102
|
+
|
|
103
|
+
- **检查点**:`changes/<slug>/delta/*.md` 列出的 spec 变更在代码里是否都实现了。
|
|
104
|
+
- **反例**:delta 写了"ADDED: 优惠券过期事件",代码里没发事件。
|
|
105
|
+
- **判定**:delta 声明但未实现 → **MUST**(archive 会把 delta 合入 `specs/`,错的 spec 污染主库)。
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## §3 Security(安全)
|
|
110
|
+
|
|
111
|
+
| 检查点 | 反例 | 正例 | 判定 |
|
|
112
|
+
| --- | --- | --- | --- |
|
|
113
|
+
| SQL 注入 | `"SELECT * FROM u WHERE name='" + n + "'"` | Prepared Statement / ORM 参数化 | 任一未参数化 → **MUST** |
|
|
114
|
+
| XSS / 模板注入 | 直接 `innerHTML = userInput` | 框架默认 escape 或 DOMPurify | **MUST** |
|
|
115
|
+
| 鉴权 | 只校验 token 存在,不校验权限范围 | 中间件统一鉴权 + 资源所有权校验 | **MUST** |
|
|
116
|
+
| 敏感数据记日志 | `log.info("user: %s", user)`(含手机号/身份证) | 结构化日志 + 脱敏装饰器 | **MUST**(合规红线)|
|
|
117
|
+
| Secret 落代码 | 代码里写 `api_key = "sk-xxx"` | `env` / Vault / SOPS | **MUST** + audit log |
|
|
118
|
+
| null 安全 | `user.getEmail().toLowerCase()` 无 nil 判断 | Optional / `user?.email` / 早 return | NPE 必 crash → **MUST**;理论存在 → **SHOULD** |
|
|
119
|
+
| 资源泄漏 | `conn := open(); use(conn)`(漏 close) | `defer close()` / `try-with-resources` | **MUST** |
|
|
120
|
+
| 密码学 | MD5 存密码;用 `math/rand` 生成 token | bcrypt / argon2;`crypto/rand` | **MUST** |
|
|
121
|
+
| CSRF | 状态变更接口无 CSRF token | 框架 CSRF 中间件 | Web 表单 → **MUST**;纯 JSON API + 鉴权 → **SHOULD** |
|
|
122
|
+
| 依赖漏洞 | 用了 CVE 披露的旧版 lib | lockfile 升级 + `npm audit` / `go mod audit` | 高危 CVE → **MUST** |
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## §4 Performance(性能)
|
|
127
|
+
|
|
128
|
+
| 检查点 | 反例 | 正例 | 判定 |
|
|
129
|
+
| --- | --- | --- | --- |
|
|
130
|
+
| N+1 查询 | 循环里每次查 DB | JOIN / IN / DataLoader / batched fetch | 接口可观测变慢 → **MUST**;调用量小 → **SHOULD** |
|
|
131
|
+
| O(N²) 嵌套 | `for x in A: for y in A: if x==y` | 用 map/set 索引 | 大数据量 → **MUST**;N<100 → NIT |
|
|
132
|
+
| 不必要的同步 | 在 HTTP handler 里同步调三方 API 串行 | 并发 + timeout + circuit breaker | 超 SLA → **MUST** |
|
|
133
|
+
| 无界循环 / 队列 | `for ; ; { dequeue() }` 无退出 | 退出信号 + max iteration | **MUST** |
|
|
134
|
+
| 内存泄漏 | listener / goroutine 不回收 | WeakRef / context cancel | **MUST** |
|
|
135
|
+
| 缓存穿透 | 热点 key miss 直接压 DB | singleflight / 空对象缓存 | 生产热点 → **MUST**;非热点 → **SHOULD** |
|
|
136
|
+
| 日志爆炸 | 每次请求打 DEBUG 全量 payload | 采样 + 级别控制 | **SHOULD** |
|
|
137
|
+
|
|
138
|
+
## §5 Maintainability(可维护性)
|
|
139
|
+
|
|
140
|
+
| 检查点 | 反例 | 正例 | 判定 |
|
|
141
|
+
| --- | --- | --- | --- |
|
|
142
|
+
| 命名 | `int t` / `doStuff()` / `handleX()` | `expireAt` / `calculateDiscount()` | **NIT**(多发 → **SHOULD**) |
|
|
143
|
+
| 魔法值 | `if status == 3` | `if status == STATUS_PAID` | **SHOULD** |
|
|
144
|
+
| 长函数(> 60 行 / > 5 层嵌套) | 200 行的 `process()` | 按职责拆 | **SHOULD** |
|
|
145
|
+
| 重复代码 | 同一段逻辑 copy 3 次 | 提抽象函数 | 首次 **NIT**,3+ 处 **SHOULD** |
|
|
146
|
+
| 职责单一 | Controller 直接写 SQL | 分层(Controller → Service → Repo) | **SHOULD** |
|
|
147
|
+
| 注释规范 | 无注释 / `// TODO` 过半年 | 关键决策 + `Why` / 公共 API 文档 | 公共 API 无注释 **SHOULD**;内部 **NIT** |
|
|
148
|
+
| 异常处理 | `catch (Exception) { log }` 吞异常 | 捕获具体类型 + rethrow / wrap | 吞异常 **MUST**;过度捕获 **SHOULD** |
|
|
149
|
+
| 循环依赖 | A → B → A | 接口倒置 / 事件解耦 | **SHOULD** |
|
|
150
|
+
|
|
151
|
+
## §6 Tests(单元测试)
|
|
152
|
+
|
|
153
|
+
> 若 `reports/test-report.md#unit` 存在,相信其 PASS 结果,只复核 FAIL 与未覆盖项。
|
|
154
|
+
|
|
155
|
+
### 6.1 tests.md ↔ 测试代码对照表
|
|
156
|
+
|
|
157
|
+
| tests.md 用例号 | 对应测试方法 / 函数 | 断言是否有效 | 状态 |
|
|
158
|
+
| --- | --- | --- | --- |
|
|
159
|
+
| TC-001 领券成功 | `TestGrantCoupon_Success` | 是 | 覆盖 |
|
|
160
|
+
| TC-002 重复领券 | — | — | **缺失(MUST)** |
|
|
161
|
+
| TC-003 库存耗尽 | `TestGrantCoupon_OutOfStock` | 只 assert 无 error,未 assert 错误码 | **SHOULD**(断言无效)|
|
|
162
|
+
|
|
163
|
+
### 6.2 测试代码质量检查
|
|
164
|
+
|
|
165
|
+
| 检查点 | 反例 | 正例 | 判定 |
|
|
166
|
+
| --- | --- | --- | --- |
|
|
167
|
+
| 断言强度 | `assert.NoError(err)` (只验不报错) | 额外验证返回值 / 状态 / 副作用 | **SHOULD** |
|
|
168
|
+
| Mock 策略 | Mock 被测函数本身 | 只 Mock 外部依赖(DB / HTTP) | **MUST** |
|
|
169
|
+
| 测试数据 | 随机 / 时间敏感(`time.Now()`) | 固定 fixture / 注入时钟 | **SHOULD** |
|
|
170
|
+
| skip / only | `it.skip` / `test.only` 入库 | CI 前清空 | **MUST** |
|
|
171
|
+
| 死测试 | 断言了永远为真的东西(`assert.Equal(1, 1)`) | 断言业务结果 | **MUST** |
|
|
172
|
+
| 测试命名 | `test1` / `testFoo2` | `Test<Function>_<Case>_<Expected>` | **NIT** |
|
|
173
|
+
|
|
174
|
+
### 6.3 覆盖率(若有 `reports/test-report.md#unit` 里的覆盖率数据)
|
|
175
|
+
|
|
176
|
+
| 指标 | 低于多少 | 判定 |
|
|
177
|
+
| --- | --- | --- |
|
|
178
|
+
| L1 | — | 只要关键路径有测试即可 |
|
|
179
|
+
| L2 | 行覆盖 < 60% | **SHOULD** |
|
|
180
|
+
| L3 | 行覆盖 < 75% 或关键路径分支覆盖 < 80% | **MUST** |
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## §7 Observability / Migration / Ops
|
|
185
|
+
|
|
186
|
+
### 7.1 可观测性
|
|
187
|
+
|
|
188
|
+
| 检查点 | 反例 | 正例 | 判定 |
|
|
189
|
+
| --- | --- | --- | --- |
|
|
190
|
+
| 关键节点日志 | 无 | 请求入口 / 外部调用前后 / 异常分支 | 关键分支无日志 **SHOULD**;异常无日志 **MUST** |
|
|
191
|
+
| TraceID 透传 | 子调用丢 traceID | `context` 透传或 header 透传 | **SHOULD** |
|
|
192
|
+
| 指标 | 新业务无 QPS / 错误率 / 延迟指标 | Prometheus / OpenTelemetry counter/histogram | 新接口 **SHOULD** |
|
|
193
|
+
| 告警 | 设计写了"库存低于 N 告警",代码没注册 | 告警规则与 design.md 对齐 | design 写了 → **MUST** |
|
|
194
|
+
|
|
195
|
+
### 7.2 迁移(DDL / 数据迁移)
|
|
196
|
+
|
|
197
|
+
| 检查点 | 反例 | 正例 | 判定 |
|
|
198
|
+
| --- | --- | --- | --- |
|
|
199
|
+
| DDL 可重入 | `ALTER TABLE ADD COLUMN` 无 `IF NOT EXISTS` | `IF NOT EXISTS` / 幂等脚本 | **MUST** |
|
|
200
|
+
| 回滚脚本 | 只有 `up.sql` | 配套 `down.sql` 或明确"不可回滚" + 原因 | 无回滚且未说明 **MUST** |
|
|
201
|
+
| 大表在线 | `ALTER TABLE` 加锁 | pt-osc / gh-ost / 分批 | 百万行以上表 **MUST** |
|
|
202
|
+
| DDL ↔ 代码字段一致 | DDL 枚举 1,2,3 vs 代码常量 10,20,30 | 完全一致或生成代码 | **MUST**(历史踩坑,超级难排查) |
|
|
203
|
+
|
|
204
|
+
### 7.3 新增字段全链路(重点!改数据层最易漏)
|
|
205
|
+
|
|
206
|
+
每新增一个字段,逐层核对(按你的技术栈替换层级名):
|
|
207
|
+
|
|
208
|
+
| 层级 | 检查 |
|
|
209
|
+
| --- | --- |
|
|
210
|
+
| DDL / migration | `ALTER TABLE` 已加且类型正确 |
|
|
211
|
+
| ORM 模型(DO / Entity / Model) | 属性已声明 + 类型匹配 DDL |
|
|
212
|
+
| 映射文件(mapper.xml / sqlc / 查询构建器) | SELECT 列表 / INSERT / UPDATE 已包含 |
|
|
213
|
+
| Domain / Service 层 | 取/存逻辑已使用新字段 |
|
|
214
|
+
| Convertor / DTO mapper | DO ↔ DTO 转换已处理 |
|
|
215
|
+
| 对外返回对象(VO / Response) | 已暴露(如需) |
|
|
216
|
+
| 前端接口文档 | 已同步(若有) |
|
|
217
|
+
|
|
218
|
+
**任一层缺失 → MUST**。这是 arb 最核心的踩坑 checklist,原因:字段从 DDL 到 VO 需要经过 5-7 层,漏任何一层都会导致线上返回 null,而且 happy path 单测都能过。
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## 严重度速查
|
|
223
|
+
|
|
224
|
+
| 判定信号 | MUST | SHOULD | NIT |
|
|
225
|
+
| --- | --- | --- | --- |
|
|
226
|
+
| 数据正确性 / 丢单 / 资损 | ✓ | | |
|
|
227
|
+
| 安全合规红线 | ✓ | | |
|
|
228
|
+
| 需求功能未实现 / 契约破坏 | ✓ | | |
|
|
229
|
+
| 测试用例缺失 / 断言无效 | ✓ | | |
|
|
230
|
+
| DDL ↔ 代码字段不一致 | ✓ | | |
|
|
231
|
+
| 生产可观测的性能回归 | ✓ | | |
|
|
232
|
+
| 非阻塞的风险(可维护性、次级性能) | | ✓ | |
|
|
233
|
+
| 非关键路径的代码异味 | | ✓ | |
|
|
234
|
+
| 纯风格(命名、排版) | | | ✓ |
|
|
235
|
+
|
|
236
|
+
**临界判定规则**:
|
|
237
|
+
|
|
238
|
+
- 拿不准 MUST / SHOULD → 问自己"这个问题上线后 P0 / P1 / P2?",P0-P1 给 MUST。
|
|
239
|
+
- 拿不准 SHOULD / NIT → 问自己"下一个接手这份代码的人会卡住吗?",会就 SHOULD。
|
|
240
|
+
- 如果 reviewer 与 coder 对严重度有分歧,把分歧本身作为 SHOULD 记录,由 `devflow review --force-pass` 或回 tech-spec 上级裁决。
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## 本 skill 与下游的交接
|
|
245
|
+
|
|
246
|
+
Reviewer 的每一个 MUST / SHOULD 都应该:
|
|
247
|
+
|
|
248
|
+
1. 写进 `review.md`(人读)
|
|
249
|
+
2. **同时**写进 `review.findings.json`(机读,给 apply 自动定位修复)
|
|
250
|
+
|
|
251
|
+
格式见 `references/output-template.md` §2。
|