fix(account-lifecycle): close Phase 21 KEEP-VERIFY — 6 real defects + fake-green tests

KEEP-VERIFY re-audit of account lifecycle (EXTEND): STATUS marked ✅ but
contained hard Gate violations and dead code.

Real defects fixed:
- D-21-A: AuthService.checkAccountStatus did not reject CLOSED → closed
  account could still log in (Gate ❌→✅); added CLOSED branch before
  BANNED/SUSPENDED.
- D-21-B: notifyActiveMatches was a TODO stub → active Matches/conversations
  not closed on withdrawal (Gate ❌→✅); now finds active matches, sets
  UNMATCHED + closes conversation via chatService.closeConversationForMatch.
- D-21-C: cancelPendingActivityRegistrations was a TODO stub → future
  activity registrations not cancelled (Gate ❌→✅); now cancels pending/approved.
- D-21-D: anonymizeServiceHistory existed but was never wired into
  closeAccount → personal identity + counseling text leaked (Gate ❌→✅);
  wired in, anonymizes id_number/real_name with placeholder, plus
  counseling_followups content.
- D-21-E: closeAccount hard-threw on blockers → all cancelXxx unreachable
  (dead code contradiction); changed to informational log + continue cleanup.
- D-21-F: 7× assertTrue(true) fake-green tests → replaced with 11 real DB
  integration tests + 3 login-guard tests (Redis-decoupled via
  ReflectionTestUtils).

Cross-module defenses (RecommendationEngine/MatchEligibility/Capability
reject non-NORMAL) confirmed effective. Remaining (no silent scope creep):
matchmaker in-progress interception still hardcodes 0 (no table), data
retention delete flow is a product decision, privacy-settings endpoint stub.

