refactor(backend): P0 阻断修复 + 按最新修改时间收敛重复模块与契约
## P0 阻断修复
- 编译:修复实体类与服务类同名导致 Lombok 注解轮次中止的问题
(MatchmakerService/CounselingService -> *Record),196 个编译错误归零
- 权限矩阵:platform_admin 按设计文档收紧为拒绝 5 项高危权限(不改测试阈值)
- 启动:修复 8 组 MyBatis-Plus 同名 bean 冲突(ConflictingBeanDefinition)
与 URL 路由歧义(Ambiguous mapping),应用可正常启动
## 模块收敛(裁决规则:以文件修改时间为准)
- messaging 包整体删除,能力迁移至 chat 包
* 会话列表/详情/未读端点、ConversationDTO、CursorPage
* 消息游标分页统一为 { items, nextCursor }
- relationship 的 Match/UserRelation entity 与 mapper 合并进 match 包
- MatchmakerUserController 合并进 MatchmakerController,删除冗余 Controller
- 补齐 INV-004:chat sendText 增加双向 Block 校验,拉黑后禁止发送
## 契约对齐
- 红娘服务提交请求兼容前端 { requirement } 字段
- 消息与会话分页契约前后端统一
## 测试
- 迁移 6 个风控用例至 ChatSafetyServiceTest
- 清理 messaging 测试包遗留:6 个真实常量断言归位 chat 包,
移除 2 个 assertTrue(true) 占位假测试(Block 真实行为已由
P0FixVerificationTest / RelationshipBlockPriorityPhase08Test 覆盖)
- schema-h2.sql 对齐 PostgreSQL 真实表结构(matches 补列、
conversation_members 改复合主键)
结果:290 tests, 0 failures, 0 errors, 3 skipped, BUILD SUCCESS
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
# 善缘丹阳 V1.1 — P0 阻断项修复报告
|
||||
|
||||
> 日期:2026-09-15 | 范围:backend | 验证方式:Docker 容器内 Maven 构建 + 全量测试
|
||||
> **结论:293 tests / 0 failures / 0 errors / BUILD SUCCESS**(修复前:196 个编译错误 + 应用无法启动)
|
||||
|
||||
---
|
||||
|
||||
## 一、最终验证
|
||||
|
||||
```
|
||||
[INFO] Tests run: 293, Failures: 0, Errors: 0, Skipped: 3
|
||||
[INFO] BUILD SUCCESS
|
||||
```
|
||||
|
||||
Spring 应用上下文成功启动 4 次,`Failed to load ApplicationContext` 归零。
|
||||
共改动 **46 个文件**,**未提交**(保留在工作区待评审)。
|
||||
|
||||
---
|
||||
|
||||
## 二、修复链条(每修一层暴露下一层)
|
||||
|
||||
### P0-1 编译断裂:196 错误 → 0
|
||||
|
||||
| 根因 | 说明 | 处理 |
|
||||
|---|---|---|
|
||||
| **同名类冲突导致 Lombok 停摆** | `MatchmakerService`、`CounselingService` 既是实体又是 Service,javac 因重复定义中止注解处理轮次,Lombok 不生成 getter/setter,引发约 110 个"找不到符号" | 实体重命名为 `MatchmakerServiceRecord` / `CounselingServiceRecord`(均有显式 `@TableName`,不影响 DB 映射) |
|
||||
| 契约缺失 | `ApiResponse` 缺 `unauthorized()/forbidden()/notFound()`(35 处调用) | 补齐 3 个工厂方法 |
|
||||
| 命名约定分裂 | `NotificationService` 已有业务通知方法但命名不同(phase-11 与后续提交分裂) | 按调用方约定补 9 个 `sendXxx` 别名,内部复用既有隐私安全模板 |
|
||||
| 其他 | 多个 mapper 缺方法、`ChatService` Optional 未解包、`ChatSafetyService` redis expire 类型错误、缺 import | 逐个补齐 |
|
||||
|
||||
> 顺带修正一处语义 bug:Service 文件里 `new MatchmakerService()`、返回类型 `List<MatchmakerService>` 本意是实体,因同名实际解析成了 Service 类自己。
|
||||
|
||||
### P0-2 权限矩阵测试:失败 → 12/12 通过
|
||||
|
||||
失败断言:`platform_admin 应有至少5个被拒绝的权限`(实际只拒 1 项)。
|
||||
|
||||
**采用收紧权限的方式修复,未放宽测试。** 依据 `运营管理后台与组织权限体系详细设计.md`:
|
||||
|
||||
| 权限 | 依据 |
|
||||
|---|---|
|
||||
| `user.sensitive.view` → 拒绝 | 第十二章:完整身份证查看"仍应单独授权" |
|
||||
| `risk.user.ban` → 拒绝 | 第六十九章:永久封禁属严重高风险,"至少由高权限角色操作" |
|
||||
| `organization.manage` → 拒绝 | 第十一章:组织管理属 super_admin |
|
||||
| `permission.manage` → 拒绝 | 第十一章:权限管理属 super_admin |
|
||||
| `data.export` → 拒绝 | 第一百零三章:导出须单独授权,"不要能看列表就能导出" |
|
||||
|
||||
### 迁移基线
|
||||
|
||||
`MigrationValidationTest.LATEST_MIGRATION` 33 → 35(实际 V001–V035,35 个脚本)。该测试是"基线守卫",新增迁移时本就应同步递增。
|
||||
|
||||
### P0-0(新发现,比原三项更严重)应用无法启动 → 修复
|
||||
|
||||
**8 组 Spring bean 重名** —— 全部是并行模块重复所致:
|
||||
|
||||
| 重复 bean 名 | 位置 |
|
||||
|---|---|
|
||||
| MessageController、MessageMapper、ConversationMapper、ConversationMemberMapper、ChatWebSocketHandler、WebSocketConfig | `chat` vs `messaging` |
|
||||
| MatchMapper、UserRelationMapper | `match` vs `relationship` |
|
||||
|
||||
处理:`messaging` 三个 mapper 加 `Legacy` 前缀、`relationship` 两个 mapper 加 `Relationship` 前缀、遗留 Controller 与 WebSocket 类显式指定 bean 名。**未删除任何模块**(保留可逆性)。
|
||||
|
||||
**路由歧义**:`GET/POST /matchmaker/services` 在 `MatchmakerController` 与 `MatchmakerUserController` 重复映射。删除后者的重复方法,保留其独有的 `/services/{id}`(小程序依赖)。
|
||||
|
||||
---
|
||||
|
||||
## 三、重要更正:昨天的 P0-3 判断有误
|
||||
|
||||
昨日评估称"V1.1 四个新角色零实现、硬规则 #22–#25 未落地"——**此结论错误**。
|
||||
|
||||
`V015__add_v11_roles_and_permissions.sql` 已完整实现四角色,且权限设计相当克制:
|
||||
|
||||
- `service_station_operator`:仅服务站查看 + 预约确认/完成 → 符合硬规则 #24
|
||||
- `counselor`:仅 `counseling.service.view/process` + `note.create`(**无 note.view**)→ 符合 INV-012
|
||||
- `counseling_manager`:带 `note.view` → INV-013 分层正确
|
||||
- `content_editor`:仅 `content.*` → 符合硬规则 #23
|
||||
|
||||
**缺的是 admin-web 前端 UI,不是后端。** 教训:此前只 grep 了前端,未检查数据库迁移脚本。
|
||||
|
||||
---
|
||||
|
||||
## 四、新发现(未修,需要决策)
|
||||
|
||||
### 1. 两套并行聊天实现(架构级)
|
||||
`chat`(V1.1) 与 `messaging`(V1.0) 都映射 `conversations` 表。
|
||||
- `chat`:`ConversationController.list()` 是**桩**(`TODO` + 返回空列表),缺 `/conversations/{id}`、`/unread`
|
||||
- `messaging`:功能完整(图片消息/历史/未读数),但端点前缀 `/messages`,前端不调
|
||||
|
||||
当前两者并存可启动,但长期是数据一致性隐患。**需决定合并方向。**
|
||||
|
||||
### 2. role_permissions 种子数据残缺(运行时权限实际是坏的)
|
||||
- `platform_admin`:只有 V1.1 权限,**V1.0 那 18 个一条没有**(无法查看用户、审核、活动)
|
||||
- `super_admin`:只有 V1.0 权限,**V1.1 的 30 多个全缺**
|
||||
- `reviewer` / `matchmaker` / `activity_manager` / `risk_operator` / `volunteer` / `data_viewer`:**从未被授予任何权限**
|
||||
|
||||
### 3. 前后端契约不一致
|
||||
小程序 `applyService` 发送 `{ requirement }`,后端 `SubmitRequest` 接收 `{ serviceType, description }`。
|
||||
|
||||
### 4. 缺失端点
|
||||
小程序调用的 `/conversations/{id}/unread`,两个包都没有实现。
|
||||
|
||||
---
|
||||
|
||||
## 五、环境备忘(本机无 JDK,务必按此执行)
|
||||
|
||||
```bash
|
||||
MSYS_NO_PATHCONV=1 docker run --rm \
|
||||
-v "E:/develop/公益婚恋服务平台:/proj" \
|
||||
-v danyang-m2-cache:/root/.m2/repository \
|
||||
-w /proj danyang-match-backend-test:latest \
|
||||
mvn -B -f backend/pom.xml test
|
||||
```
|
||||
|
||||
三个坑:
|
||||
1. **必须挂载项目根目录**(不是 backend),否则按 `backend/src/...` 取路径的测试会误报 NoSuchFileException(本次误报 16 个)
|
||||
2. **不要用 `-o`**:缺 `surefire-junit-platform`,且容器 `--rm` 不留存下载 → 用命名卷持久化 `/root/.m2/repository`
|
||||
3. **`mvn clean` 离线会失败**(clean 插件未缓存)→ 手动 `rm -rf backend/target/classes`
|
||||
|
||||
另:本机 `find` 在中文路径下对所有目录返回 0,统计文件请用 `grep -rl ... | wc -l` 或 Glob 工具。
|
||||
@@ -0,0 +1,137 @@
|
||||
# 善缘丹阳 V1.1 代码进度实测与差距评估
|
||||
|
||||
日期:2026-09-15
|
||||
分支:`codex/ui-v11-fidelity`(HEAD `9d73087`,工作区干净,0 未提交)
|
||||
方法:**以代码与构建产物为唯一证据**,不采信任何文档中的"已完成 / ✅ / 已部署"声明(依据 AGENTS.md 执行纪律)
|
||||
|
||||
---
|
||||
|
||||
## 一、结论先行
|
||||
|
||||
| 项 | 结论 |
|
||||
|---|---|
|
||||
| 整体状态 | **NO-GO**(距可验收仍有实质差距) |
|
||||
| 代码资产真实完成度 | **约 55%**(显著高于文档自评的 35%,但低于模块覆盖率给人的直觉) |
|
||||
| 最致命问题 | **后端 HEAD 源码无法编译**(`HomeApplicationService` 两处硬错误,且已提交入库) |
|
||||
| 最危险的合规缺口 | **V1.1 四个新角色零实现** + 唯一失败的测试正是 `PermissionMatrixTest` |
|
||||
| 文档可信度 | **严重失真**,且失真方向是*低估*代码、*高估*风险,导致计划与代码脱节 |
|
||||
|
||||
> 一句话:代码的"宽度"已铺开(模块几乎都有),但"深度"不足(推荐算法是壳、业务闭环断裂),且当前处于**构建断裂**状态。
|
||||
|
||||
---
|
||||
|
||||
## 二、三端实测数据
|
||||
|
||||
### 2.1 后端(Java / Spring Boot)
|
||||
|
||||
| 指标 | 实测值 | 证据 |
|
||||
|---|---|---|
|
||||
| Java 源文件 | 约 300 个(Controller 56 / Service 53 / Mapper 56 / DTO 35) | `src/main/java` 统计 |
|
||||
| 领域包 | 37 个顶层包 | `com.danyang.match.platform/*` |
|
||||
| Flyway 迁移 | **V001–V035** | 文档仅登记到 V027 |
|
||||
| 测试类 | 59 个 | `src/test` |
|
||||
| 上次成功测试结果 | **293 tests / 1 failure / 0 errors / 3 skipped** | `target/surefire-reports`(快照 2026-09-13) |
|
||||
|
||||
**V1.1 八大新增模块覆盖(源码级)**
|
||||
|
||||
| 模块 | 状态 | 说明 |
|
||||
|---|---|---|
|
||||
| banner | 有 | 仅运营端接口,缺 C 端读接口(靠 home 聚合兜底) |
|
||||
| service_location | 有 | 未独立成包,并入 `service_appointment/` |
|
||||
| appointment | 有 | 实际包名为 `service_appointment/` |
|
||||
| counseling | 有(**双实现**) | `CounselingService`(167行,线上) 与 `CounselingServiceApp`(280行,仅测试引用) 并存 |
|
||||
| content | 有 | 分类 + 文章 |
|
||||
| service_program | 有 | — |
|
||||
| local_eligibility | 有 | — |
|
||||
| home | **有但编译失败** | `HomeApplicationService` 两处硬错误 |
|
||||
|
||||
**Phase 14–18 真实代码量(文档称"暂停",实际有码)**
|
||||
|
||||
`activity_mutual` 6 · `appeal` 8 · `risk` 14 · `analytics` 2 · `relationship` 12 · `referral` 2 · `verification` 6 · `review` 11
|
||||
|
||||
### 2.2 小程序端(63 页)
|
||||
|
||||
- 完整实现约 **50 页**,空壳 **3 页**(`bind-phone` 45B、`activity-register` 89B、`my-activities` 89B),写死假数据 **7 页**(`service-center`、`service-program`、`service-appointment`、`service-history`、`my-appointments`、`content-detail`、`anti-fraud`)
|
||||
- **首页固定结构 10/10 全对**:顶部品牌 / 用户状态 / Banner / 8 核心入口(顺序与命名全对)/ 今日推荐 / 善缘公益服务 / 近期公益活动 / 善缘服务站 / 婚恋课堂 / 安全提醒,且调用真实 `GET /home`
|
||||
- 服务层 13 个 + stores 9 个均为真实 HTTP,无 mock 分支
|
||||
|
||||
### 2.3 管理后台(Vue 3)
|
||||
|
||||
- 23 个 `.vue`,`src` 共 4858 行;业务模块(Banner/内容/服务站/预约/咨询/专项/审核/用户)**均存在且接真实接口**
|
||||
- **架构层空心**:`src/components`、`src/pages`、`src/permissions`、`src/modules/recommendation` **均为空目录**
|
||||
- UI 重构仅推广到 3/17 文件,14 个仍用旧内联样式;`theme` 变量与布局硬编码冲突(220px vs 208px)
|
||||
|
||||
---
|
||||
|
||||
## 三、与 V1.1 硬规则对账(最关键部分)
|
||||
|
||||
| 规则 | 要求 | 实测 | 判定 |
|
||||
|---|---|---|---|
|
||||
| #14/#15 #17 | 首页结构 + 8 入口顺序固定 | 小程序 10/10 符合 | ✅ 通过 |
|
||||
| #26 | 入口由服务端 CapabilityService 决定 | `capability/` 包存在(Controller+Service,10 处引用) | ✅ 后端具备 |
|
||||
| #16 | Banner 仅内部跳转 | 待验证 target_type 枚举约束 | ⚠️ 待测 |
|
||||
| #18/#19/#20 | 活动互选二阶段同意 | `activity_mutual` 有 6 个文件 | ⚠️ 待测 |
|
||||
| #22 Counselor 仅 Assigned | — | 有 `CounselingDataScopeTest` | ⚠️ 待测 |
|
||||
| #23 ContentEditor 零用户数据 | — | 有 `ContentControllerPermissionContractTest` | ⚠️ 待测 |
|
||||
| #24 服务站不可浏览全库 | — | 仅有 `ServiceAppointmentDataScopeTest` | ⚠️ 待测 |
|
||||
| **#22–#25 四新角色** | `service_station_operator` / `counseling_manager` / `content_editor` / `counselor` | **管理端 3 个角色 0 次出现**,仅 `counselor` 存在于 `stores/auth.ts` 硬编码假数据 | ❌ **未实现** |
|
||||
|
||||
> **红线提示**:唯一失败的测试是 `invariants.PermissionMatrixTest`。权限矩阵不通过 + 四个角色未实现,对公益平台属合规级风险,应优先于一切 UI 工作。
|
||||
|
||||
---
|
||||
|
||||
## 四、文档 vs 代码的偏差(文档失真清单)
|
||||
|
||||
| # | 文档声明 | 代码事实 |
|
||||
|---|---|---|
|
||||
| 1 | "Phase 08 及以后仍暂停" | git 已有 `phase-08`~`phase-13A` 六个 feat 提交;Phase 14–18 相关包亦有代码 |
|
||||
| 2 | "未检出独立 CapabilityService" | `capability/` 包存在(提交 `dd58ab6` 即为抽取 CapabilityService) |
|
||||
| 3 | "Flyway V001–V027" | 实际 V001–**V035** |
|
||||
| 4 | "工作区 55 个未提交改动" | 当前 **0 个**(已收口) |
|
||||
| 5 | "277 tests → 4F / 8E / 3S" | 上次快照 **293 tests → 1F / 0E / 3S** |
|
||||
| 6 | 自评完成度 35% | 代码资产约 55% |
|
||||
|
||||
**判断**:文档更新跟不上代码推进,且昨日的评估文档(2026-09-14)结论已有 3 条被证伪。继续执行前必须先重建文档基线,否则计划会持续建立在过期认知上。
|
||||
|
||||
---
|
||||
|
||||
## 五、差距清单(按严重度)
|
||||
|
||||
### P0 — 阻断(必须先修)
|
||||
1. **后端编译断裂**:`HomeApplicationService.java` 第 114 行使用未声明的 `userIdentityMapper`;第 133 行使用未 import 的 `LocalEligibility`。已提交入库,`target/classes` 停留在 09-13 19:20,源码 09-14 11:34。首页聚合 API 当前不可用。
|
||||
2. **权限矩阵测试失败**:`PermissionMatrixTest` 1 failure,须定位是不变量实现缺陷还是测试用例缺陷。
|
||||
3. **V1.1 四个新角色未实现**:管理端角色表单无角色字段,硬规则 #22–#25 无法落地。
|
||||
|
||||
### P1 — 业务闭环断裂
|
||||
4. **小程序服务站链路全断**:`service-center` → 预约 → 我的预约 → 服务记录,4 页全为写死数组,无后端调用。
|
||||
5. **登录链路断**:`bind-phone` 为 45 字节空壳。
|
||||
6. **活动报名闭环断**:`activity-register` / `my-activities` 为占位;`activity-detail` 渲染写死 `previewActivity`。
|
||||
7. **推荐算法是壳**:`MatchEligibilityService` 8 处 TODO(候选池、评分、推荐理由未实现),`RecommendationEngineService` 占位。
|
||||
|
||||
### P2 — 架构与一致性
|
||||
8. 平行重复包:`messaging/` 与 `chat/` 双套会话;`relationship/` 与 `match/` 双套匹配。
|
||||
9. `counseling` 双 Service 实现,完整版未接入线上。
|
||||
10. 管理端 6 个已注册路由无菜单入口(`/appeals`、`/audit`、`/banner`、`/service-appointment`、`/service-program`、`/matchmaker`)。
|
||||
11. 管理端架构目录(components/permissions/recommendation)为空,无复用组件与权限指令。
|
||||
12. banner / service_program / home 三个模块**零测试**。
|
||||
|
||||
---
|
||||
|
||||
## 六、建议的下一步(顺序不可颠倒)
|
||||
|
||||
1. **先修 P0-1**:补全 `userIdentityMapper` 声明与 `LocalEligibility` import,`mvn compile` 通过后再谈其他。
|
||||
2. **修 P0-2**:定位 `PermissionMatrixTest` 失败原因并清零。
|
||||
3. **重建文档基线**:将 V028–V035 迁移、Phase 08–13A 完成状态、CapabilityService 现状写回 `STATUS.md` / `JIRA_BACKLOG.md`,使文档与代码口径一致。
|
||||
4. **补 P0-3 角色权限**:这是 V1.1 硬规则,也是公益平台合规底线,优先级高于 UI 打磨。
|
||||
5. **再推进 UI 终验**:管理端第二批 + 小程序 C 组,按参考图逐页验收。
|
||||
6. **最后补 P1 业务闭环**:服务站 / 登录 / 活动报名三条链路。
|
||||
|
||||
> 每步完成后暂停,输出完成报告并等待人工验收,不自动进入下一步。
|
||||
|
||||
---
|
||||
|
||||
## 附:本次核验方法说明
|
||||
|
||||
- 代码统计使用 `grep -rl` / Glob 工具(`find` 在本机中文路径下失效,返回 0,已排除该误判)
|
||||
- 编译结论为静态分析(未声明变量 + 未 import 类型),并以 `target/classes` 与源码 mtime 差作为交叉验证
|
||||
- 测试结论取自 `target/surefire-reports` 汇总,为 2026-09-13 快照,非当前源码状态
|
||||
Reference in New Issue
Block a user