codex@macbookpro
·
2026-03-30
FIX-BUG-035.md
1# FIX-BUG-035: null remote_conversation_id 仍保持 conversation link 唯一
2
3## 执行状态
4
5- 已完成(2026-03-30,代码 + 自动化验证已落地)
6
7## 关联 Bug
8
9BUG-035-conversation-links-null-unique-index.md
10
11## 实际修改文件
12
13- `packages/artifact-db/src/schema.ts`
14- `packages/artifact-db/src/store.ts`
15- `packages/artifact-db/src/index.test.js`
16- `packages/d1-client/src/d1-setup.sql`
17- `packages/d1-client/src/index.test.js`
18- `apps/conductor-daemon/src/index.test.js`
19
20## 实际修改
21
22- 把 `conversation_links` 的唯一约束拆成两类:
23 - `remote_conversation_id IS NOT NULL` 时继续按 `(platform, remote_conversation_id)` 唯一
24 - `remote_conversation_id IS NULL` 时按 `(platform, client scope, route/page/target/client fallback)` 级联唯一
25- 在 `ArtifactStore` 初始化时增加一次轻量迁移:
26 - 读取历史 `remote_conversation_id = NULL` 的重复 link
27 - 以最新记录为 canonical row
28 - 合并缺失字段并删除同 identity 的旧重复行
29 - 再创建新的部分唯一索引
30- 更新 store 的 null-remote resolve/upsert 逻辑:
31 - 优先按 `route_path`
32 - 其次按 `page_url`
33 - 再退到 `target_id`
34 - 最后才是仅 `client_id` 的兜底
35- 新增回归测试,覆盖:
36 - null remote 的重复 route upsert 只保留一条 link
37 - 旧 schema 下已写出的重复 null-remote link 能被启动迁移收敛为一条 canonical row
38 - `observeRenewalConversation` 在缺失 `remote_conversation_id` 时重复 observe 会稳定命中同一条 link
39
40## 验收标准
41
421. `remote_conversation_id = NULL` 时,同一平台/同一路由不会继续写出多条冲突 link
432. 缺失 remote conversation 的 repeated observe / upsert 会复用同一条 canonical link
443. 旧库中已存在的重复 null-remote link 不会阻塞新索引创建
454. `pnpm -C packages/artifact-db test`、`pnpm -C packages/d1-client test`、`pnpm -C apps/conductor-daemon test` 通过