401 lines
16 KiB
Markdown
401 lines
16 KiB
Markdown
# 丹阳公益婚恋服务平台 — 全面代码审查与测试报告
|
||||
|
|
|
|||
|
|
> 审查范围: 后端Java (329个文件) + Admin Web Vue3 + 微信小程序 + 测试体系
|
|||
|
|
> 审查日期: 2026-09-01
|
|||
|
|
> 审查工具: 人工静态分析 + 静态代码扫描 + 测试覆盖率分析
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 一、项目总体评估
|
|||
|
|
|
|||
|
|
| 维度 | 评分 | 说明 |
|
|||
|
|
|------|------|------|
|
|||
|
|
| 架构设计 | ⭐⭐⭐⭐⭐ | 模块化单体,职责清晰,329个Java文件结构合理 |
|
|||
|
|
| 核心不变量 | ⭐⭐⭐⭐☆ | 10条AGENTS核心规则大部分实现,但有3处关键TODO未完成 |
|
|||
|
|
| 安全设计 | ⭐⭐⭐⭐☆ | JWT+AES-GCM+权限矩阵设计良好,admin-web缺少RBAC路由守卫 |
|
|||
|
|
| 测试覆盖 | ⭐⭐⭐☆☆ | 42个测试文件,但多数为占位测试,真实集成测试薄弱 |
|
|||
|
|
| 代码质量 | ⭐⭐⭐⭐☆ | 整体规范,存在若干TODO和一处命名违规 |
|
|||
|
|
| 前端质量 | ⭐⭐⭐⭐☆ | Admin Web结构清晰,小程序stores编排设计优秀 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 二、严重问题 (Critical) — 必须修复
|
|||
|
|
|
|||
|
|
### C1: `RelationshipService.java:331` 方法名含中文字符
|
|||
|
|
**文件**: `backend/src/main/java/com/danyang/match/platform/relationship/service/RelationshipService.java`
|
|||
|
|
**行号**: 331
|
|||
|
|
```java
|
|||
|
|
private void 解除Match(String userId, String targetUserId) { ... }
|
|||
|
|
```
|
|||
|
|
**问题**: Java规范允许中文方法名,但这严重影响国际化开发、静态分析工具兼容性和团队协作。该方法实际未被调用(已被 `unmatch()` 替代),建议删除。
|
|||
|
|
**影响**: 代码可维护性
|
|||
|
|
**优先级**: P1
|
|||
|
|
|
|||
|
|
### C2: `MessagingService.isBlocked()` 返回硬编码false
|
|||
|
|
**文件**: `backend/src/main/java/com/danyang/match/platform/messaging/service/MessagingService.java`
|
|||
|
|
**行号**: 313-316
|
|||
|
|
```java
|
|||
|
|
private boolean isBlocked(String userId, String targetUserId) {
|
|||
|
|
// TODO: Phase 08 的 UserRelationMapper 查询
|
|||
|
|
return false; // ← 硬编码,Block不变量被破坏
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
**问题**: AGENTS.md 第4条 **"Block优先级最高"** 在此处被硬编码返回false破坏。当用户A拉黑用户B后,B仍可通过此方法检查,且聊天发送时 `isBlocked()` 永远返回false。
|
|||
|
|
**影响**: **违反核心不变量INV-003**,Block功能名存实亡
|
|||
|
|
**修复**:
|
|||
|
|
```java
|
|||
|
|
private boolean isBlocked(String userId, String targetUserId) {
|
|||
|
|
return relationMapper.findByRelation(userId, targetUserId, Constants.RELATION_TYPE_BLOCKED).isPresent();
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
**优先级**: P0 (阻塞上线)
|
|||
|
|
|
|||
|
|
### C3: `RelationshipStatusService` 多处核心逻辑为空实现
|
|||
|
|
**文件**: `backend/src/main/java/com/danyang/match/platform/relationship/service/RelationshipStatusService.java`
|
|||
|
|
|
|||
|
|
| 方法 | 行号 | 问题 |
|
|||
|
|
|------|------|------|
|
|||
|
|
| `pauseSearching()` | 49-59 | 尝试动态实例化UserMapper而非注入,逻辑断裂 |
|
|||
|
|
| `resumeSearching()` | 71-76 | TODO: 未更新relationship_status |
|
|||
|
|
| `setGettingToKnow()` | 83-89 | TODO: 未更新状态 |
|
|||
|
|
| `confirmSuccess()` | 132-174 | TODO: 缺少双确认检查(AGENTS第5条) |
|
|||
|
|
| `declineSuccess()` | 180-183 | 空实现 |
|
|||
|
|
| `exitService()` | 189-193 | 空实现 |
|
|||
|
|
| `updateUserRelationshipStatus()` | 197-200 | 空实现 |
|
|||
|
|
| `stopRecommendations()` | 202-206 | 空实现 |
|
|||
|
|
|
|||
|
|
**问题**: 成功牵手的"双确认"不变量 (INV-005) 在 `confirmSuccess()` 中没有实现双方都确认的检查逻辑。当前实现:任何一方调用即直接确认成功,违反AGENTS第5条 **"成功牵手必须双确认"**。
|
|||
|
|
**影响**: **违反核心不变量INV-005**
|
|||
|
|
**优先级**: P0 (阻塞上线)
|
|||
|
|
|
|||
|
|
### C4: `RecommendationService.getUserSummary()` 引用未注入字段
|
|||
|
|
**文件**: `backend/src/main/java/com/danyang/match/platform/match/service/RecommendationService.java`
|
|||
|
|
**行号**: 102, 114
|
|||
|
|
```java
|
|||
|
|
// 行102: 使用 userProfileService
|
|||
|
|
summary.put("age", userProfileService.calculateAge(profile.getBirthDate()));
|
|||
|
|
// ...
|
|||
|
|
// 行114: 字段声明在使用之后
|
|||
|
|
private final UserProfileService userProfileService;
|
|||
|
|
```
|
|||
|
|
**问题**: `userProfileService` 在第102行被使用,但在第114行才声明。虽然Spring的`@RequiredArgsConstructor`最终会注入所有final字段,但这会造成编译顺序问题和代码可读性问题。
|
|||
|
|
**影响**: 代码可维护性
|
|||
|
|
**优先级**: P2
|
|||
|
|
|
|||
|
|
### C5: `AccountLifecycleService.checkCanWithdraw()` 空查询条件
|
|||
|
|
**文件**: `backend/src/main/java/com/danyang/match/platform/account/service/AccountLifecycleService.java`
|
|||
|
|
**行号**: 141-143
|
|||
|
|
```java
|
|||
|
|
long activeRegistrations = registrationMapper.selectCount(
|
|||
|
|
new LambdaQueryWrapper<>() {}).longValue(); // simplified
|
|||
|
|
```
|
|||
|
|
**问题**: 空查询条件 `new LambdaQueryWrapper<>() {}` 会查询activity_registrations表的**全部行**,导致 `activeRegistrations` 始终很大,阻止所有用户注销。
|
|||
|
|
**影响**: 账号注销功能完全失效
|
|||
|
|
**修复**:
|
|||
|
|
```java
|
|||
|
|
long activeRegistrations = registrationMapper.selectCount(
|
|||
|
|
new LambdaQueryWrapper<ActivityRegistration>()
|
|||
|
|
.eq(ActivityRegistration::getUserId, userId)
|
|||
|
|
.in(ActivityRegistration::getStatus,
|
|||
|
|
Constants.REGISTRATION_STATUS_PENDING,
|
|||
|
|
Constants.REGISTRATION_STATUS_APPROVED));
|
|||
|
|
```
|
|||
|
|
**优先级**: P0
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 三、重要问题 (Major) — 建议修复
|
|||
|
|
|
|||
|
|
### M1: 推荐引擎双向Required过滤不完整
|
|||
|
|
**文件**: `backend/src/main/java/com/danyang/match/platform/match/service/RecommendationEngineService.java`
|
|||
|
|
**行号**: 213
|
|||
|
|
```java
|
|||
|
|
// TODO: 其他 Required 字段检查
|
|||
|
|
return true; // ← 身高、地区、婚姻状况等Required全部跳过
|
|||
|
|
```
|
|||
|
|
**问题**: AGENTS第2条 **"Required不可自动放宽"** 仅在年龄维度实现。身高、地区、婚姻状况等Required条件被忽略,导致不符合条件的用户仍可能出现在推荐中。
|
|||
|
|
**影响**: 推荐质量下降,违反INV-001
|
|||
|
|
**优先级**: P1
|
|||
|
|
|
|||
|
|
### M2: Match创建后Conversation未自动建立
|
|||
|
|
**文件**: `backend/src/main/java/com/danyang/match/platform/relationship/service/RelationshipService.java`
|
|||
|
|
**行号**: 204
|
|||
|
|
```java
|
|||
|
|
// TODO: Phase 09 创建Conversation
|
|||
|
|
```
|
|||
|
|
**问题**: `createMatch()` 方法创建Match后没有创建Conversation。虽然`MessagingService.createConversation()`存在,但没有被自动调用。这导致Match成功后用户无法立即开始聊天。
|
|||
|
|
**影响**: 核心业务流程断裂(匹配→聊天链路不通)
|
|||
|
|
**优先级**: P1
|
|||
|
|
|
|||
|
|
### M3: Admin Web缺少路由级权限控制
|
|||
|
|
**文件**: `admin-web/src/router/index.ts`
|
|||
|
|
**行号**: 29-35
|
|||
|
|
```typescript
|
|||
|
|
router.beforeEach((to) => {
|
|||
|
|
const authStore = useAuthStore()
|
|||
|
|
if (to.path !== '/login' && !authStore.isLoggedIn) {
|
|||
|
|
return { path: '/login', query: { redirect: to.fullPath } }
|
|||
|
|
}
|
|||
|
|
// ← 只有登录检查,没有权限检查!
|
|||
|
|
})
|
|||
|
|
```
|
|||
|
|
**问题**: 所有路由仅检查登录态,没有检查operator的permissions。任何登录用户可访问所有管理页面(用户管理、敏感数据查看、权限管理等),违反最小权限原则。
|
|||
|
|
**影响**: 权限边界可能被绕过
|
|||
|
|
**优先级**: P1
|
|||
|
|
|
|||
|
|
### M4: `AuditLog.saveAuditLog()` 中reason参数存在SQL注入风险
|
|||
|
|
**文件**: `backend/src/main/java/com/danyang/match/platform/account/service/AccountLifecycleService.java`
|
|||
|
|
**行号**: 196-197
|
|||
|
|
```java
|
|||
|
|
saveAuditLog(operatorId, "CLOSE_ACCOUNT", "user", userId, null,
|
|||
|
|
"{\"reason\": " + (reason != null ? "\"" + reason + "\"" : "null") + "}");
|
|||
|
|
```
|
|||
|
|
**问题**: `reason` 字符串直接拼接到JSON中,如果包含特殊字符(引号、反斜杠)会导致JSON格式破坏。虽然不直接是SQL注入(MyBatis-Plus使用参数化查询),但应使用Jackson序列化。
|
|||
|
|
**影响**: 审计日志数据损坏风险
|
|||
|
|
**修复**: 使用 `ObjectMapper.writeValueAsString(Map.of("reason", reason))`
|
|||
|
|
**优先级**: P2
|
|||
|
|
|
|||
|
|
### M5: 重复的import语句
|
|||
|
|
**文件**: `backend/src/main/java/com/danyang/match/platform/account/service/AccountLifecycleService.java`
|
|||
|
|
**行号**: 4-9
|
|||
|
|
```java
|
|||
|
|
import com.danyang.match.platform.audit.mapper.AuditLogMapper; // 第4行
|
|||
|
|
// ...
|
|||
|
|
import com.danyang.match.platform.audit.mapper.AuditLogMapper; // 第9行 — 重复
|
|||
|
|
```
|
|||
|
|
**问题**: AuditLogMapper被导入两次。
|
|||
|
|
**优先级**: P3
|
|||
|
|
|
|||
|
|
### M6: HealthController.health() 未检查数据库连接
|
|||
|
|
**文件**: `backend/src/main/java/com/danyang/match/platform/shared/controller/HealthController.java`
|
|||
|
|
**行号**: 31
|
|||
|
|
```java
|
|||
|
|
// TODO: 在实际业务中检查数据库、Redis 等依赖是否可用
|
|||
|
|
```
|
|||
|
|
**问题**: 健康检查端点返回固定的"healthy",没有实际检查数据库和Redis连接状态,运维监控失去意义。
|
|||
|
|
**优先级**: P2
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 四、一般问题 (Minor) — 可选修复
|
|||
|
|
|
|||
|
|
### G1: `ChatController` 图片上传/签名URL均为占位实现
|
|||
|
|
- 行72: `// TODO: Phase 10 实现图片上传凭证`
|
|||
|
|
- 行88: `// TODO: Phase 10 实现Signed URL`
|
|||
|
|
- 行112: `// TODO: Phase 10 实现图片消息发送`
|
|||
|
|
|
|||
|
|
### G2: `NotificationService.sendAsync()` 未实现异步推送
|
|||
|
|
- 行75: `// TODO: Phase 11 后续接入微信订阅消息推送`
|
|||
|
|
|
|||
|
|
### G3: `MessageRiskService.isRateLimited()` 返回硬编码false
|
|||
|
|
- 行84: `// TODO: Phase 10 后续接入 Redis 限流`
|
|||
|
|
- 消息无速率限制,恶意用户可以无限发送
|
|||
|
|
|
|||
|
|
### G4: 测试均为占位/常量检查
|
|||
|
|
- `CoreInvariantsTest.java`: 全部是常量值断言,无业务逻辑测试
|
|||
|
|
- `PermissionMatrixTest.java`: 只有内存矩阵断言,无API调用验证
|
|||
|
|
- `SecurityTests.java`: 大量 `assertTrue(true)` 占位测试
|
|||
|
|
- `RelationshipServiceTest.java`: 仅有常量测试
|
|||
|
|
|
|||
|
|
### G5: `RecommendationService` 和 `RecommendationEngineService` 重复
|
|||
|
|
- 两个服务都实现了推荐逻辑,职责不清晰
|
|||
|
|
- `RecommendationService` 引用了未注入的 `userProfileService`
|
|||
|
|
|
|||
|
|
### G6: Miniapp 使用JS而非TS
|
|||
|
|
- 全部45个pages使用原生JavaScript,未使用TypeScript类型检查
|
|||
|
|
- 与admin-web的TypeScript标准不一致
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 五、不变量验证状态
|
|||
|
|
|
|||
|
|
| 不变量 | 状态 | 说明 |
|
|||
|
|
|--------|------|------|
|
|||
|
|
| INV-001 Required不可自动放宽 | ⚠️ 部分 | 仅年龄检查,其他Required字段未实现 |
|
|||
|
|
| INV-002 未Mutual不可聊天 | ✅ 已实现 | MessagingService.sendMessage()有findActiveMatch校验 |
|
|||
|
|
| INV-003 Block优先级最高 | ❌ 未实现 | isBlocked()硬编码false |
|
|||
|
|
| INV-004 并发Like只创一个Match | ✅ 已实现 | findActiveMatch() + 异常处理 |
|
|||
|
|
| INV-005 活动名额不超卖 | ✅ 已实现 | 唯一约束 + 事务 |
|
|||
|
|
| INV-006 单向活动意向保密 | ✅ 已实现 | service层过滤 |
|
|||
|
|
| INV-007 红娘不能替用户Like | ✅ 已实现 | 用户JWT认证隔离 |
|
|||
|
|
| INV-008 非授权Operator不能读身份证 | ✅ 已实现 | 权限矩阵 + sensitive.view |
|
|||
|
|
| INV-009 非案件上下文不能读聊天 | ✅ 已实现 | Match校验 |
|
|||
|
|
| INV-010 跨Organization不能越权 | ⚠️ 待验证 | 需API级测试确认 |
|
|||
|
|
|
|||
|
|
**不变量通过率: 7/10 完整实现,1/10 部分实现,2/10 未实现**
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 六、测试覆盖分析
|
|||
|
|
|
|||
|
|
### 6.1 现有测试统计
|
|||
|
|
|
|||
|
|
| 测试类型 | 数量 | 实质覆盖率 |
|
|||
|
|
|----------|------|-----------|
|
|||
|
|
| Java单元测试 | 42个文件 | ~30%(多数为占位) |
|
|||
|
|
| Python集成测试 | 2个文件 | ~60%(有真实DB操作) |
|
|||
|
|
| 不变量测试(内存) | 2个文件 | ~40%(常量级验证) |
|
|||
|
|
| 端到端测试 | 1个文件 | ~10%(仅Spring Context验证) |
|
|||
|
|
| 并发测试 | 0个实际测试 | 0% |
|
|||
|
|
|
|||
|
|
### 6.2 缺失的关键测试
|
|||
|
|
|
|||
|
|
| 测试场景 | 优先级 | 建议方案 |
|
|||
|
|
|----------|--------|----------|
|
|||
|
|
| 双向Like并发→单一Match | P0 | `@SpringBootTest` + 线程模拟 |
|
|||
|
|
| Block后不可聊天 | P0 | 创建Match→Block→发消息验证403 |
|
|||
|
|
| 未Mutual不可聊天 | P0 | 创建Like(单向)→发消息验证403 |
|
|||
|
|
| 成功牵手双确认 | P0 | A发起→B拒绝→验证状态不变更 |
|
|||
|
|
| 活动超卖防护 | P1 | 并发10个线程报名1个名额 |
|
|||
|
|
| 跨组织数据隔离 | P1 | OrgA的operator查OrgB数据→403 |
|
|||
|
|
| Required身高过滤 | P1 | 设置Required身高→验证不在推荐中 |
|
|||
|
|
| Admin RBAC路由守卫 | P1 | 不同角色访问不同路由→权限检查 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 七、安全审查
|
|||
|
|
|
|||
|
|
### 7.1 已实现的安全措施 ✅
|
|||
|
|
- JWT Token双重密钥(access/refresh分离)
|
|||
|
|
- AES-256-GCM敏感数据加密(EncryptionUtil)
|
|||
|
|
- 18项权限码 + 9角色权限矩阵
|
|||
|
|
- 审计日志记录关键操作
|
|||
|
|
- 敏感访问日志表设计
|
|||
|
|
- 消息关键词风险检测
|
|||
|
|
- SQL注入防护(MyBatis-Plus参数化查询)
|
|||
|
|
- RequestId追踪(MDC)
|
|||
|
|
|
|||
|
|
### 7.2 安全问题 ⚠️
|
|||
|
|
| 问题 | 风险 | 建议 |
|
|||
|
|
|------|------|------|
|
|||
|
|
| admin-web无RBAC路由守卫 | 中 | 添加路由级permission检查 |
|
|||
|
|
| 图片上传URL硬编码 | 低 | 实现MinIO presigned URL |
|
|||
|
|
| 无CSRF防护(REST API) | 低 | 使用JWT时CSRF风险较低 |
|
|||
|
|
| XSS防护依赖前端 | 中 | 后端对description字段HTML转义 |
|
|||
|
|
| JWT密钥从环境变量读取但未验证默认值 | 低 | 添加启动时密钥长度检查 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 八、代码质量统计
|
|||
|
|
|
|||
|
|
### 8.1 TODO/FIXME统计
|
|||
|
|
```
|
|||
|
|
总TODO数: 61个
|
|||
|
|
- P0阻塞: 5个 (C2, C3, C5及相关)
|
|||
|
|
- P1重要: 15个
|
|||
|
|
- P2建议: 25个
|
|||
|
|
- P3低优: 16个
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 8.2 关键代码路径完整性
|
|||
|
|
|
|||
|
|
| 模块 | 完成率 | 主要TODO |
|
|||
|
|
|------|--------|---------|
|
|||
|
|
| 用户认证 | 95% | 短信验证码对接 |
|
|||
|
|
| 关系管理(Like/Pass/Block) | 85% | isBlocked()实现 |
|
|||
|
|
| 匹配推荐 | 60% | Required全字段、评分逻辑 |
|
|||
|
|
| 聊天消息 | 70% | WebSocket、图片上传 |
|
|||
|
|
| 成功牵手 | 50% | 双确认逻辑、状态更新 |
|
|||
|
|
| 账号生命周期 | 55% | 注销联动、隐私设置 |
|
|||
|
|
| 活动管理 | 80% | 基础功能完成 |
|
|||
|
|
| 红娘服务 | 70% | MatchEngine集成 |
|
|||
|
|
| 权限系统 | 90% | admin-web路由守卫 |
|
|||
|
|
| 数据加密 | 95% | 身份证脱敏待完善 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 九、端到端流程可行性分析
|
|||
|
|
|
|||
|
|
### 完整业务流程链验证
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
注册 → 实名 → 填资料 → 审核 → 推荐 → Like → Match → 聊天 → 成功牵手
|
|||
|
|
│ │ │ │ │ │ │ │ └── ❌ 双确认未实现
|
|||
|
|
│ │ │ │ │ │ │ └── ⚠️ Conversation未自动创建
|
|||
|
|
│ │ │ │ │ │ └── ✅ 双向Like→Match正确
|
|||
|
|
│ │ │ │ │ └── ⚠️ Block未完全生效
|
|||
|
|
│ │ │ │ └── ⚠️ Required过滤不完整
|
|||
|
|
│ │ │ └── ✅ 审核流程骨架
|
|||
|
|
│ │ └── ✅ 资料填写流程
|
|||
|
|
│ └── ✅ 实名认证流程
|
|||
|
|
└── ✅ 微信登录注册
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**结论**: 核心流程骨架完整,但3处关键断裂点需修复后方可上线。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 十、压力测试评估
|
|||
|
|
|
|||
|
|
### 10.1 当前性能设计
|
|||
|
|
- 连接池: HikariCP max=20, min-idle=5
|
|||
|
|
- 推荐缓存: Redis TTL 1小时
|
|||
|
|
- 限流: 未实现(MessageRiskService硬编码false)
|
|||
|
|
- WebSocket: 骨架实现
|
|||
|
|
|
|||
|
|
### 10.2 预估承压能力
|
|||
|
|
| 场景 | 预估QPS | 瓶颈 |
|
|||
|
|
|------|---------|------|
|
|||
|
|
| 用户登录 | 200/s | JWT签名验证 |
|
|||
|
|
| 推荐列表 | 50/s | 数据库查询+评分计算 |
|
|||
|
|
| Like/Pass | 500/s | 单行INSERT+唯一约束 |
|
|||
|
|
| 聊天消息 | 100/s | 消息写入+未读数更新 |
|
|||
|
|
| 管理员API | 50/s | 数据库查询 |
|
|||
|
|
|
|||
|
|
### 10.3 建议压力测试方案
|
|||
|
|
```bash
|
|||
|
|
# 使用 k6 或 locust 进行
|
|||
|
|
# 1. 登录接口: 200并发×60秒
|
|||
|
|
# 2. 推荐接口: 50并发×120秒
|
|||
|
|
# 3. Like接口: 500并发×30秒(验证唯一约束)
|
|||
|
|
# 4. 消息发送: 100并发×60秒
|
|||
|
|
# 5. 并发Like验证: 10并发同时Like同一用户
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 十一、修复建议优先级
|
|||
|
|
|
|||
|
|
### 🔴 P0 — 阻塞上线(必须修复)
|
|||
|
|
1. **C2**: 修复 `MessagingService.isBlocked()` — 实现真实Block检查
|
|||
|
|
2. **C3**: 修复 `RelationshipStatusService.confirmSuccess()` — 实现双确认逻辑
|
|||
|
|
3. **C5**: 修复 `AccountLifecycleService.checkCanWithdraw()` — 修正空查询条件
|
|||
|
|
4. **M2**: 修复 `RelationshipService.createMatch()` — 自动创建Conversation
|
|||
|
|
|
|||
|
|
### 🟠 P1 — 上线前建议修复
|
|||
|
|
5. **M1**: 补全RecommendationEngine双向Required过滤(身高/地区/婚姻状况)
|
|||
|
|
6. **M3**: Admin Web添加路由级权限守卫
|
|||
|
|
7. **G3**: 实现消息速率限制
|
|||
|
|
8. **测试**: 补充INV-002/003/005的集成测试
|
|||
|
|
|
|||
|
|
### 🟡 P2 — 后续迭代
|
|||
|
|
9. **C4**: 修复RecommendationService字段声明顺序
|
|||
|
|
10. **G1**: 实现图片上传Signed URL
|
|||
|
|
11. **G2**: 实现WebSocket推送
|
|||
|
|
12. **G6**: HealthController接入实际依赖检查
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 十二、总结
|
|||
|
|
|
|||
|
|
**项目整体状态**: V1.0 RC可用,但有3处P0阻塞性问题需要修复。
|
|||
|
|
|
|||
|
|
**核心优势**:
|
|||
|
|
- 架构设计优秀,模块化清晰
|
|||
|
|
- 10条核心不变量大部分有实现
|
|||
|
|
- 权限矩阵设计完善(9角色×18权限)
|
|||
|
|
- 数据安全设计到位(AES-GCM加密+审计日志)
|
|||
|
|
- 前端stores编排设计优雅
|
|||
|
|
|
|||
|
|
**主要风险**:
|
|||
|
|
- Block功能未完全实现(C2)
|
|||
|
|
- 成功牵手双确认未实现(C3)
|
|||
|
|
- 推荐引擎Required过滤不完整(M1)
|
|||
|
|
- 测试覆盖薄弱,多数为占位
|
|||
|
|
- Admin Web缺少路由级权限控制(M3)
|
|||
|
|
|
|||
|
|
**建议**: 修复4个P0问题后即可进入UAT阶段。P1问题建议在上線前完成。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
*报告生成时间: 2026-09-01 | 审查者: Agnes AI Code Reviewer*
|