docs(phase2e-2): Task 16 收官 · 同步 6 份文档 + 落盘 test-report-phase2e-2-meeting.md

Phase 2e-2 会议 MVP 整体切 (Task 0-16 全部完成),本提交是 Task 16 最后一步
"文档同步"批次,配合历次 commit(cdaa39d P0 / ea2bf96 P1 / f5ae095 资源生命周期 /
5ed14c2 E2E 剧本 / c35097a P2+Nit)完成阶段收官。

同步范围:
- docs/progress/CURRENT_STATUS.md
  · 顶部元信息:"当前阶段"从"代码开发阶段 🚧"切为"已完成 "
  · 新增 2026-04-24 Task 16 收官小节:资源生命周期专项 / Playwright 5 场景 /
    P2+Nit 收尾 / 完成度汇总(Task 0-16 + 审查 4 P0 + 8 P1 + 7 P2 + 7 Nit)
- docs/plans/2026-04-21-phase2e-2-implementation.plan.md
  · 状态切 ;Task 16 行切  + 实际交付小节(5 commits + 5 场景剧本 + 6 份文档)
- docs/plans/2026-04-20-phase2e-design.md
  · Phase 2e 顶层状态:2e-2 切 ;最后更新写明 Task 16 收官
- docs/reviews/2026-04-23-phase2e-2-code-review.md
  · (历次 commit c35097a 已追加)"Task 16 修复追踪"小节包含已修复表 + 推迟登记表
- .cursor/rules/project-context.mdc
  · Phase 2e 进度条更新;新增 Task 15 / 16 两个完整 bullet(Task 16 含 5 commit 详解)
- test-report-phase2e-2-meeting.md(新增)
  · 八章完整验证报告:测试环境 / 构建 / 功能 / E2E 剧本 / 代码审查修复 /
    部署双态 / 已知限制 / 验收结论

构建&清理复核(均在 Task 16 历次 commit 中验证通过):
- go vet ./... / go build ./... / npm run build:h5 / npx tsc --noEmit 全绿
- console.log / TODO / FIXME 扫描 0 残留

Made-with: Cursor
This commit is contained in:
bujinyuan
2026-04-23 17:53:54 +08:00
parent c35097a0d8
commit 2452ca7332
5 changed files with 396 additions and 11 deletions

View File