Full regression: 650 tests / 0 failures / 0 errors / 3 skipped (baseline 648, +2).
This commit is contained in:
WorkBuddy
2026-09-18 10:12:34 +08:00
parent 22c778b111
commit 0580da0c62
7 changed files with 581 additions and 66 deletions
+3 -2
View File
@@ -52,7 +52,7 @@
> 后立即暴露 `ActivityPhase14Test` 夹具违规(`household` → `household_registration`)。新增
> `LocalEligibilityStatusVocabularyGuardTest`(9)。负向验证两轮共 7 处注入 → **7 个用例精准变红且无无关失败**
> (其中一处被"源码结构 + 运行时行为"两层守卫同时捕获),还原后 `md5sum` 逐字节一致、`NEG-VAL` 残留 0。
> 后端 **648 tests 全绿**;admin-web `vue-tsc --noEmit` EXIT=0;**Phase 21 尚未获准。**
> 后端 **648 tests 全绿**;admin-web `vue-tsc --noEmit` EXIT=0;**Phase 21 已复验关闭(2026-09-18,650 tests 全绿,见 `docs/Phase-21-V11-Recovery-Completion-Report-2026-09-18.md`)**
> 证据:`docs/Phase-20-V11-Recovery-Completion-Report-2026-09-17.md`。
> **2026-09-16 状态校正:** Phase 07 UI 已按 2026-09-13 规格重新实现,**首批 11 页于 2026-09-16 通过用户验收(结论:基本达标)**,本文件此前"视觉否决/REOPENED"口径随之关闭。
@@ -177,7 +177,8 @@
| Phase 17 举报与风控复验 | 已完成(2026-09-17) | 见 `Phase-17-V11-Recovery-Completion-Report-2026-09-17.md`;修复 **6 处真实缺陷**(**D1(Critical,必崩级盲区)测试库缺 `reports`/`risk_events`/`risk_actions` 三表 → 风控/举报真实 DB 路径零覆盖,`ReportServiceTest` 全 `assertTrue(true)` 假绿**;**D3(High)敏感访问(查看他人风险画像/举报)无审计(违反 AGENTS.md #8)**;D4 审计缺 `ip`/`userAgent`;D5 `findByUserId` 未过滤软删;D2 人工标记无审计;**D6 `javax`→`jakarta` 隐藏编译缺陷 + `risk_events` 漏 `updated_at` 列**);补齐三表并移出白名单入 `REQUIRED_IN_TEST_SCHEMA`;新增 `AuditLogService.recordSensitiveAccess` 并接线三端点;新增 `ReportAndRiskPhase17IntegrationTest`(7 用例);负向验证(注释 getReportDetail 审计 → D3 守卫精准变红并还原);后端 **488 tests 全绿**;**Phase 18 尚未获准** |
| Phase 18 申诉复验 | 已完成(2026-09-17) | 见 `Phase-18-V11-Recovery-Completion-Report-2026-09-17.md`;修复 **8 处真实缺陷**(**D1(Critical,必崩级盲区)测试库缺 `appeals` 表 + `AppealServiceTest` 9 例中 6 例 `assertTrue(true)` 假绿 → 申诉真实 DB 路径零覆盖**;**D2(High,只在 PG 上炸)`escalateAppeal` 向 `operatorId` 发用户通知撞 `notifications.user_id → users(id)` FK → 升级事务整体回滚**;**D3(High,只在 PG 上炸)`appealType` 未校验生产 `chk_appeal_type` 白名单**;D4 escalated 死胡同(前后端均无法再决策);D5 `processAppeal` 先读后写并发竞态;D6 三处查询漏 `deleted_at` 过滤;D7 硬编码 `resolved`;D8 证据字段契约 `evidenceFileIds`);补 `appeals` 表并移出白名单入 `REQUIRED_IN_TEST_SCHEMA`;新增原子认领 `markReviewingIfProcessable`;新增 `AppealPhase18IntegrationTest`(15 用例),删除假绿 `AppealServiceTest`(9 用例);负向验证(误伤其他处置 → Gate 用例精准变红并还原);后端 **494 tests 全绿**;admin-web `vue-tsc` EXITCODE=0;**Phase 19 尚未获准** |
| Phase 19 统一运营后台 + 用户端公益服务页面复验 | 已完成(2026-09-17) | 见 `Phase-19-V11-Recovery-Completion-Report-2026-09-17.md`;修复 **25 处真实缺陷**(**D20 服务站公告能力整条不可达:Service + V042 表都在、全仓零端点**;**D21 服务站 `create/update` 越权写:类级 `service_location.view` 兜底,`service_location.manage` 是从未使用的死权限**;D22 该控制器未纳入权限覆盖守卫;**D2/D3 Banner 校验 500 + 软删 Banner 仍上首页**;**D5/D6 Content 发布死路 + 分类停用不可恢复**;D10~D14 ServiceProgram 审批死路/草稿泄露/成员数恒 0/退出未实现/撞唯一键;D9/D23 测试库缺 `content_categories` 与 `service_location_announcements` → 零覆盖;D18 预约 IDOR;D24 迁移基线未跟进 V042);补 V042 公告表 + 运营端五端点 + 用户端只读端点 + 后台公告管理 UI + 小程序 U50 公告区块;新增 3 组守卫(24+5+5 用例)并把服务站运营端收入权限覆盖扫描;负向验证 3 注入 → 4 用例精准变红;后端 **602 tests 全绿**;admin-web `vue-tsc`/`vite build` 双绿;小程序 `tsc` EXIT=0;ui-tests 14/14;**Phase 20 尚未获准** |
| Phase 20 Analytics 数据统计与管理驾驶舱复验 | 已完成(2026-09-17) | 见 `Phase-20-V11-Recovery-Completion-Report-2026-09-17.md`;修复 **20 处真实缺陷**(**D1 实名人数用 `profile_status != 'rejected'` 冒充 → 把"资料还在填"算成已实名**;**D3 Chat Started 直接数会话行数 → 系统通知计入**;**D4 Match 不分来源 → 10 对互选被当 10 对成功引用**;**D5 活动漏斗全部硬编码 0 + 一行把"用户数"当"活动数"的死代码**;**D6 Banner 曝光/点击硬编码 0**;**D12 系统性软删缺陷:`BaseEntity.deletedAt` 无 `@TableLogic` + 全局无逻辑删除配置 → `selectCount` 把软删数据全部计入且无任何报错**,修复 45 处统计调用(含 2 轮复验补扫出的 5 处次级路径);**D15 三套独立实现** → 抽 `AnalyticsMetricsCalculator` 统一口径;**D13/权限 授予脱节:`data_viewer` 空壳角色 + `platform_admin` 被 `id >= '20000000-…'` 条件漏掉 V1.0 老权限段 → 整个模块除 super_admin 外全员 403**;**D14 `AnalyticsServiceTest` = 5×`assertTrue(true)` 假绿 → 删除**;D20 `getDailySummary` 无边界校验;前端 `AnalyticsView.vue` 未接 `/v11-dashboard`);建立指标字典 `MetricCatalog`(36 指标 × 12 字段)+ `docs/ANALYTICS_METRICS.md`;新增 V043 授权(**刻意排除 `organization_admin`** —— 相关表无组织维度,无范围全量数据即越权);新增守卫 `MetricCatalogGuardTest`(11) / `AnalyticsMetricsPhase20IntegrationTest`(21) / `AnalyticsSoftDeleteGuardTest`(4,结构性) / `AnalyticsPermissionGrantTest`(6);**跨阶段修复 X1~X3**(**注销写入 `user_identities` 状态域的 `'failed'` → 违反 V017 `chk_elig_verify_status` → 真实 PG 上账号注销 100% 不可用**;`checkCanWithdraw` 资格拦截死代码;测试库补两条 CHECK 后暴露 `ActivityPhase14Test` 夹具违规)并新增 `LocalEligibilityStatusVocabularyGuardTest`(9);负向验证两轮 7 注入 → 7 用例精准变红并还原(`md5sum` 逐字节一致);后端 **648 tests 全绿**;admin-web `vue-tsc` EXIT=0;**Phase 21 尚未获准** |
| Phase 20 Analytics 数据统计与管理驾驶舱复验 | 已完成(2026-09-17) | 见 `Phase-20-V11-Recovery-Completion-Report-2026-09-17.md`;修复 **20 处真实缺陷**(**D1 实名人数用 `profile_status != 'rejected'` 冒充 → 把"资料还在填"算成已实名**;**D3 Chat Started 直接数会话行数 → 系统通知计入**;**D4 Match 不分来源 → 10 对互选被当 10 对成功引用**;**D5 活动漏斗全部硬编码 0 + 一行把"用户数"当"活动数"的死代码**;**D6 Banner 曝光/点击硬编码 0**;**D12 系统性软删缺陷:`BaseEntity.deletedAt` 无 `@TableLogic` + 全局无逻辑删除配置 → `selectCount` 把软删数据全部计入且无任何报错**,修复 45 处统计调用(含 2 轮复验补扫出的 5 处次级路径);**D15 三套独立实现** → 抽 `AnalyticsMetricsCalculator` 统一口径;**D13/权限 授予脱节:`data_viewer` 空壳角色 + `platform_admin` 被 `id >= '20000000-…'` 条件漏掉 V1.0 老权限段 → 整个模块除 super_admin 外全员 403**;**D14 `AnalyticsServiceTest` = 5×`assertTrue(true)` 假绿 → 删除**;D20 `getDailySummary` 无边界校验;前端 `AnalyticsView.vue` 未接 `/v11-dashboard`);建立指标字典 `MetricCatalog`(36 指标 × 12 字段)+ `docs/ANALYTICS_METRICS.md`;新增 V043 授权(**刻意排除 `organization_admin`** —— 相关表无组织维度,无范围全量数据即越权);新增守卫 `MetricCatalogGuardTest`(11) / `AnalyticsMetricsPhase20IntegrationTest`(21) / `AnalyticsSoftDeleteGuardTest`(4,结构性) / `AnalyticsPermissionGrantTest`(6);**跨阶段修复 X1~X3**(**注销写入 `user_identities` 状态域的 `'failed'` → 违反 V017 `chk_elig_verify_status` → 真实 PG 上账号注销 100% 不可用**;`checkCanWithdraw` 资格拦截死代码;测试库补两条 CHECK 后暴露 `ActivityPhase14Test` 夹具违规)并新增 `LocalEligibilityStatusVocabularyGuardTest`(9);负向验证两轮 7 注入 → 7 用例精准变红并还原(`md5sum` 逐字节一致);后端 **648 tests 全绿**;admin-web `vue-tsc` EXIT=0;**Phase 21 已复验关闭(2026-09-18,650 tests 全绿)** |
| Phase 21 账户生命周期增量复验 | 已完成(2026-09-18) | 见 `docs/Phase-21-V11-Recovery-Completion-Report-2026-09-18.md`;KEEP-VERIFY 复验发现 STATUS 标✅ 但含 **6 处真实缺陷 + 假绿测试**:① `AuthService.checkAccountStatus` 不拒 `CLOSED` → 注销后仍可登录(Gate ❌→✅);② `notifyActiveMatches` 为 TODO 桩 → 注销未关闭活跃 Match/会话(Gate ❌→✅,已实现关闭 Match + `chatService.closeConversationForMatch`);③ `cancelPendingActivityRegistrations` 为 TODO 桩 → 未来活动报名未关闭(Gate ❌→✅);④ `anonymizeServiceHistory` 已实现却**从未被 `closeAccount` 调用(死代码)** → 个人/咨询正文暴露(Gate ❌→✅,已接线 + 脱敏身份证占位符 + `counseling_followups` 正文);⑤ `closeAccount` 在 blockers 处硬抛异常使 `cancelXxx` 永远不可达(死代码矛盾 → 信息性日志 + 继续清理);⑥ 删除 7×`assertTrue(true)` 假绿 → 替换为 11 用例真实 DB 集成测试 + 3 用例登录守卫;跨模块防线(推荐引擎/匹配资格/Capability 已拒非 NORMAL)确认有效;后端 **650 tests 全绿**(起点 648,净 +2);**Phase 22 尚未获准** |
| UI-CLEANUP-20260913 | 已完成 | 废弃 UI 代码、冲突规范、旧计划和无效验收证据已清理;`ui-document-baseline-contracts` 锁定唯一视觉入口 |
| UI-ADMIN-20260913 | 已完成(待桌面端目视复验) | 管理端全局框架与工作台已按规格交付;18 modules + 22 routes,vue-tsc 与 vite build 全绿 |
| UI-MINIAPP-20260913 | 已完成 | 小程序 11 个核心页面已重构;11/11 页 TS-only,2026-09-16 通过用户验收 |