## 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
119 lines
6.1 KiB
Markdown
119 lines
6.1 KiB
Markdown
# 善缘丹阳 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 工具。
|