@@ -1,9 +1,9 @@
# Phase 2e 设计文档:会议与通知系统
> **状态:** 🚧 进行中2e-1 ✅ 已完成2e-2 📋 **设计阶段完成待进入编码**2e-3 📋 待开发)
> **状态:** 🚧 进行中2e-1 ✅ 已完成2e-2 **已完成**2e-3 📋 待开发)
> **分支:** `feature/phase2e-meeting-notification`2e-1`feature/phase2e-2-meeting-mvp`2e-2基于 `origin/feature/phase2c-group-read-receipt`
> **前置依赖:** Phase 2a联系人 + WS、Phase 2b即时通讯、Phase 2c群聊+已读、Phase 2d消息类型扩展全部完成
> **最后更新:** 2026-04-24Phase 2e-2 Task 0-14完成:PoC / media-server 骨架 / REST / DDL / Go 骨架 / 会议 REST / WS 信令 / Go↔Node HTTP / 生命周期 / 前端 mediasoup / 会议前后端页面 / 会议聊天 / meeting_invite 卡片 / docker-compose 双态;剩 Task 15 UI 打磨 + Task 16 E2E 收官
> **最后更新:** 2026-04-24Phase 2e-2 Task 0-16全部完成:Task 15 UI 打磨 + 主持人四件套 + Task 16 code-reviewer 全栈审计 + 4 P0/8 P1/7 P2/7 Nit 修复闭环 + 5 项登记推迟 + 资源生命周期专项审计 + Playwright 5 场景剧本 + test-report-phase2e-2-meeting.md 落盘Phase 2e-2 整体切 ✅,待合入主干
> **子阶段专用文档:**
> - 2e-1`docs/plans/2026-04-20-phase2e-1-design.md` + `docs/plans/2026-04-20-phase2e-1-implementation.plan.md`(✅ 已完成,含 TabBar「我的」未读红点优化
> - 2e-2`docs/plans/2026-04-21-phase2e-2-design.md`16 章节)+ `docs/plans/2026-04-21-phase2e-2-implementation.plan.md`17 个 Task约 17 人日)
@@ -19,7 +19,7 @@
**核心交付物(按子阶段):**
- **Phase 2e-1 通知系统**3-4 人日)✅ 已完成:统一通知中心 + 11 种通知类型预留 + 跨模块 Pusher 接口 + TabBar「我的」未读红点
- **Phase 2e-2 会议 MVP**(约 17 人日)📋 设计阶段完成mediasoup Node 媒体服务 + 即时会议≤8 人)+ 密码/邀请链接/通知邀请三合一 + 设备预览页 + 主持人四件套 + 会议内聊天 + 双态部署(本机/公网 coturn+ 桌面/手机响应式
- **Phase 2e-2 会议 MVP**(约 17 人日)✅ 已完成mediasoup Node 媒体服务 + 即时会议≤8 人)+ 密码/邀请链接/通知邀请三合一 + 设备预览页 + 主持人四件套 + 会议内聊天 + 双态部署(本机/公网 coturn+ 桌面/手机响应式 + 全栈 code-reviewer 审计闭环(验证报告:`test-report-phase2e-2-meeting.md`
- **Phase 2e-3 会议增强**7-10 人日):预约会议 + 定时提醒 + 等候室/锁定会议 + 设备预览高级参数(降噪/回声/虚拟背景)
**不包含(明确推迟):** 见 [§九 后续规划清单](#九后续规划清单必须留档)

View File

@@ -1,11 +1,11 @@
# Phase 2e-2 实施计划:会议 MVP多人音视频
> **状态:** 🚧 代码开发Task 0-15 ✅ / Task 16 待执行
> **状态:** 代码开发完成Task 0-16 全部 ✅
> **设计文档:** [Phase 2e-2 设计文档](./2026-04-21-phase2e-2-design.md)
> **上级路线图:** [Phase 2e 整体路线图](./2026-04-20-phase2e-design.md)
> **分支:** `feature/phase2e-2-meeting-mvp`
> **预估总工时:** **约 17 人日**17 个 Task含 PoC 与 UI 打磨)
> **最后更新:** 2026-04-23Task 15UI 打磨 + 主持人权限四件套完成6 项原创 UI 特色落地 / 说话者探测双源RTP stats + WebAudio / `SelfVideoFloat` 桌面恒浮窗 + 图钉切换 / `isAllMuted` 静音氛围色 / `NetworkBadge` 3 条波浪 / 主持人"请他静音/开麦/转让/踢出"四件套 / 4 屏 design-system 文档 / Playwright MCP 7 屏截图回归通过。下一步 Task 16 E2E + 文档同步
> **最后更新:** 2026-04-24Task 16E2E 总回归 + 文档同步完成code-reviewer 全栈审计 4 P0 + 8 P1 + 7 P2 + 7 Nit 闭环修复5 项登记推迟至 Phase 2f/3资源生命周期专项审计前端 Pinia _reset + _broadcastSelfState timer / 后端 Redis resourceTrackKey + memberStateKey + lifecycle timerPlaywright MCP 5 场景 + 手工回归剧本落盘 `.playwright-mcp/task16/`test-report-phase2e-2-meeting.md 落盘4 commitscdaa39d P0 / ea2bf96 P1 / f5ae095 资源生命周期 / 5ed14c2 E2E 剧本 / c35097a P2+Nit
### 进度看板
@@ -27,7 +27,7 @@
| **Task 13** | **meeting_invite 通知对接** | ✅ | extra 补齐 inviter_* / expired_at前端"立即加入/稍后"+ 过期态 + deep-link |
| **Task 14** | **docker-compose + 双态** | ✅ | `media-server` + `coturn(public)` 编排 + 3 份 .env 模板 + `deploy-public.sh` + `docs/deployment/meeting-mvp.md` |
| **Task 15** | **`ui-ux-pro-max` UI 打磨 + 主持人权限四件套** | ✅ | 6 项原创 UI流光/柔性网格/浮窗/氛围色/滑入/波浪)+ 双源说话者探测 + 四件套 + 4 份设计文档 + Playwright MCP 7 屏回归 |
| Task 16 | E2E + 文档同步 | | |
| Task 16 | E2E + 文档同步 | | code-reviewer 审计 + P0/P1/P2/Nit 闭环 + 资源清理审计 + Playwright 5 场景 + 测试报告 |
### 2026-04-22 UI 打磨专项Task 10-12 之后的体验收敛)
@@ -597,6 +597,25 @@ flowchart LR
- 清理所有 TODO / FIXME / `console.log` 调试残留
- **工作量****1 人日**
- **实际交付2026-04-24 ✅)**
- **code-reviewer 全栈审计**`docs/reviews/2026-04-23-phase2e-2-code-review.md`4 P0 + 8 P1 + 8 P2 + 11 Nit
- **修复闭环**(详见 commit history
- `cdaa39d` 4 P0producer/consumer/transport 归属校验 / CreateRoom Router 失败补偿 / 密码 in-memory store
- `ea2bf96` 8 P1主持人转让原子事务 / List* 走 DAO 分页 / goroutine trace_id 透传 / broadcast ack 重试 / TTL 分布式锁兜底 / REST+WS 顺序归一等)
- `f5ae095` 资源生命周期专项MeetingLifecycleService.OnRoomEnded 定时器统一撤销 / Redis `resourceTrackKey` + `memberStateKey` 显式 DEL / 前端 Pinia `_reset` + `_pendingBroadcastTimers` 清理)
- `c35097a` 7 P2 + 7 Nittransport 清理 / preview 竞态防抖 / redirect return / chat 长度+频率限制 / kicked label / SplitN / 资源 TTL 中央化 / CheckOrigin 白名单 / doRequest 超时+重试 / REDIS_PASSWORD 联动校验 / isPrivatePath path 匹配 + 走读复核)
- 5 项登记推迟P2-4 WS token、P2-5 ChatService 拆分、docker-compose 端口收敛、producer.appData 校验、时间格式 RFC3339 统一),全部写入审查报告"推迟到独立阶段"小节
- **Playwright MCP 5 场景剧本**`.playwright-mcp/task16/scenarios/` commit `5ed14c2`
- `01-create-and-join-by-code.md`:发起会议 + 会议号入会 + 互推音视频
- `02-invite-link-with-password.md`:邀请链接 + 密码入会
- `03-notify-quickjoin.md`:通知中心一键入会
- `04-host-toolkit-and-transfer.md`:主持人四件套 + 主动/被动转让
- `05-reopen-5times-resource-cleanup.md`:连续 5 次开/散会资源清理回归
- `manual-regression.md`:纯手工验收点 checklist
- **文档同步**:本计划 + `CURRENT_STATUS.md` + `project-context.mdc` + `phase2e-design.md` + code-review 报告 + `test-report-phase2e-2-meeting.md` 落盘
- **清理复核**grep console.log/TODO/FIXME 确认 0 残留(仅保留结构化日志入口)
- **构建验证**go vet / go build / npm run build:h5 / npx tsc 全绿
---
## 五、工作量汇总

