codex@macbookpro
·
2026-03-31
FIX-BUG-036.md
1# FIX-BUG-036: projector cursor system_state 时间单位统一到毫秒
2
3## 执行状态
4
5- 已完成(2026-03-31,代码 + 自动化验证已落地)
6
7## 关联 Bug
8
9- `BUG-036-projector-cursor-updated-at-unit-mismatch.md`
10
11## 实际修改文件
12
13- `apps/conductor-daemon/src/renewal/projector.ts`
14- `apps/conductor-daemon/src/local-api.ts`
15- `apps/conductor-daemon/src/index.test.js`
16- `apps/status-api/src/data-source.ts`
17- `apps/status-api/src/index.test.js`
18- `packages/db/src/index.ts`
19- `packages/db/src/index.test.js`
20- `ops/sql/schema.sql`
21- `ops/sql/migrations/0001_init.sql`
22
23## 实际修改
24
25- 把 renewal projector cursor 保存到 `system_state` 时的 `updated_at` 从秒级改为毫秒级,和 `valueJson.observed_at` 保持同一单位。
26- 保持 cursor 恢复语义不变:
27 - 仍然只从 `valueJson.message_id` / `valueJson.observed_at` 恢复 cursor
28 - 不依赖 `system_state.updated_at` 决定恢复位置
29- 把 `automation` 这条 `system_state` 的写入链统一到毫秒级:
30 - `packages/db` 的 `ensureAutomationState()` 和 `setAutomationMode()` 默认写毫秒
31 - `local-api` 的 `setAutomationMode()` 在落库前把秒值规范化成毫秒,兼容旧调用点
32- 更新 `system_state` 初始化 SQL 和首个 migration,让默认 `automation.updated_at` 以毫秒单位写入。
33- 补上兼容读取:
34 - `local-api` 返回系统状态时接受秒或毫秒输入,统一输出毫秒
35 - `status-api` 读取 D1 快照时对 `automation.updatedAt` 做单位归一化,避免和仍为秒级的 lease 时间比较时出现混算
36
37## 回归测试
38
39- `packages/db`:覆盖 schema 初始化和 `ensureAutomationState()` 回填后的 `system_state.updated_at` 为毫秒
40- `apps/conductor-daemon`:
41 - 覆盖 projector saveCursor 写入毫秒级 `updated_at`
42 - 覆盖 legacy 秒级 `updated_at` 的 cursor 仍能按 `valueJson` 正常恢复
43 - 覆盖 `/v1/system/pause` 返回的 automation `updated_at` 与库内毫秒值一致
44- `apps/status-api`:覆盖毫秒级 automation 时间和秒级 lease 时间并存时的快照归一化
45
46## 验证
47
48- `pnpm -C packages/db test`
49- `pnpm -C apps/status-api test`
50- `pnpm -C apps/conductor-daemon test`
51- `pnpm build`