* H-60: harden Captain migration rollback and concurrency * chore(agent): baseline — uncommitted work from the local directory * fix: route Shangwutong events by display id --------- Co-authored-by: Rogee <rogee@ipao.vip>
26 lines
3.8 KiB
Markdown
26 lines
3.8 KiB
Markdown
审查结论:阻断,不建议父问题进入 review。Stage 3 两个子问题虽然已标记完成且 PR #5/#6 据交接记录已 squash 合并,但 H-17 的 CID 相关阻断仍未全部关闭。
|
||
|
||
阻断项(按严重性)
|
||
|
||
1. P0:kind=52 CID 链路仍不可达。`channels/shangwutong/internal/delivery/mapping.go:170-171` 只设置 `ContactCID`,没有设置 `RequiresContact`/`RawOnly`;因此 `inbound.go:106-108` 直接 complete,永远不会执行 `ensureResources` 的 metadata 写入。结果 `contact_inboxes.channel_metadata.cid` 不会被持久化,昵称 durable job 无法命中 CID。最小修复:让 kind=52 进入仅更新 ContactInbox metadata 的路径,且把 CID 纳入写入条件;补真实 worker/HTTP 调用链回归测试。
|
||
|
||
2. P1:公共 Widget 仍可注入内部 CID。`backend/internal/handler/widget/widget_handler.go:1394-1429` 和 `backend/internal/service/widget_service.go:821-845` 接受并保存 `channel_metadata.cid`;HMAC 非 mandatory 时,知道 source_id 的公共调用方可写任意 CID,可能把客服改名投递到错误商务通客户。最小修复:从公共 request DTO、绑定和 service 写入中删除 CID;仅保留受信 Connector 内部路径。
|
||
|
||
3. P1:已有 source 的 CID 更新仍只改内存。`backend/internal/service/widget_service.go:769-784` 的 PublicCreateContact existing 分支调用 `setContactInboxChannelMetadata` 后没有 `contactInboxRepo.Update`,所以 Connector 走已有 source 的 POST 分支时 CID 静默丢失。最小修复:metadata 变化时持久化,并覆盖已有 source 测试。
|
||
|
||
4. P2:migration down 仍丢失 rename operation。`channels/shangwutong/db/migrations/002_add_rename_operation.down.sql:17-19` 只复制 `operation = 'end_conversation'`,随后删除原表;任何 `change_contact_name` 的 pending/delivered/uncertain/failed 记录都会被静默删除。最小修复:存在该类记录时明确拒绝 down,或完整无损迁移后再收紧约束。用 sqlite 重现确认 down 后只剩 end_conversation。
|
||
|
||
5. P1:昵称事件入队错误被吞掉。`backend/internal/handler/api/v1/contact_handler.go:293-297` 忽略 `channelDispatcher.Dispatch` 错误;若 durable job 入队因数据库/worker 故障失败,联系人更新仍返回 200 且没有补偿事件,反写任务永久丢失。最小修复:让该错误进入明确的可重试失败响应,或把事件入队纳入同一可靠事务/outbox。
|
||
|
||
AI 接管退出部分无阻断:`message_service.go` 用行锁和 takeover version 防止人工消息与迟到 AI 竞态;显式退出和人工发送均发布既有 `conversation.updated`,WS payload 含最新 `ai_takeover_active`,前端消费后立即合并状态。
|
||
|
||
验证通过:
|
||
- `cd backend && go test ./internal/service -run 'TestConversationServiceAITakeoverStartExitAndRestart|TestMessageServiceHumanOutgoingExitsAITakeoverAtomically|TestCaptainConversationResponseRechecksTakeoverBeforeCreate|TestCaptainConversationResponseRejectsStaleJobAfterReentry' -count=1`
|
||
- `cd backend && go test ./internal/wsevent -run TestOnEvent_ConversationUpdatedPublishesInactiveTakeover_Cov3 -count=1`
|
||
- `cd backend && go test ./internal/handler/api/v1 ./internal/handler/widget ./internal/service -run 'Test(Shangwutong|WidgetHandler_PublicContactIgnoresCID|ContactUpdate|Captain|MessageServiceHumanOutgoing|ConversationServiceAITakeover)' -count=1`
|
||
- `cd channels/shangwutong && go test ./... -count=1 && go vet ./...`
|
||
- `cd frontend && pnpm exec vitest run app/javascript/dashboard/helper/specs/actionCable.spec.js app/javascript/dashboard/store/modules/specs/conversations/mutations.spec.js`(83 passed)
|
||
- `cd frontend && pnpm build`
|
||
|
||
PR 状态:H-28/H-29 交接记录称 #5/#6 已合并;当前 Multica issue PR link 查询为空(squash 后关联未保留)。无需新 PR;请退回 H-28 修复上述 CID/回滚/入队问题后再复审。
|