|
|
@@ -0,0 +1,74 @@
|
|
|
+# S-cfc-322 - admin.content.security 实现验证报告 (2026-11-14)
|
|
|
+
|
|
|
+**能力键**: `admin.content.security`
|
|
|
+**任务号**: S-cfc-322(TDD 实现使绿,SC-A-13 内容安全审核 ⭐ / SC-A-18 内容安全审核队列 ⭐)
|
|
|
+**状态**: TDD-GREEN(实现已存在,测试已通过)
|
|
|
+**状态机流转**: YELLOW -> GREEN(通过本验证提交)
|
|
|
+
|
|
|
+## 验证摘要
|
|
|
+
|
|
|
+1. **契约测试**: `AdminContentSecurityContractTest`(15 cases,测试侧 S-cfc-208 `a18b731c3` 登记、已合入 cfclub)在 `origin/cfclub` HEAD(`b9d80dd6d`)上已全绿 **15/15**,无需任何 src/main 改动。
|
|
|
+2. **实现校验**(能力链在 `origin/cfclub` 已完整落地):
|
|
|
+ - `AdminArticleController /api/admin/articles` 审核端点家族全部存在且为 `@PostMapping`:
|
|
|
+ `/audit`(`audit`)、`/submit-review`(`submitReview`)、`/withdraw`(`withdraw`)、
|
|
|
+ `/re-draft`(`reDraft`)、`/upload/image`(`uploadImage`,微信 `checkImage` 检测)、
|
|
|
+ `/upload/video`(`uploadVideo`)、`/comments/list`(`commentList`)、`/list`(`list`)。
|
|
|
+ - `create` 敏感词命中拦截:标题命中 -> `Result.error("文章标题包含敏感信息,发布失败")`;
|
|
|
+ 正文命中 -> `Result.error("文章内容包含敏感信息,发布失败")`;均不触达 `articleService.create`。
|
|
|
+ - `checkTextSafe` fail-open:`null`/全空白直接放行,不触达微信检测(单测未注入 wechatService 也不 NPE)。
|
|
|
+ - `ArticleService` 审计状态机:
|
|
|
+ - `submitForReview`:draft -> status=pending + auditStatus=pending + `updateById`;
|
|
|
+ 非 draft 抛 `仅草稿状态可提交审核` 且不写库。
|
|
|
+ - `withdraw`:published -> withdrawn(下架);非 published 抛 `仅发布中的文章可撤回` 且不写库。
|
|
|
+ - `reDraft`:rejected/withdrawn -> draft 且清空 auditStatus/auditReason/auditorId/auditedAt;
|
|
|
+ 其他状态抛 `仅已驳回或已撤回的文章可重新编辑` 且不写库。
|
|
|
+ - `auditArticle`:approved -> published / rejected -> rejected+原因(SC-A-13 闭环)。
|
|
|
+ - `ReviewCenterController /api/admin/review-center/summary`(SC-A-18 审核队列):
|
|
|
+ `articlePending / productPending / guidePending / vendorPending / butlerPending / packagePending /
|
|
|
+ activityPending / activityRegistrationPending / withdrawPending / refundPending /
|
|
|
+ hierarchyChangePending / nutritionistPending / knowledgePending` **13 类待审聚合键**齐全;
|
|
|
+ 空队列时全部键存在且为 0。
|
|
|
+ - `ContentFilterController /api/content/by-tags`:无标签无问题域 -> code 200,
|
|
|
+ `resultTags/articles/knowledgeBases/foods` 四组全空,不触达 DB。
|
|
|
+ - 权限流:`/api/admin/` 整族登录门(B-142-1 已修)+ `audit` 角色守卫——由
|
|
|
+ `AdminArticleAuditContractTest`(12/12 绿)锁定,本键不重复覆盖。
|
|
|
+3. **测试结果**: 目标类 0 失败 -> 15 通过;关联链 `AdminArticleAuditContractTest` 12/12 绿,
|
|
|
+ 合计 **27/27 全绿,BUILD SUCCESS**。
|
|
|
+
|
|
|
+## 结论
|
|
|
+
|
|
|
+该能力键的实现已存在于 `origin/cfclub`,无需代码修改即可使红单测全绿(与 S-cfc-309 实现验证报告、
|
|
|
+S-cfc-208 测试侧首验结论一致:契约端点与行为在登记 RED 任务时即已全部落地,测试以「契约绿锁定」
|
|
|
+形式作为回归基线)。本提交仅登记闭环验证产物,标记任务已完成。
|
|
|
+
|
|
|
+## 暴露的缺陷
|
|
|
+
|
|
|
+无。实现现状与契约断言全部吻合;本键属编排侧在测试登记(S-cfc-208 实现在先)后重复派发的 GREEN
|
|
|
+任务,建议编排侧直接登记收尾,不再重复派发。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 实现会话实跑复核(2026-11-14,隔离工作树 `.worktrees/task_S-cfc-322`)
|
|
|
+
|
|
|
+**基准**: `origin/cfclub` @ `b9d80dd6d`(HEAD)
|
|
|
+
|
|
|
+**复核命令**(cfc-backend 单模块,未触碰测试 / 未改实现):
|
|
|
+```
|
|
|
+mvn -Dtest="AdminContentSecurityContractTest,AdminArticleAuditContractTest" test
|
|
|
+```
|
|
|
+
|
|
|
+**实测结果**(surefire 报告):
|
|
|
+```
|
|
|
+[INFO] Tests run: 15, Failures: 0, Errors: 0, Skipped: 0 - in com.etotem.cfc.unit.AdminContentSecurityContractTest
|
|
|
+[INFO] Tests run: 12, Failures: 0, Errors: 0, Skipped: 0 - in com.etotem.cfc.controller.admin.AdminArticleAuditContractTest
|
|
|
+[INFO] BUILD SUCCESS
|
|
|
+```
|
|
|
+
|
|
|
+**复核结论**: 红单测实跑为全绿(失败数 0 -> 通过数 15/15),实现(审核端点家族 + 敏感词拦截 +
|
|
|
+审计状态机 + review-center 13 类队列聚合 + content by-tags 空标签边界 + fail-open 策略)已完整落地于
|
|
|
+`origin/cfclub`,本键无需 src/main 改动即可闭环。
|
|
|
+
|
|
|
+**改动文件**:
|
|
|
+- `docs/tdd/impl-2026-11-14-S-cfc-322-admin-content-security.md`(本报告,docs-only,无代码变更)
|
|
|
+
|
|
|
+**暴露的缺陷**: 无。
|