Files
gochat/review-h58.md
T
Rogeeandrogee c922460649 H-97: fix Shangwutong conversation routing (#16)
* 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>
2026-08-14 14:35:12 +08:00

2.5 KiB
Raw Blame History

审查结论:发现 2 个阻断项;H-53 的事务回滚根因已关闭,但迁移可逆性与并发回归测试仍不满足验收。

P1

  • backend/migrations/000079_make_captain_bindings_unique.down.sql:1-4 不可逆:up 迁移会删除重复 agent_botsagent_bot_inboxescaptain_inboxes 并重指向 conversation/rule/eventdown 只删索引和 captain_assistant_id 列,无法恢复被删行、原引用或 assistant 绑定信息。生产回滚会造成永久数据丢失。最小修复:将该迁移明确标为不可回滚并阻止自动 down,或在 up 前做可恢复备份/保留映射并实现恢复型 down。

  • backend/internal/service/captain_binding_atomicity_test.go:44-51,55-87 的“并发”测试设置 SetMaxOpenConns(1)8 个 goroutine 被数据库连接池串行化,不能触发 select/insert 竞态,也不能证明 PostgreSQL 的唯一约束 + ON CONFLICT 在真实并发下有效。最小修复:使用至少 2 个连接,在真实 PostgreSQL(或允许并发连接的 SQLite)上用 barrier 同时进入,并断言所有调用成功且只存在一个 bot/binding。

非阻断残余风险

  • backend/migrations/000079_make_captain_bindings_unique.up.sql:87-92 会静默保留最小 id 并删除同一 inbox 的其他 active CaptainInbox;若历史数据代表不同 assistant,这是业务绑定丢失。部署前应核对冲突数量并记录/人工决策,而不是仅依赖迁移中的删除。
  • migration 未显式锁表;在线写入可能在去重后、唯一索引建立前制造新冲突,导致迁移失败(通常停写/维护窗可规避)。

已核验

  • go test ./internal/service -run 'Test(WidgetConversationRollsBackCaptainBindingOnCreateFailure|TestEnsureCaptainAgentBotBindingConcurrentCallsStayUnique|TestDissociateInboxRollsBackCaptainDeleteWhenBindingDeleteFails)' -count=1:通过。
  • go test ./internal/service -run 'Test(ConversationServiceAITakeoverRejectsMissingOrAmbiguousAI|TestCaptain)' -count=1:通过。
  • go vet ./internal/service ./internal/repository ./internal/modelgo build ./...:通过。
  • 事务实现确认:widget conversation、Captain bot、AgentBotInbox 在同一 Transaction;解绑两次删除在同一 Transaction,失败会回滚。

因此:三个 P1 中“widget conversation 原子创建”和“解绑失败回滚”已关闭;“assistant/inbox 并发唯一性”代码路径有数据库约束,但当前新增测试没有有效验证真实并发;迁移回滚不可逆是新增阻断项。