im_wower
·
2026-03-22
T-023-control-api-smoke.md
1---
2task_id: T-023
3title: Control API 本地 D1 与 smoke
4status: done
5branch: feat/T-023-control-api-smoke
6repo: /Users/george/code/baa-conductor
7base_ref: main@6505a31
8depends_on:
9 - T-018
10write_scope:
11 - apps/control-api-worker/**
12 - tests/control-api/**
13 - scripts/cloudflare/**
14updated_at: 2026-03-22T02:16:15+0800
15---
16
17# T-023 Control API 本地 D1 与 smoke
18
19## 目标
20
21把 `control-api-worker` 从“有 Worker / D1 配置模板”推进到“能在本地做最小 D1 绑定与 smoke 验证”的程度。
22
23## 本任务包含
24
25- 在 `apps/control-api-worker/**` 内补本地 dev / smoke 入口
26- 在 `tests/control-api/**` 下补最小 smoke 或集成测试
27- 如有需要,在 `scripts/cloudflare/**` 下补本地准备脚本
28- 验证 control-api 在本地 D1 / mock D1 条件下的最小读写闭环
29
30## 本任务不包含
31
32- 修改 conductor-daemon
33- 修改 status-api
34- 真实线上 Cloudflare deploy
35- 修改 `packages/db/**`
36
37## 建议起始文件
38
39- `apps/control-api-worker/wrangler.jsonc`
40- `apps/control-api-worker/src/index.ts`
41- `apps/control-api-worker/src/runtime.ts`
42- `tests/control-api/`
43
44## 交付物
45
46- 本地 smoke 路径
47- 最小 control-api 集成测试
48- 更明确的本地 D1 准备方式
49
50## 验收
51
52- `npx --yes pnpm --filter @baa-conductor/control-api-worker typecheck`
53- `npx --yes pnpm --filter @baa-conductor/control-api-worker build`
54- 能说明如何在本地跑 control-api smoke
55
56## 更新要求
57
58完成时更新 frontmatter 的:
59
60- `status`
61- `base_ref`
62- `updated_at`
63
64并补充下面这些内容:
65
66## files_changed
67
68- `coordination/tasks/T-023-control-api-smoke.md`
69- `apps/control-api-worker/.dev.vars.example`
70- `apps/control-api-worker/package.json`
71- `apps/control-api-worker/local/sqlite-d1.mjs`
72- `apps/control-api-worker/local/harness.mjs`
73- `apps/control-api-worker/local/dev.mjs`
74- `apps/control-api-worker/local/smoke.mjs`
75- `scripts/cloudflare/prepare-control-api-local-db.mjs`
76- `tests/control-api/control-api-smoke.test.mjs`
77
78## commands_run
79
80- `git worktree add /Users/george/code/baa-conductor-T023 -b feat/T-023-control-api-smoke 6505a31`
81- `npx --yes pnpm install`
82- `node --check apps/control-api-worker/local/sqlite-d1.mjs`
83- `node --check apps/control-api-worker/local/harness.mjs`
84- `node --check apps/control-api-worker/local/dev.mjs`
85- `node --check apps/control-api-worker/local/smoke.mjs`
86- `node --check scripts/cloudflare/prepare-control-api-local-db.mjs`
87- `node --check tests/control-api/control-api-smoke.test.mjs`
88- `npx --yes pnpm --filter @baa-conductor/control-api-worker typecheck`
89- `npx --yes pnpm --filter @baa-conductor/control-api-worker build`
90- `npx --yes pnpm --filter @baa-conductor/control-api-worker db:prepare:local`
91- `npx --yes pnpm --filter @baa-conductor/control-api-worker smoke -- --db .wrangler/state/local-control-api.sqlite --resetDb`
92- `npx --yes pnpm --filter @baa-conductor/control-api-worker test:integration`
93- `node local/dev.mjs --smoke --resetDb`
94- `git diff --check`
95
96## result
97
98- 在 `apps/control-api-worker/local/**` 新增了 SQLite-backed D1 shim、本地 harness、`dev` server 和 `smoke` runner;`pnpm --filter @baa-conductor/control-api-worker dev` 现在会先构建,再在本地起一个可直接用 Bearer token 访问的 control-api。
99- 在 `tests/control-api/control-api-smoke.test.mjs` 增加了最小集成 smoke,覆盖 `system.pause -> system.state`、`leader.acquire -> system.state`、`tasks.create -> tasks.read` 三条最小读写闭环。
100- 在 `scripts/cloudflare/prepare-control-api-local-db.mjs` 增加了本地 DB 准备脚本,并在包脚本中暴露 `db:prepare:local`、`smoke`、`test:integration` 入口,方便后续联调复用。
101
102## risks
103
104- 当前本地验证使用的是 Node `node:sqlite` 驱动实现的 D1-compatible shim,而不是 `wrangler dev` 内建的真实本地 D1 运行时;SQL 行为与当前仓库 schema 一致,但仍可能与 Cloudflare 边缘环境存在细小差异。
105- 本次 smoke 聚焦已经实现的读写路由;`tasks.plan`、`tasks.claim`、`steps.*`、`tasks.logs.read`、`runs.read` 这些仍保持占位或未在测试中覆盖。
106- `dev` 入口是 Node HTTP wrapper,不包含 Cloudflare 特有的 request metadata 或 Worker 生命周期细节;如果后续要验证这些差异,仍需单独补 wrangler-local smoke。
107
108## next_handoff
109
110- 后续如果要把 control-api 纳入 `T-024` 端到端 smoke,可直接复用 `pnpm --filter @baa-conductor/control-api-worker dev` 和 `tests/control-api/control-api-smoke.test.mjs` 里的本地 harness。
111- 如果需要更贴近 Cloudflare 本地运行时,再补一层 `wrangler dev --local` / `wrangler d1` 路径,把现在的 SQLite shim smoke 与 wrangler smoke 并排保留。
112- 若后续开始实现 `tasks.plan`、`tasks.claim` 或 `steps.*` 的 durable 写入,应沿用当前 harness,把新增路由接到同一套本地 D1 smoke 里继续扩展。