fix(activity): close Phase 14 KEEP-VERIFY/EXTEND — 11 backend + 3 frontend-contract + 2 test-fidelity defects
Phase 14 (multi-type public-welfare activities) verification closure. Backend (D1-D11): - D1 CRITICAL: ActivityMapper.countRemainingCapacity had no @Select and no XML -> activity detail / register / approve all threw Invalid bound statement. Removed the shell; unified on ActivityRegistrationMapper. - D2 CRITICAL: register & approve were read-then-write -> oversold under concurrency. Replaced with single atomic SQL (insertIfCapacityAvailable / approveIfCapacityAvailable, affectedRows==0 => full). - D3 HIGH: activityType / orgRole never validated against production chk_activity_type / chk_org_role -> 500 only on PostgreSQL. - D4 HIGH: ActivityListItemDTO had no activityType -> miniapp category tabs always empty (Gate failure). - D5: male/female counts were fabricated as approvedCount/2; now real aggregation over user_profiles.gender. - D6: minAge/maxAge was a TODO no-op; added assertAgeInRange. - D7: registration_policy write-only; per-type eligibility now enforced (identity / local eligibility / gender quota). - D8: POST /operator/activities dropped type, multi-org and capacity groups and set organizer_org_id to the operator user id; now delegates to createActivityFromAdmin (single implementation). - D9: three operator write endpoints were mounted on the user-side ActivityController (dual implementation, zero callers) -> moved. - D10: NPE on soft-deleted activity in getMyActivities; NPE/500 on missing admin form fields (Instant.parse(null)); tolerant time parsing added. - D11: DTO lacked registeredCount / status / coverFileId / description -> card always showed 0 registered, "view detail", no cover, no summary. Frontend contract (F1-F3): - F1: miniapp category code "classroom" is not in the production whitelist (should be relationship_education); three types had no tab at all. - F2: ui-activity-card read 7 fields that do not exist on the backend; now reads only real DTO fields, plus per-type badge and eligibility hint. - F3: admin-web had no activity management page at all; added ActivityManagementView.vue (type-driven dynamic form, multi-org, capacity groups, publish/cancel) + /activities route and nav entry. Test fidelity (T1-T2): - T1: deleted two assertTrue(true) placeholder tests (testNoOverbooking, testNoDuplicateRegistration) that covered the exact broken invariants. - T2: test schema lacked V023 columns/constraints and three tables; the activity tables were only in the OPTIONAL set (zero coverage) -> schema completed and moved to REQUIRED_IN_TEST_SCHEMA. Tests: ActivityPhase14Test (23 cases), ActivityConstraintGuardTest (9 cases, parses real db/migration/V*.sql plus miniapp source). Two negative-verification rounds proved both guard families actually turn red. Regression: 450 tests / 0 failures / 0 errors / 3 skipped / BUILD SUCCESS (baseline 420). admin-web vue-tsc 0 error, vite build OK.
This commit is contained in:
@@ -5,6 +5,22 @@
|
||||
|
||||
> **2026-09-16 状态校正:** Phase 07 UI 已按 2026-09-13 规格重新实现,**首批 11 页于 2026-09-16 通过用户验收(结论:基本达标)**,本文件此前"视觉否决/REOPENED"口径随之关闭。
|
||||
>
|
||||
> **2026-09-17 Phase 14 复验关闭:** EPIC-P14 已完成。复验发现 activity 模块存在**必崩级空壳**——
|
||||
> `ActivityMapper.countRemainingCapacity` **既无 `@Select` 也无 XML**,而 `ActivityService` 调用的
|
||||
> 正是它 → 活动详情/报名/审核三条路径必然抛 `Invalid bound statement`。修复 **11 处后端缺陷**:
|
||||
> **D1(Critical,生产故障)** Mapper 空壳致三条路径必崩;
|
||||
> **D2(Critical,并发)** 报名与审核「先读后写」→ 并发**超卖**,改单条原子 SQL;
|
||||
> **D3(High,生产故障)** `activityType`/`orgRole` 未校验生产 CHECK 白名单(只在 PG 上炸);
|
||||
> **D4(High,契约)** `ActivityListItemDTO` 无 `activityType` → 小程序分类 Tabs 恒无数据;
|
||||
> D5 男女人数为 `approvedCount/2` 编造;D6 年龄门槛为 TODO 空壳;D7 `registration_policy` 只写不读;
|
||||
> **D8 `POST /operator/activities` 丢弃类型/多组织/分组且把 `organizer_org_id` 错设为操作者 userId**;
|
||||
> D9 三个运营写入端点错挂用户端控制器(双实现);D10 软删活动与缺字段致 NPE/500;
|
||||
> D11 DTO 缺 `registeredCount`/`status`/`coverFileId`/`description`。
|
||||
> 另有 **3 处前端契约缺陷**(小程序分类 code `classroom` 不在白名单、卡片读 7 个不存在的字段、
|
||||
> admin-web 无活动管理页 → 新增 `ActivityManagementView.vue` 动态表单)与
|
||||
> **2 处测试保真度缺陷**(2 条 `assertTrue(true)` 占位假绿;测试库缺 V023 列与三张表、activity 五表零覆盖)。
|
||||
> 证据:`docs/Phase-14-V11-Recovery-Completion-Report-2026-09-17.md`。**Phase 15 需用户确认后启动。**
|
||||
>
|
||||
> **2026-09-17 Phase 13A 复验关闭:** EPIC-P13A 已完成。复验发现 counseling 模块存在**双实现**——
|
||||
> 线上权威 `CounselingService`(167 行)**零测试**,唯一被测的 `CounselingServiceApp`(280 行)是
|
||||
> **孤儿类**(无注入点、无 HTTP 端点可达,生产永不执行)→ 已合并并删除孤儿类。修复 **9 处缺陷**:
|
||||
@@ -103,6 +119,7 @@
|
||||
| Phase 12 Relationship Progress 复验 | 已完成(2026-09-16) | 见 `Phase-12-V11-Recovery-Completion-Report-2026-09-16.md`;修复 4 处缺陷(**实体↔生产迁移系统性漂移 23 表 50 列**、双路径 episode/NPE、测试库缺 7 表致首页零覆盖、计划项 2 未实现),新增永久守卫 `EntityMigrationParityTest`,删除 2 个假测试类,后端 371 tests 全绿 |
|
||||
| Phase 13 公益红娘转介复验 | 已完成(2026-09-16) | 见 `Phase-13-V11-Recovery-Completion-Report-2026-09-16.md`;修复 7 处缺陷(**2 处生产故障级 CHECK 约束缺口致推荐接受/服务提交必崩**、推荐与转介三处越权、`getServiceDetail` 越权读、Mapper 缺 `@Select` 致必崩、前端 5 处契约缺口),测试库补 3 张 matchmaker 表,迁移基线 V038;新增 `MatchmakerReferralPhase13Test`(17 用例)+ 重写 `MatchmakerServiceTest`(6 用例,解析真实 DDL),删除 3 处假测试,后端 **391 tests 全绿**;**Phase 13A 尚未获准** |
|
||||
| Phase 13A 婚恋咨询与婚前辅导复验 | 已完成(2026-09-17) | 见 `Phase-13A-V11-Recovery-Completion-Report-2026-09-17.md`;发现 counseling **双实现**(权威类零测试 / 孤儿类被单测),已合并删除孤儿类;修复 **9 处缺陷**(**D1 咨询正文写日志=INV-013 泄露**、D2 申请 userId 取请求体、**D3 分配先读后写并发静默覆盖**、D4 manager 可读 followups=INV-013 绕过、D5 无状态机、**D6 `/services/intro` 后端不存在致小程序 intro 页 100% 无数据**、D7 Admin 5 端点 404、D8 小程序字段名/幂等/静默失败、D9 测试库 counseling 零 CHECK 约束)+ **4 处测试基建缺陷**(守卫找不到 DDL 恒真假绿、全限定 `@TableField` 漏解析、权限守卫假阳性、测试自身逻辑缺陷);迁移基线 V039;新增 `CounselingPhase13ATest`(25)+ `CounselingConstraintGuardTest`(5,解析真实 DDL),两轮负向验证证明守卫会红;后端 **420 tests 全绿**;**Phase 14 尚未获准** |
|
||||
| Phase 14 多类型公益活动复验 | 已完成(2026-09-17) | 见 `Phase-14-V11-Recovery-Completion-Report-2026-09-17.md`;修复 **11 处后端缺陷**(**D1 `ActivityMapper.countRemainingCapacity` 无 SQL 空壳致详情/报名/审核必崩**、**D2 报名与审核先读后写并发超卖** → 改原子 SQL、D3 类型/角色未校验生产 CHECK 白名单、**D4 DTO 无 `activityType` 致小程序分类 Tabs 恒空**、D5 男女人数 `approvedCount/2` 编造、D6 年龄门槛空壳、D7 按类型资格策略为空、**D8 运营端建活动丢弃类型且把主办组织错设为操作者 userId**、D9 三个运营端点错挂用户端双实现、D10 软删活动/缺字段 NPE、D11 DTO 缺 4 字段)+ **3 处前端契约缺陷**(分类 code `classroom` 不在白名单、卡片读 7 个不存在字段、admin-web 无活动管理页)+ **2 处测试保真度缺陷**(2 条占位假绿、测试库缺 V023 列与三张表);新增 `ActivityPhase14Test`(23)+ `ActivityConstraintGuardTest`(9,解析真实 DDL **与前端源码**),两轮负向验证证明守卫会红;admin-web `vue-tsc` 0 error + `vite build` 通过;后端 **450 tests 全绿**;**Phase 15 尚未获准** |
|
||||
| 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 通过用户验收 |
|
||||
|
||||
Reference in New Issue
Block a user