Files
danyang-match/docs/Phase-16-V11-Completion-Report.md
T

79 lines
2.6 KiB
Markdown
Raw Normal View History

2026-09-09 22:05:00 +08:00
# Phase 16 完成报告:活动互选二阶段同意重构
> 版本基线:v1.0.0-RC.2 → v1.1.0-dev | 日期:2026-09-08
> 对应 EPIC:EPIC-P16-V11
---
## 完成摘要
| 项目 | 内容 |
|------|------|
| Phase | 16 |
| 模块 | 活动互选二阶段同意重构 |
| 状态 | ✅ 核心链路已完成(V1.1 MVP) |
| 不变量 | INV-014/INV-015 强制执行 |
---
## 核心变更
### 数据模型(V024)
**新建 `activity_mutual_connection_consents` 表:**
- 每对用户在同一个活动中有一条独立记录
- 分别追踪 `user_a_status` 和 `user_b_status`(pending/accepted/declined)
- 双方都 accepted 时设置 `both_confirmed_at`
- UNIQUE 约束使用 `LEAST/GREATEST` 保证 (A,B) 和 (B,A) 是同一对
### 不变量强制实现
| 不变量 | 实现方式 |
|--------|----------|
| INV-014: Activity Mutual 不能直接创建 Match | `confirmConnection()` 只更新 consent 状态,不自动创建 Match |
| INV-015: 双方确认后才创建 Activity Match | `confirmActivityInterest()` 在 RelationshipService 中调用,仅在 bothConfirmed 时触发 |
| INV-010: 复用已有 active Match | `hasActiveMatch()` 检查优先于新建 |
| INV-010: prior Unmatch 新建 episode | `findLatestMatch()` 检查是否曾 unmatch |
### API 端点
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/activities/{id}/mutual/results` | 检测双向互选结果 |
| POST | `/activities/{id}/mutual/consent` | 创建互选同意记录 |
| POST | `/activities/{id}/mutual/confirm` | 用户确认开启沟通 |
| POST | `/activities/{id}/mutual/decline` | 用户拒绝 |
| GET | `/activities/{id}/mutual/status/{partnerId}` | 查询个人同意状态 |
| GET | `/mutual/my-results` | 获取我的互选结果列表 |
### Miniapp 页面
| 页面 | 编号 | 功能 |
|------|------|------|
| activity-mutual-result | U60 | 展示所有互选结果,已确认可开聊 |
| activity-mutual-waiting | U61 | 单对互选详情页,支持确认/拒绝/等待状态 |
---
## 前端状态流转
```
[未表达] → [双方互选产生] → [等待确认] → [用户A确认] → [用户B确认] → [Match创建,可聊天]
↓ ↓
[用户A拒绝] [用户B拒绝] → [单向关闭]
```
---
## 待补充
| 任务 | 阶段 | 说明 |
|------|------|------|
| T13 timeout handling | 后续 | 互选超时自动过期逻辑 |
| Admin Web 互选管理 | Phase 19 | 运营后台查看互选统计 |
| E2E 测试补全 | Phase 23 | 完整两阶段流程测试 |
---
*Phase 16 核心链路完成。下一阶段:Phase 17(举报与风控扩展)*