Skip to content

Commit d92292f

Browse files
duyetduyetbot
andauthored
test(api): stabilize sparse state query coverage (#99)
* test(api): stabilize sparse state query coverage Co-Authored-By: Duyet Le <me@duyet.net> Co-Authored-By: duyetbot <bot@duyet.net> * test(api): speed up sparse state query setup Co-Authored-By: Duyet Le <me@duyet.net> Co-Authored-By: duyetbot <bot@duyet.net> --------- Co-authored-by: duyetbot <bot@duyet.net>
1 parent 000d264 commit d92292f

4 files changed

Lines changed: 56 additions & 42 deletions

File tree

AGENTS.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ scripts/ Setup and deployment scripts
1515

1616
See `docs/knowledge/core-memory.md` for durable maintenance notes. Do not create dated AI review reports; fold recurring findings into core memory and keep `docs/INDEX.md` updated.
1717

18+
For automation runs, read `$CODEX_HOME/automations/code-smell-detector/memory.md` before scanning commits. In sandboxed checkouts, use the writable Bun/Wrangler paths recorded in `docs/knowledge/core-memory.md` if verification commands hit tempdir or Wrangler log permission errors.
19+
1820
**Architecture**: Single Cloudflare Worker serves both the REST API (`/api/v1/*`) and dashboard static assets.
1921

2022
## Dev Commands
@@ -123,7 +125,7 @@ Run all quality checks in parallel. If any regress, fix before proceeding.
123125
bunx biome check packages/api/src/
124126
bunx tsc --noEmit -p packages/api/tsconfig.json
125127
cd packages/api && bunx vitest run
126-
cd packages/dashboard && bunx tsc --noEmit
128+
cd packages/dashboard && bun run build
127129
git status --short
128130
```
129131

CLAUDE.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ scripts/ Setup and deployment scripts
1515

1616
See `docs/knowledge/core-memory.md` for durable maintenance notes. Do not create dated AI review reports; fold recurring findings into core memory and keep `docs/INDEX.md` updated.
1717

18+
For automation runs, read `$CODEX_HOME/automations/code-smell-detector/memory.md` before scanning commits. In sandboxed checkouts, use the writable Bun/Wrangler paths recorded in `docs/knowledge/core-memory.md` if verification commands hit tempdir or Wrangler log permission errors.
19+
1820
**Architecture**: Single Cloudflare Worker serves both the REST API (`/api/v1/*`) and dashboard static assets.
1921

2022
## Dev Commands
@@ -123,7 +125,7 @@ Run all quality checks in parallel. If any regress, fix before proceeding.
123125
bunx biome check packages/api/src/
124126
bunx tsc --noEmit -p packages/api/tsconfig.json
125127
cd packages/api && bunx vitest run
126-
cd packages/dashboard && bunx tsc --noEmit
128+
cd packages/dashboard && bun run build
127129
git status --short
128130
```
129131

docs/knowledge/core-memory.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,15 @@ Durable notes for recurring maintenance. Keep this file small and update it inst
77
- `CLAUDE.md` is the main repo guide; root `AGENTS.md` carries the same guidance for Codex and other agents.
88
- Use `PLAN.md` as the autonomous maintenance playbook, but store recurring lessons here.
99
- Do not create new snapshot files like `docs/API_DOCS_REVIEW.md`, `docs/test-coverage-analysis.md`, or `docs/reviews/code-smell-dead-code-*.md`.
10+
- For code-smell automation, read `$CODEX_HOME/automations/code-smell-detector/memory.md` first, scan commits since that timestamp, then fall back to the last 24 hours or 7 days only when needed.
1011
- When refreshing `/agents.md`, edit `packages/api/src/content/agents.md` and regenerate `packages/api/src/content/static.ts`.
12+
- In sandboxed maintenance runs, set Bun and Wrangler writable paths when needed: `BUN_TMPDIR=/private/tmp/codex-bun-tmp`, `BUN_INSTALL_CACHE_DIR=/private/tmp/codex-bun-cache`, and `XDG_CONFIG_HOME=/private/tmp/codex-wrangler-config`.
13+
- Validate dashboard changes with `cd packages/dashboard && bun run build`; raw `bunx tsc --noEmit` can fail in fresh checkouts before Next generates route type files.
1114

1215
## Review Memory
1316

1417
- Historical API-doc review notes from March 2026 were folded into the live docs. Keep API endpoint coverage current in `docs/api-reference.md`, `docs/sdk.md`, and `docs/integration.md`.
1518
- Historical test-coverage notes were stale after the test suite expanded. Use current `packages/api/test/` coverage and CI output as the source of truth before adding tests.
1619
- Recent state-platform maintenance should cover sparse `/api/v2/states/query` filters. Tag and JSON-path queries must keep scanning past nonmatching rows instead of stopping at the first capped candidate page.
20+
- Sparse state-query cap tests seed enough D1 rows to run close to Vitest's default timeout under full-suite load; keep an explicit per-test timeout on that coverage instead of changing production scan behavior.
1721
- The TypeScript LangGraph adapter should extend `BaseCheckpointSaver` from `@langchain/langgraph-checkpoint`; keep the optional peer and dev dependency aligned so SDK type/build checks verify that contract.

packages/api/test/state-platform.test.ts

Lines changed: 46 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -147,51 +147,57 @@ describe("State platform", () => {
147147
expect(body.data.map((row: any) => row.state_key)).toEqual(["sparse-match"]);
148148
});
149149

150-
it("returns a cursor when sparse query scanning reaches the per-request cap", async () => {
151-
await putState("sparse-capped-match", {
152-
agent_id: "query-agent-sparse-capped",
153-
data: { status: "done", nested: { priority: "high" } },
154-
tags: ["sparse-capped-match"],
155-
});
156-
157-
for (let index = 0; index < 55; index++) {
158-
await putState(`sparse-capped-miss-${index}`, {
159-
agent_id: "query-agent-sparse-capped",
160-
data: { status: "pending", nested: { priority: "low" } },
161-
tags: ["sparse-capped-miss"],
162-
});
163-
}
164-
165-
const first = await SELF.fetch("http://localhost/api/v2/states/query", {
166-
method: "POST",
167-
headers: authHeaders(),
168-
body: JSON.stringify({
150+
it(
151+
"returns a cursor when sparse query scanning reaches the per-request cap",
152+
async () => {
153+
await putState("sparse-capped-match", {
169154
agent_id: "query-agent-sparse-capped",
155+
data: { status: "done", nested: { priority: "high" } },
170156
tags: ["sparse-capped-match"],
171-
limit: 1,
172-
}),
173-
});
157+
});
174158

175-
expect(first.status).toBe(200);
176-
const firstBody = await first.json<any>();
177-
expect(firstBody.data).toEqual([]);
178-
expect(firstBody.pagination.next_cursor).toEqual(expect.any(String));
159+
await Promise.all(
160+
Array.from({ length: 55 }, (_, index) =>
161+
putState(`sparse-capped-miss-${index}`, {
162+
agent_id: "query-agent-sparse-capped",
163+
data: { status: "pending", nested: { priority: "low" } },
164+
tags: ["sparse-capped-miss"],
165+
}),
166+
),
167+
);
168+
169+
const first = await SELF.fetch("http://localhost/api/v2/states/query", {
170+
method: "POST",
171+
headers: authHeaders(),
172+
body: JSON.stringify({
173+
agent_id: "query-agent-sparse-capped",
174+
tags: ["sparse-capped-match"],
175+
limit: 1,
176+
}),
177+
});
179178

180-
const second = await SELF.fetch("http://localhost/api/v2/states/query", {
181-
method: "POST",
182-
headers: authHeaders(),
183-
body: JSON.stringify({
184-
agent_id: "query-agent-sparse-capped",
185-
tags: ["sparse-capped-match"],
186-
limit: 1,
187-
cursor: firstBody.pagination.next_cursor,
188-
}),
189-
});
179+
expect(first.status).toBe(200);
180+
const firstBody = await first.json<any>();
181+
expect(firstBody.data).toEqual([]);
182+
expect(firstBody.pagination.next_cursor).toEqual(expect.any(String));
183+
184+
const second = await SELF.fetch("http://localhost/api/v2/states/query", {
185+
method: "POST",
186+
headers: authHeaders(),
187+
body: JSON.stringify({
188+
agent_id: "query-agent-sparse-capped",
189+
tags: ["sparse-capped-match"],
190+
limit: 1,
191+
cursor: firstBody.pagination.next_cursor,
192+
}),
193+
});
190194

191-
expect(second.status).toBe(200);
192-
const secondBody = await second.json<any>();
193-
expect(secondBody.data.map((row: any) => row.state_key)).toEqual(["sparse-capped-match"]);
194-
});
195+
expect(second.status).toBe(200);
196+
const secondBody = await second.json<any>();
197+
expect(secondBody.data.map((row: any) => row.state_key)).toEqual(["sparse-capped-match"]);
198+
},
199+
15_000,
200+
);
195201

196202
it("enforces leases for protected writes", async () => {
197203
await putState("leased-run", { agent_id: "lease-agent", data: { value: 1 } });

0 commit comments

Comments
 (0)