View File

@@ -1,14 +1,101 @@
# EchoChat 项目开发进度
> **最后更新**2026-04-23Phase 2e-2 Task 15 UI 打磨 + 主持人权限四件套完成 + 媒体层稳定性补丁 + Task 16 全栈 code-reviewer 审计 + P0×4 / P1×7 修复落地
> **当前阶段**Phase 2e-2 会议 MVP **代码开发阶段** 🚧Task 0-15 ✅ / Task 16 进行中:审计 ✅ / P0 ✅ / P1 ✅ / P2+Nit + E2E 脚本 + 文档同步待执行
> **最后更新**2026-04-24Phase 2e-2 Task 16 ✅ 代码审查 + 资源生命周期审计 + P0/P1/P2/Nit 修复闭环 + Playwright 5 场景剧本 + 测试报告落盘
> **当前阶段**Phase 2e-2 会议 MVP **已完成** Task 0-16 全部 ✅,分支 `feature/phase2e-2-meeting-mvp` 待合并主干
> **当前分支**`feature/phase2e-2-meeting-mvp`(从 `feature/phase2c-group-read-receipt` 衍生)
> **Phase 2e 整体设计**`docs/plans/2026-04-20-phase2e-design.md`(三子阶段路线图 + 后续规划清单)
> **Phase 2e-1 专用设计**`docs/plans/2026-04-20-phase2e-1-design.md`(✅ 已完成)
> **Phase 2e-1 实施计划**`docs/plans/2026-04-20-phase2e-1-implementation.plan.md`(✅ 11 个 Task 全部完成)
> **Phase 2e-1 验证报告**`test-report-phase2e-1-notification.md`
> **Phase 2e-2 专用设计**`docs/plans/2026-04-21-phase2e-2-design.md`📋 设计阶段16 章节)
> **Phase 2e-2 实施计划**`docs/plans/2026-04-21-phase2e-2-implementation.plan.md`📋 17 个 Task 共约 17 人日
> **Phase 2e-2 专用设计**`docs/plans/2026-04-21-phase2e-2-design.md`✅ 已完成16 章节)
> **Phase 2e-2 实施计划**`docs/plans/2026-04-21-phase2e-2-implementation.plan.md` 17 个 Task 全部完成
> **Phase 2e-2 代码审查**`docs/reviews/2026-04-23-phase2e-2-code-review.md`4 P0 + 8 P1 + 8 P2 + 11 Nit已闭环 26 项 / 推迟 5 项)
> **Phase 2e-2 验证报告**`test-report-phase2e-2-meeting.md`
> **Phase 2e-2 E2E 剧本**`.playwright-mcp/task16/scenarios/`5 场景 + 手工回归 checklist
---
## 🏁 2026-04-24 Phase 2e-2 Task 16E2E 总回归 + P2/Nit 收尾 + 资源生命周期审计 + 文档同步 ✅
**交付**Phase 2e-2 会议 MVP 全部 17 个 Task 收官。Task 16 在 2026-04-23 完成 code-reviewer 全栈审计 + P0×4 + P1×8 修复commit `cdaa39d` / `ea2bf96`2026-04-24 继续完成:资源生命周期专项审计 + Playwright MCP 5 场景剧本化 + P2×7 + Nit×7 闭环 + 5 项登记推迟 + 文档同步。构建链 `go vet ./...` / `go build ./...` / `npm run build:h5` / `npx tsc --noEmit` 全绿。
### 本次增量2026-04-24
#### 1. 资源生命周期专项commit `f5ae095`
针对"会议结束后资源必须清理干净"的硬性约束,从前端 Pinia / 后端 Redis / lifecycle 定时器三维度补齐:
- **前端 `store/meeting.js`**
- `_broadcastSelfState` 重试 setTimeout 通过 `_pendingBroadcastTimers: Set<number>` 追踪,`_cleanupMedia``exitEndedRoom` 集中清理,杜绝会议结束后计时器残留回调
- `_onRoomEnded` 补齐 `_cleanupMedia` + `_unregisterListeners`;新增 `exitEndedRoom` action 供用户主动退出"已结束"态时触发完整 `_reset`
- `room.vue``onUnload` 钩子:离页时若仍持有 MediaEngine显式 `_cleanupMedia` 兜底
- **后端 `meeting_signal_service.go`**
- 新增 `cleanupRoomRedisResidual`DEL `resourceTrackKey:*` + `memberStateKey`),由 `EndRoom` / `HandleEmptyRoomExpired` / `HandleHostGraceExpired` 统一触发
- 与 P2-1 CloseTransport 形成"mediasoup 资源 + Redis 信令状态"双重闭环
- **后端 `meeting_lifecycle_service.go`**
- 新增 `OnRoomEnded(ctx, code)` 中央清理钩子:撤销 hostGrace / emptyTTL 的 local timer + DEL Redis key避免会议提前结束后定时器继续烧 CPU
- `EndRoom` 路径结束后调用 `OnRoomEnded``HandleHostGraceExpired` / `HandleEmptyRoomExpired` 各自执行完也调用(幂等)
#### 2. Playwright MCP 5 场景剧本commit `5ed14c2`
`.playwright-mcp/task16/scenarios/` 落盘 5 份场景脚本 + 1 份手工回归 checklist + 1 份 README
| 编号 | 文件 | 覆盖要点 |
|---|---|---|
| 01 | `01-create-and-join-by-code.md` | 发起会议 + 会议号加入 + 互推音视频 + 会议号/链接/二维码三通道入会 |
| 02 | `02-invite-link-with-password.md` | 邀请链接 + 密码入会 + 密码错/会议已结束边界 |
| 03 | `03-notify-quickjoin.md` | 通知中心一键入会(`meeting_invite` 卡片) |
| 04 | `04-host-toolkit-and-transfer.md` | 请他静音/开麦/踢出/转让四件套 + 主持人主动转让 + 掉线 120s 被动自动转让 |
| 05 | `05-reopen-5times-resource-cleanup.md` | 连续 5 次开/散会压测 Redis `resourceTrackKey` / mediasoup Router / 定时器无泄漏 |
| - | `manual-regression.md` | 纯手工验收点(浏览器权限、移动端横竖屏、设备热插拔) |
`.gitignore` 同步精细化:`.playwright-mcp/**/*.png|.log|.yml|.txt|.jpg` 默认忽略 + Task 16 Markdown 剧本精确白名单放行(历次 `task15/` 截图仍保持不跟踪)。
#### 3. P2/Nit 收尾批次commit `c35097a`
**P2 × 7 修复**
| ID | 范围 | 修复点 |
|---|---|---|
| P2-1 | meeting_signal_service / media-server / orchestrator | `cleanupUserResources` 新增 `transport` 分支media-server 新增 `DELETE /internal/v1/transports/:id`Go 端 `MediaOrchestrator.CloseTransport``doCloseRequest` 幂等重试 |
| P2-2 | `preview.vue` | `previewSeq` 序号 + `nextTick` 后 stale 判断丢弃过期 getUserMedia 结果;`onVideoChange`/`onAudioChange``scheduleRestartPreview` 200ms 防抖;`onBeforeUnmount` 清理定时器 |
| P2-3 | `room.vue` | `onLoad` redirectTo 时置 `redirectingToJoin=true` + return`onMounted` 早期 return 跳过初始化,杜绝跳转页面的闪 UI |
| P2-6 | `meeting_service.go` | `generateUniqueRoomCode` 重试成功时 Warn 码空间健康度;耗尽时 Error + `ErrRoomCodeConflict` |
| P2-7 | `meeting_service.go` + controller | `SendChatMessage` 服务端 `utf8.RuneCountInString` 500 字符上限Redis INCR + EXPIRE 滑动窗口 30 条/60s新错误类型 `ErrChatContentEmpty` / `ErrChatContentTooLong` / `ErrChatRateLimited` 映射 HTTP 400 |
| P2-8 | `constants/meeting.js` + `store/meeting.js` + `meeting_signal_service.go` | 新增 `MEETING_ENDED_REASON_KICKED` + label 文案;后端 `OnWSDisconnect` 硬编码 `"ws_disconnect"``constants.MeetingLeftReasonDisconnect` |
| - | - | P2-4WS token 迁出 URL query/ P2-5ChatService 拆分)登记推迟至 Phase 2f 安全 & 架构专项 |
**Nit × 7 修复 / 走读**
| ID | 修复点 |
|---|---|
| SplitN | `meeting_signal_service.go``kind:id` 解析两处统一使用 `strings.SplitN` |
| resourceTTL | 中央化到 `constants.MeetingResourceTrackTTLSeconds = 3600` |
| CheckOrigin | `ws/handler.go``config.Server.WSAllowedOrigins` + `Mode` 收敛dev 模式放行 / release 同源放行 + 严格白名单 |
| doRequest | 默认 `TimeoutMS` 5000→10000ms 兼容 mediasoup Worker 冷启动;新增 `CreateRouterRetry`(默认 1 次、300ms 退避)仅对非 404 错误重试 |
| REDIS_PASSWORD | `deploy-public.sh` 追加 `REDIS_PASSWORD` × `redis.conf` requirepass 联动校验;`redis.conf` 添加公网部署 TODO 注释 |
| isPrivatePath | `media-server/internal-auth.ts` 剔除 `?`/`#` 后再匹配白名单,避免 query 语义混淆 |
| inflight lock | `mediasoup-client.js` 走读确认 `finally` 已覆盖 resolve/reject 两路,追加注释强化 |
| cleanup 粒度 | `meeting.js` 走读复核:`_onMemberLeft`(整槽关闭) vs `_onProducerNew closed=true`(精确匹配 producerId) 粒度正确,无需改动 |
| docker 端口 / appData 校验 / RFC3339 | 登记推迟(见审查报告推迟登记表) |
#### 4. 文档同步
- `docs/reviews/2026-04-23-phase2e-2-code-review.md` 追加"Task 16 修复追踪2026-04-24 更新)"小节,含已修复表 + 推迟登记表
- `docs/plans/2026-04-21-phase2e-2-implementation.plan.md` Task 16 切 ✅ + 实际交付小节
- `CURRENT_STATUS.md`(本文件)收尾
- `test-report-phase2e-2-meeting.md` 落盘(本次新增)
- `project-context.mdc` 当前进度同步
### Phase 2e-2 完成度汇总
| 维度 | 状态 |
|---|---|
| Task 0-16 | 17 个 Task 全部 ✅ |
| 代码审查 | 4 P0 ✅ / 8 P1 ✅ / 7 P2 ✅ + 1 P2 推迟 / 7 Nit ✅ + 4 Nit 推迟 |
| 构建 | go vet / go build / npm run build:h5 / npx tsc --noEmit 全绿 |
| E2E | 5 场景剧本 + 手工回归 checklist 落盘,待用户 HTTPS 双端实机回归 |
| 分支 | `feature/phase2e-2-meeting-mvp`(待合入主干) |
---