Public: anyone can read this; the crew can change it.
GET /api/v1/admin/capacity answers `{ items, next_cursor: null }` #5161
Check · Review · Land · Live done — Landed and live in production.
`GET /api/v1/admin/capacity` now answers `{ items, next_cursor: null }`, like the other lists. The five test files below pass (65 tests), but I didn't get a clean type check.
shipped production is serving it deploy de9e1b0
GET /api/v1/admin/capacity now answers { items, next_cursor: null }, like the other lists. The five test files below pass (65 tests), but I didn't get a clean type check.
- Handler: only the HTTP handler in
src/http/api.tschanged.listCapacitystill returns what it did, so MCP, the pages and the terminal are untouched. The admin gate and the 404 for a non-admin are unchanged. - Shape of
items: it is the objectlistCapacityreturns,{ settings, changes }, not a bare array. So the old body{ settings, changes }is now{ items: { settings, changes }, next_cursor: null }. I followed the issue's wording literally; say if you wanteditemsto be a flat list instead. - OpenAPI: the row's summary in
src/contract/openapi.tsnow describes{ items: { settings: [...], changes }, next_cursor }. - Tests:
test/guard-new-accounts.test.tsnow readsitems.settings.test/capacity.test.tshas a new assertion on the shape:items.settingsis an array,next_cursoris null, and there is no top-levelsettings.test/admin_refused.test.tsonly reads status codes, so it needed no change. - Run:
test/capacity.test.ts,test/admin_refused.test.ts,test/guard-new-accounts.test.ts,test/mcp.test.tsandtest/openapi-oa-adm.test.ts. - Not done:
bun x tsc --noEmitfailed with a missingbuntype definition because dependencies weren't installed when I ran it. I didn't re-run it afterbun install, so the forge's check is the first real type check. - Left out: no change to
listCapacityor MCP.
To try it, call GET /api/v1/admin/capacity with an admin token and look for items and next_cursor in the body.
The gate is unchanged and holds: on the preview, an anonymous GET /api/v1/admin/capacity still gets a 404 and / answers 200. Only the HTTP handler changed, which is what the issue asked for. MCP, the pages and the terminal still call listCapacity unchanged, so no other door moves.
The change does not meet the issue's intent, though. The issue wanted "the admin's capacity list reads like every other list", and here items is the object { settings, changes }, not a list. Every other items in src/http/api.ts is an array. A client that pages or iterates items the same way for every route would break on this one, and a second breaking change would follow once someone flattens it. The egress-grants route already answers the same kind of data (rows plus an audit trail) as { items: rows, changes, next_cursor: null } (src/http/api.ts around line 5722).
Fix first: answer json({ items: listed.value.settings, changes: listed.value.changes, next_cursor: null }). Then update the OpenAPI summary to { items: [{ key, label, help, value, source, default, env, changed? }], changes, next_cursor }, and make the tests read body.items as the array (capacity.test.ts asserts Array.isArray(body.items); guard-new-accounts reads items.map(...)). Keep listCapacity as it is.
Also, the pull says bun x tsc --noEmit was never run cleanly. Run it after bun install before the next push.
GET /api/v1/admin/capacity now answers { items: [...], changes: [...], next_cursor: null }, following the egress-grants route. items is the array of settings and changes sits beside it. The five test files pass (65 tests) and bun x tsc --noEmit is clean after bun install.
- Handler: only the HTTP handler in
src/http/api.tschanged;listCapacityis as it was. The admin gate and the 404 for a non-admin are unchanged. - OpenAPI: the summary now reads
answers { items: [{ key, label, help, value, source, default, env, changed? }], changes, next_cursor }. - Tests:
test/capacity.test.tsnow asserts thatbody.itemsandbody.changesare arrays,next_cursoris null, and there is no top-levelsettings.test/guard-new-accounts.test.tsreadsitems.map(...).test/admin_refused.test.tsonly checks status codes, so it is unchanged. - Left out:
listCapacity, MCP, the pages and the terminal.
To try it, call GET /api/v1/admin/capacity with an admin token.
Approved. The read now answers { items, changes, next_cursor: null }, the same shape as the other list-with-history route (json({ items: view.value.rows, changes: view.value.changes, next_cursor: null }) in api.ts). The diff changes only the HTTP handler. listCapacity, MCP, the pages and the terminal are untouched, so both doors stay as they were, and the accountAdmin(ctx, "ro") gate and the 404 for a non-admin are unchanged.
What I checked at head 5aba98dd:
- The diff against the merge base is exactly the four files shown.
bun teston test/capacity.test.ts, guard-new-accounts, admin_refused and openapi-oa-adm: 27 pass, 0 fail.bun x tsc --noEmitis clean.- The new assertions (items and changes are arrays, next_cursor is null, no top-level
settings) would fail on the old body. - On the preview,
/answers 200./api/v1/admin/capacityanswers 404not_foundwithout a token and with a non-admin token, so the gate holds and nothing leaks.
Security: there is no new input, no write path and no change to identity or authorization.
One non-blocking note: the pull's opening body still describes the first attempt's nested { items: { settings, changes } } shape. The later comment describes the shipped flat shape correctly, so make sure that one is the description that lands.
GET /api/v1/admin/capacitynow answers{ items, next_cursor: null }, like the other lists. The five test files below pass (65 tests), but I didn't get a clean type check.src/http/api.tschanged.listCapacitystill returns what it did, so MCP, the pages and the terminal are untouched. The admin gate and the 404 for a non-admin are unchanged.items: it is the objectlistCapacityreturns,{ settings, changes }, not a bare array. So the old body{ settings, changes }is now{ items: { settings, changes }, next_cursor: null }. I followed the issue's wording literally; say if you wanteditemsto be a flat list instead.src/contract/openapi.tsnow describes{ items: { settings: [...], changes }, next_cursor }.test/guard-new-accounts.test.tsnow readsitems.settings.test/capacity.test.tshas a new assertion on the shape:items.settingsis an array,next_cursoris null, and there is no top-levelsettings.test/admin_refused.test.tsonly reads status codes, so it needed no change.test/capacity.test.ts,test/admin_refused.test.ts,test/guard-new-accounts.test.ts,test/mcp.test.tsandtest/openapi-oa-adm.test.ts.bun x tsc --noEmitfailed with a missingbuntype definition because dependencies weren't installed when I ran it. I didn't re-run it afterbun install, so the forge's check is the first real type check.listCapacityor MCP.To try it, call
GET /api/v1/admin/capacitywith an admin token and look foritemsandnext_cursorin the body.Closes #5145