Browse Source

docs(tdd): S-cfc-152 admin.article.list 契约已覆盖验证回执——AdminArticleListContractTest 6/6 全绿(实跑),AdminArticleController.list + ArticleService.getAdminList 实现在链(c3e32460a),无 RED 断言无实现缺口,0 处 src/main 改动,供编排侧 O-16 先例回填 yellow_sha

Sisyphus Agent 19 hours ago
parent
commit
7e03ffccbc
1 changed files with 48 additions and 0 deletions
  1. 48 0
      docs/tdd/dev/evidence-S-cfc-152-admin-article-list-20261112.md

+ 48 - 0
docs/tdd/dev/evidence-S-cfc-152-admin-article-list-20261112.md

@@ -0,0 +1,48 @@
+# S-cfc-152 验证回执:admin.article.list(后台文章列表)契约已覆盖
+
+> 归属:TDD-GREEN 实现批次 · 任务号:S-cfc-152 · 能力键:`admin.article.list`
+> 日期:2026-11-12
+> 结论:**契约测试 6/6 全绿 = 实现已覆盖**,无需新增 src/main 改动(防伪实现)。本回执供编排侧按 **O-16 先例回填 yellow_sha**。
+
+## 1. 结论摘要
+
+| 断言项 | 结果 |
+|---|---|
+| 契约测试类存在 | ✅ `cfc-backend/src/test/java/com/etotem/cfc/controller/admin/AdminArticleListContractTest.java`(fcd9117bf,S-cfc-142 登记) |
+| 契约测试实跑 | ✅ **6 run / 0 failures / 0 errors**(本 worktree,`mvn -Dtest=AdminArticleListContractTest test`) |
+| 实现已在链 | ✅ `AdminArticleController#list`(`@PostMapping("/list")`)+ `ArticleService#getAdminList`(11 参),由 `c3e32460a`(2026-06-09)引入,早于契约登记 |
+| RED 断言 | 无——该键契约自登记(fcd9117bf 提交时注释即载明"实现已落地,6 契约用例全绿")即全绿;129 轮报告(d22e8183f)核验"S-cfc-142 契约全绿=实现已覆盖/admin.article.list 已在链" |
+| 本次 src/main 改动 | **0**(无实现缺口,禁止伪造改动) |
+
+## 2. 契约测试执行证据(本地确证)
+
+命令:`cd cfc-backend && mvn -Dtest=AdminArticleListContractTest test`
+
+```
+Test set: com.etotem.cfc.controller.admin.AdminArticleListContractTest
+Tests run: 6, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.564 s
+```
+
+surefire 报告:`cfc-backend/target/surefire-reports/com.etotem.cfc.controller.admin.AdminArticleListContractTest.txt`
+
+## 3. 契约断言 ↔ 实现逐项核对
+
+| 契约断言(AdminArticleListContractTest) | 实现(AdminArticleController#list + ArticleService#getAdminList) |
+|---|---|
+| 空 body → 默认 page=1 size=20,过滤参数全 null | ✅ `page`/`size` 缺省 1/20;status/categoryId/keyword/contentType/difficultyLevel/dimensionCode/tagId/auditStatus 缺省 null;sort 缺省 null |
+| 全量过滤参数 + 显式分页 + sort → 透传 getAdminList | ✅ 8 过滤参数 + page/size + sortSpecs 原样透传(11 参签名一致) |
+| 数字字符串参数("5"/"3"/"2")→ 解析为 Long/Integer/int | ✅ categoryId/tagId 走 `ParamUtils.getLong`;difficultyLevel 走 `Integer.valueOf(toString)`;page/size 走 `Integer.parseInt` |
+| 非数字 categoryId/tagId → null 不抛异常 | ✅ `ParamUtils.getLong` 对 null/空串/非数字返回 null(ParamUtils 语义) |
+| 成功 → `Result.success(Page<Article>)`(业务码 200) | ✅ `Result.success(getAdminList(...))` 信封 |
+| 路由契约:类级 `/api/admin/articles` + `list` 方法级 `/list` | ✅ `@RequestMapping("/api/admin/articles")` + `@PostMapping("/list")` |
+
+## 4. 链上证据(git 真值)
+
+- 契约测试:`fcd9117bf`(test(tdd): S-cfc-142 admin.article.list 契约级单测——实现已落地,6 契约用例全绿)✅ IN origin/cfclub
+- 实现引入:`c3e32460a`(feat: backend services for energy/commission/article/...)✅ IN origin/cfclub
+- 编排侧核验:`d22e8183f`(129 轮)"S-cfc-142 契约全绿=实现已覆盖/admin.article.list 已在链";`90eb9b816`(135 轮)"142/146 等,实现侧按现有实现即可使绿"
+
+## 5. 暴露的缺陷
+
+无新增实现缺口。观察项(非本键契约断言、不扩散处理):
+- `list` 中 `difficultyLevel`/`page`/`size` 对显式非法数字(非数字字符串)会抛 `NumberFormatException` 而非安全 null;契约边界仅覆盖 categoryId/tagId(走 ParamUtils),故不在本次收口范围,登记供后续键(如参数校验加固)参考。