From 7a2693b239827116aa0a33dd3a987e94e4102d8e Mon Sep 17 00:00:00 2001 From: WorkBuddy Date: Thu, 17 Sep 2026 01:25:12 +0800 Subject: [PATCH] =?UTF-8?q?fix(counseling):=20close=20Phase=2013A=20KEEP-V?= =?UTF-8?q?ERIFY/EXTEND=20=E2=80=94=209=20real=20defects=20+=204=20test-in?= =?UTF-8?q?fra=20defects?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 13A(婚恋咨询与婚前辅导)复验关闭。历史 ✅ 不可信:counseling 模块存在双实现, 线上权威 CounselingService(167 行)零测试,唯一被测的 CounselingServiceApp(280 行) 是孤儿类(无注入点、无 HTTP 端点可达,生产永不执行)→ 已合并并删除。 生产缺陷(D1~D9): - D1 Critical 生产故障 · INV-013 泄露:咨询正文 userRequestSummary 原文被写入 WARN 日志 (同 Phase 10 D2 一族)→ 改为只记 serviceId + riskLevel,绝不记正文。 - D2 High 越权:申请 userId 取自请求体而非认证主体 → Controller 强制 principal.id()。 - D3 High 并发:分配用「先读后写」→ 两管理员并发分配静默覆盖; 改 assignIfPending 条件更新(WHERE status='pending' AND assigned_operator_id IS NULL), affectedRows=0 明确报错。 - D4 High 越权读:counseling_manager 经 getDetail 可读 followups 正文 → INV-013 绕过通道; manager 只加回 userRequestSummary,不装配 followups。 - D5 Medium:无状态机 → 「已完成」可被再取消;新增 ALLOWED_TRANSITIONS + assertTransition。 - D6 Medium 生产故障:GET /counseling/services/intro 后端不存在(且被 /services/{id} 吞掉) → 小程序 intro 页 100% 无数据;补端点并声明在变量路径之前。 - D7 Medium 契约:Admin 调用 5 条不存在的 /services/operator/*(404)+ 缺四态 → 后端补 8 个运营端端点(@PreAuthorize),前端整体重写 + 注册 /counseling 路由。 - D8 Medium 契约:小程序字段名错(userRequestSummary/preferredServiceMode)+ 无幂等 + my-counseling 未检查 success(403 静默空列表)+ 跳转不存在的页 + WXML 内调用方法。 - D9 Medium 测试保真度:测试库 counseling 两表零 CHECK 约束, counseling_services 未列入 EntityMigrationParityTest 任何集合(= 零覆盖)。 测试基建缺陷(T1~T4,不修即恒真假绿): - T1 守卫找不到 DDL:surefire workingDirectory = ${project.basedir}/.. 使 CWD 为仓库根, 且 backend/ 是子目录非祖先 → 改为候选后缀 + 逐级向上定位,失败大声抛异常。 - T2 全限定 @com.baomidou...TableField(exist=false) 漏解析(假漂移警报)→ 正则放宽 + 回归守卫。 - T3 OperatorEndpointPermissionCoverageTest 扫到私有辅助方法(假阳性)→ 只扫描真实端点 + 自检。 - T4 两处测试自身逻辑缺陷:陈旧内存快照比较、Instant 纳秒 vs DB 微秒精度。 迁移:新增 V039(counseling 幂等键 + 三个 CHECK 白名单显式固化),基线 38 → 39。 负向验证两轮(均已还原,grep -c NEG-VAL = 0): - ① DDL 常量守卫:从 V039 移除 'scheduled' → 常量守卫精准变红 (证明解析的是真实 DDL 而非副本)。 - ② 行为守卫:注入「并发回退先读后写 / manager 读 followups / 状态机守卫失效」 → 三个用例各自精准变红。 测试:新增 CounselingPhase13ATest(25)+ CounselingConstraintGuardTest(5,解析真实 DDL); 删除孤儿类及其 3 个 DTO、删除测死代码的 CounselingDataScopeTest。 全量回归:Tests run: 420, Failures: 0, Errors: 0, Skipped: 3 / BUILD SUCCESS(4:49)。 基线 391 → 420(净 +29)。admin-web vue-tsc EXIT=0;miniapp tsc EXIT=0。 Tag: phase13a-recovery-2026-09-17 Report: docs/Phase-13A-V11-Recovery-Completion-Report-2026-09-17.md --- .../src/modules/counseling/CounselingView.vue | 288 +++++++++--- .../controller/CounselingController.java | 218 +++++++-- .../counseling/dto/CounselingDTO.java | 31 -- .../counseling/dto/CounselingRequest.java | 18 - .../platform/counseling/dto/FollowupDTO.java | 14 - .../entity/CounselingServiceRecord.java | 27 ++ .../mapper/CounselingFollowupMapper.java | 8 + .../mapper/CounselingServiceMapper.java | 25 +- .../counseling/service/CounselingService.java | 330 ++++++++++++-- .../service/CounselingServiceApp.java | 292 ------------ ...unseling_idempotency_and_status_guards.sql | 58 +++ .../CounselingConstraintGuardTest.java | 255 +++++++++++ .../counseling/CounselingDataScopeTest.java | 93 ---- .../counseling/CounselingPhase13ATest.java | 430 ++++++++++++++++++ .../deployment/EntityMigrationParityTest.java | 35 +- .../deployment/MigrationValidationTest.java | 2 +- ...peratorEndpointPermissionCoverageTest.java | 30 +- backend/src/test/resources/schema-h2.sql | 22 +- docs/JIRA_BACKLOG.md | 85 +++- ...1-Recovery-Completion-Report-2026-09-17.md | 272 +++++++++++ docs/STATUS.md | 83 +++- ...阳 V1.1 客户需求基线增量开发与修复计划.md | 43 +- .../counseling-request/counseling-request.ts | 44 +- miniapp/pages/my-counseling/my-counseling.ts | 110 ++++- .../pages/my-counseling/my-counseling.wxml | 57 ++- .../premarital-request/premarital-request.ts | 38 +- 26 files changed, 2208 insertions(+), 700 deletions(-) delete mode 100644 backend/src/main/java/com/danyang/match/platform/counseling/dto/CounselingDTO.java delete mode 100644 backend/src/main/java/com/danyang/match/platform/counseling/dto/CounselingRequest.java delete mode 100644 backend/src/main/java/com/danyang/match/platform/counseling/dto/FollowupDTO.java delete mode 100644 backend/src/main/java/com/danyang/match/platform/counseling/service/CounselingServiceApp.java create mode 100644 backend/src/main/resources/db/migration/V039__add_counseling_idempotency_and_status_guards.sql create mode 100644 backend/src/test/java/com/danyang/match/platform/counseling/CounselingConstraintGuardTest.java delete mode 100644 backend/src/test/java/com/danyang/match/platform/counseling/CounselingDataScopeTest.java create mode 100644 backend/src/test/java/com/danyang/match/platform/counseling/CounselingPhase13ATest.java create mode 100644 docs/Phase-13A-V11-Recovery-Completion-Report-2026-09-17.md diff --git a/admin-web/src/modules/counseling/CounselingView.vue b/admin-web/src/modules/counseling/CounselingView.vue index 91e8f1f..2d9fd5a 100644 --- a/admin-web/src/modules/counseling/CounselingView.vue +++ b/admin-web/src/modules/counseling/CounselingView.vue @@ -1,45 +1,83 @@