Files
sino-mci/docs/superpowers/plans/2026-07-15-send-routing-e2e-verification-plan.md

334 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 发送路由端到端验证实施计划
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 通过 admin-web UI 走通「内部群 → WECOM_BOT → 发送 → 查询状态」链路,验证自动路由可用,并修复沿途问题。
**Architecture:** 基于现有后台能力(已有异步发送、任务状态查询、会话管理和账号管理 API通过 Chrome DevTools MCP 操作浏览器完成端到端验证;发现问题时现场修复前后端代码并重新验证。
**Tech Stack:** Spring Boot 4.1.0 (backend), Vue 3 + Element Plus (admin-web), RabbitMQ (async send), MySQL, Chrome DevTools MCP.
## Global Constraints
- 项目工作目录:`/f/sino-mci`
- JDK 21 路径:`/f/tools/jdk-21.0.4+7`
- 后端构建命令:`cd /f/sino-mci/backend && mvn clean install -DskipTests`
- 后端单元测试:`cd /f/sino-mci/backend && mvn test -pl mci-server,mci-channel-wecom`
- admin-web 运行命令:`cd /f/sino-mci/admin-web && npm run dev`
- 登录账号:`superadmin` / `admin123`
- 当前代码分支:`main`,远端为 `origin/main`
- 不要删除或覆盖工作区中未提交的无关文件
---
## 文件结构
本次验证主要读取/操作以下文件:
- `admin-web/src/views/ChannelAccount.vue` — 创建 WECOM_BOT 账号
- `admin-web/src/views/Conversation.vue` — 创建内部群、绑定账号
- `admin-web/src/views/MessageTest.vue` — 发送测试消息
- `admin-web/src/views/SendRecord.vue` — 查询发送记录
- `backend/mci-server/src/main/java/com/sino/mci/send/service/SendService.java` — 发送路由与状态
- `backend/mci-server/src/main/java/com/sino/mci/channel/service/ConversationService.java` — 会话绑定校验
- `backend/mci-server/src/main/java/com/sino/mci/channel/service/AccountSelector.java` — 账号选择
- `logs/mci-server.log` — 后端错误排查
- `admin-web/screenshots/` — 保存验证截图
---
### Task 1: 环境检查
**Files:**
- Read: `logs/admin-web.log`, `logs/mci-server.log`, `logs/channel-service.log`
- Use: Chrome DevTools MCP
**Interfaces:**
- Consumes: 后台服务进程状态
- Produces: 环境就绪确认
- [ ] **Step 1: 检查后台服务是否运行**
Run: `cd /f/sino-mci && docker compose -p sino-mci --profile infra ps` (Windows 环境可能无 Docker CLI此时通过后端日志/网络连接确认基础设施可达)
Expected: MySQL / Redis / RabbitMQ 容器正常(或本地已启动等价服务/远程可达)。
Run: `ps aux | grep -E "mci-server|admin-web|channel-service" | grep -v grep`
Expected: 三个服务进程都在运行。
- [ ] **Step 2: 检查 admin-web 可访问**
Use Chrome DevTools MCP navigate to `http://localhost:5177/login`.
Expected: 页面加载到登录页,无 404/502。注意开发环境下 `/msg-platform` 会被 Vite proxy 转发到后端。
- [ ] **Step 3: 若服务未启动则启动**
Run: `cd /f/sino-mci && ./scripts/run-local.sh backend` (若未运行)
Run: `cd /f/sino-mci && ./scripts/run-local.sh frontend` (若未运行)
Run: `cd /f/sino-mci && ./scripts/run-local.sh channel` (若未运行)
- [ ] **Step 4: 提交状态**
If all services are healthy, mark Task 1 complete. No code commit needed.
---
### Task 2: 登录并创建 WECOM_BOT 账号
**Files:**
- Modify if needed: `admin-web/src/views/ChannelAccount.vue`
- Test via UI: `http://localhost:5177/channel/account`
**Interfaces:**
- Consumes: `POST /api/v1/channel-account`
- Produces: 一个 accountType=6 的 WECOM_BOT 账号记录
- [ ] **Step 1: 登录 admin-web**
Use Chrome DevTools MCP:
- Navigate to `http://localhost:5177/msg-platform/login`
- Fill username `superadmin`, password `admin123`
- Click login
- Expected: 跳转至首页。
- [ ] **Step 2: 进入渠道账号页面**
Navigate to `http://localhost:5177/msg-platform/channel-account`.
Take screenshot: `admin-web/screenshots/01-channel-account-list.png`
- [ ] **Step 3: 打开创建账号弹窗**
Click "新增账号".
Expected: 弹窗显示表单,账号类型下拉包含「企微群机器人」。
- [ ] **Step 4: 填写 WECOM_BOT 账号信息**
Select:
- 账号类型:企微群机器人
- 渠道:`wecom`
- 账号 ID填写企业微信群机器人 key如真实 key 或 `test-bot-001`
- 名称:`测试内部群机器人`
- Webhook URL若使用占位 key填写一个可访问的 mock URL`https://httpbin.org/post` 或本地 mock 服务)
- [ ] **Step 5: 提交并确认**
Click "保存".
Expected: 弹窗关闭,列表出现新账号,类型显示为「企微群机器人」。
Take screenshot: `admin-web/screenshots/02-bot-created.png`
- [ ] **Step 6: 数据库确认(可选)**
Run: `docker exec -it mci-mysql mysql -uroot -proot sino_mci -e "SELECT id, account_name, account_type, channel_type FROM mci_channel_account WHERE account_type=6;"`
Expected: 看到新创建的 WECOM_BOT 记录。
- [ ] **Step 7: 提交修复(如有 UI 问题)**
If any bug found, fix in `admin-web/src/views/ChannelAccount.vue` and commit.
---
### Task 3: 手动创建内部群
**Files:**
- Modify if needed: `admin-web/src/views/Conversation.vue`
- Test via UI: `http://localhost:5177/customer/group`
**Interfaces:**
- Consumes: `POST /api/v1/conversation`
- Produces: conversationType=2, conversationScene=1 的会话记录
- [ ] **Step 1: 进入会话管理页面**
Navigate to `http://localhost:5177/msg-platform/conversation`.
Take screenshot: `admin-web/screenshots/03-conversation-list.png`
- [ ] **Step 2: 打开新增会话弹窗**
Click "新增会话".
Expected: 弹窗包含「会话类型」「渠道」「场景」「渠道会话ID」「名称」「负责人」。
- [ ] **Step 3: 填写内部群信息**
Select:
- 会话类型:群聊
- 渠道:`wecom`
- 场景:内部群
- 渠道会话 ID`roomid_manual_internal_001`
- 名称:`测试内部群`
- 负责人:留空或选择任意账号
- [ ] **Step 4: 提交并确认**
Click "保存".
Expected: 弹窗关闭,列表出现新群聊,场景列显示「内部群」。
Take screenshot: `admin-web/screenshots/04-internal-group-created.png`
- [ ] **Step 5: 数据库确认(可选)**
Run: `docker exec -it mci-mysql mysql -uroot -proot sino_mci -e "SELECT id, conversation_name, conversation_type, conversation_scene FROM mci_conversation WHERE channel_conversation_id='roomid_manual_internal_001';"`
Expected: conversation_scene=1。
---
### Task 4: 绑定 WECOM_BOT 到内部群
**Files:**
- Modify if needed: `admin-web/src/views/Conversation.vue`, `backend/mci-server/src/main/java/com/sino/mci/channel/service/ConversationService.java`
- Test via UI: 会话详情抽屉
**Interfaces:**
- Consumes: `POST /api/v1/conversation/{id}/bind-account`
- Produces: ChannelAccountConversation 主发送绑定记录
- [ ] **Step 1: 打开会话详情**
In Conversation list, click the row of the newly created internal group.
Expected: 右侧抽屉打开,显示会话详情和「绑定账号」「绑定标签」按钮。
- [ ] **Step 2: 打开绑定账号弹窗**
Click "绑定账号".
Expected: 弹窗显示可选账号列表,应能过滤或显示 WECOM_BOT 账号。
- [ ] **Step 3: 选择 WECOM_BOT 账号**
Select the WECOM_BOT account created in Task 2.
Binding type: 主发送账号(若 UI 有选项,选 1
- [ ] **Step 4: 提交并确认**
Click "保存" / "绑定".
Expected: 绑定成功提示,会话详情中负责人变为该 WECOM_BOT 账号。
Take screenshot: `admin-web/screenshots/05-bot-bound.png`
- [ ] **Step 5: 数据库确认(可选)**
Run: `docker exec -it mci-mysql mysql -uroot -proot sino_mci -e "SELECT account_id, binding_type FROM mci_channel_account_conversation WHERE conversation_id=(SELECT id FROM mci_conversation WHERE channel_conversation_id='roomid_manual_internal_001');"`
Expected: 存在 binding_type=1 的记录。
- [ ] **Step 6: 提交修复(如有绑定校验问题)**
If binding fails with "账号渠道类型与会话不一致" or similar, check `ConversationService.isAccountCompatibleWithConversation` and fix.
---
### Task 5: 发送测试消息
**Files:**
- Modify if needed: `admin-web/src/views/MessageTest.vue`, `backend/mci-server/src/main/java/com/sino/mci/send/service/SendService.java`
- Test via UI: `http://localhost:5177/message/test`
**Interfaces:**
- Consumes: `POST /api/v1/send/test``POST /api/v1/send`
- Produces: SendResponse(taskId, totalCount, status)
- [ ] **Step 1: 进入消息测试页面**
Navigate to `http://localhost:5177/msg-platform/message-test`.
Take screenshot: `admin-web/screenshots/06-message-test.png`
- [ ] **Step 2: 选择内部群目标**
Select target type = 群聊,选择刚才创建的「测试内部群」。
- [ ] **Step 3: 填写消息内容**
Content type: text
Content: `测试消息 from e2e verification`
- [ ] **Step 4: 发送并记录 taskId**
Click "发送".
Expected: 页面显示发送成功,返回 taskId 和 status`accepted`)。
Copy the taskId.
Take screenshot: `admin-web/screenshots/07-message-sent.png`
- [ ] **Step 5: 后端日志检查**
Tail `logs/mci-server.log` for routing decision.
Expected log: 路由到 WECOM_BOT 账号,调用 webhook URL。
- [ ] **Step 6: 提交修复(如有路由错误)**
If routing goes to WECHAT_PERSONAL or WECOM_AGENT instead of WECOM_BOT, fix `SendService.resolveConversationTarget`.
---
### Task 6: 查询任务状态
**Files:**
- Modify if needed: `admin-web/src/views/SendRecord.vue`, `backend/mci-server/src/main/java/com/sino/mci/send/service/SendService.java`
- Test via UI/API: `GET /api/v1/send/{taskId}/status`, `GET /api/v1/send/records`
- UI page: `http://localhost:5177/message/send-record`
**Interfaces:**
- Consumes: taskId from Task 5
- Produces: 聚合状态计数和明细记录
- [ ] **Step 1: 等待 MQ 消费**
Wait 5-10 seconds for send task to be processed.
- [ ] **Step 2: 查询任务状态**
Option A (UI): Navigate to SendRecord page, filter by taskId.
Option B (API): `curl -H "X-Tenant-Code: <tenant>" http://localhost:8080/msg-platform/api/v1/send/{taskId}/status`
Expected: total=1, success=1 或 failed=1取决于 webhook URL 是否有效)。
Take screenshot: `admin-web/screenshots/08-task-status.png`
- [ ] **Step 3: 查询明细记录**
Run: `docker exec -it mci-mysql mysql -uroot -proot sino_mci -e "SELECT task_id, channel_type, send_status, channel_result FROM mci_send_record WHERE task_id='{taskId}';"`
Expected: send_status in (2,3)channel_type related to wecom_bot/wecom。
- [ ] **Step 4: 提交修复(如有状态不准)**
If status counts are wrong or records missing, fix `SendService.getTaskStatus` or `SendMessageConsumer`.
---
### Task 7: 汇总验证报告
**Files:**
- Create: `docs/testing/2026-07-15-send-routing-e2e-report.md`
**Interfaces:**
- Consumes: 前面所有任务的截图、日志、数据库结果
- Produces: 验证报告文档
- [ ] **Step 1: 整理发现的问题和修复**
List all bugs found and their commits.
- [ ] **Step 2: 编写报告**
Write report with sections:
- 环境
- 执行步骤
- 通过项
- 未验证项(如需真实企业微信环境)
- 剩余风险
- 截图索引
- [ ] **Step 3: 提交报告和截图**
```bash
git add admin-web/screenshots/ docs/testing/2026-07-15-send-routing-e2e-report.md
git commit -m "docs(testing): e2e verification report for send routing"
```
- [ ] **Step 4: Push 到 origin/main**
```bash
git push origin main
```
---
## Self-Review Checklist
- [ ] Spec coverage: 设计文档中的 7 步流程、检查点、问题处理、交付物均有对应任务。
- [ ] Placeholder scan: 无 TBD/TODO所有步骤均有明确命令或操作。
- [ ] Type consistency: 使用的设计字段名conversationScene, accountType, channelType, taskId与代码一致。
- [ ] File paths: 所有路径均使用绝对路径或相对于 `/f/sino-mci` 的路径。