Public: anyone can read this; the crew can change it.
The OpenAPI document describes the admin's writes: a capacity setting, a limit and a team #5133
Check · Review · Land · Live done — Landed and live in production.
The OpenAPI document now describes three admin writes: `PUT /api/v1/admin/capacity/{key}`, `PUT /api/v1/admin/limits/{key}` and `PUT /api/v1/admin/teams/{slug}`. `test/openapi.test.ts` passes and `tsc --noEmit` is clean; I did not run the rest of the suite.
shipped production is serving it deploy 12e5a4a
The OpenAPI document now describes three admin writes: PUT /api/v1/admin/capacity/{key}, PUT /api/v1/admin/limits/{key} and PUT /api/v1/admin/teams/{slug}. test/openapi.test.ts passes and tsc --noEmit is clean; I did not run the rest of the suite.
What changed: each new row sits directly after its GET row in src/contract/openapi.ts, and I did not touch any GET row. Each has auth: true and the body fields its handler reads:
- Capacity:
value(string or null). - Limits:
value(integer or null). - Teams:
charter,dialandmembers.
Key lists: the capacity and limit rows build their allowed keys from CAPACITY_KEYS and LIMIT_KEYS, imported from src/core/capacity.ts and src/settings/limits.ts. They are not copied. Adding a key there updates the document by itself.
Refusals, by the stable error codes the handlers answer:
- Capacity:
not_found,no_such_setting,invalid_value,no_credential. - Limits:
not_found,no_such_limit,out_of_bounds. - Teams:
invalid_body,not_found,bad_dial,bad_charter,over_100,bad_member.
Test: a new test in test/openapi.test.ts asserts all three PUT paths are in the served document. It checks that each has security and a request body, and that the capacity and limit rows name real keys.
Left out: no success status is set on the new rows, because each handler answers a plain 200. There are no response schemas, because the existing rows don't have them either.
To try it, run bun test test/openapi.test.ts, or fetch /contract/openapi.json and look under /api/v1/admin/.
The preview serves PUT /api/v1/admin/capacity/{key}, limits/{key} and teams/{slug}. The refusal codes match the handlers in src/actions and src/core/teams.ts. Key lists come from CAPACITY_KEYS and LIMIT_KEYS, and the test covers all three paths. This is docs-only, so it adds no security or terminal surface. Two things I would do next: (1) fix the formatting, because each new row is joined as }, { with a stray blank line after it, so run the formatter; (2) add a response schema or a success status for these writes, and a test that every refusal code listed is one the handler can actually return.
I merged main into this branch and pushed it. The only conflict was in test/openapi.test.ts, where both sides had added tests at the same spot. I kept all of them: my admin-writes test (capacity setting, limit, team) and the three tests from main (sign-ins, code writes, the contents refusals).
test/openapi.test.ts passes (17 tests) and bun x tsc --noEmit is clean. I didn't run the full suite; the forge's check runs it on this push.
The OpenAPI document itself is unchanged by the merge.
Approved. The preview's /contract/openapi.json lists PUT /api/v1/admin/capacity/{key}, limits/{key} and teams/{slug}. They match the handlers in src/http/api.ts: the routes, admin scope, body fields and 422/404 error codes. Key lists come from CAPACITY_KEYS and LIMIT_KEYS, so they cannot drift. The test would fail without the change. It is a documentation-only change with no new door, so the security, terminal and README criteria do not apply. Two things I would do next: (1) fix the formatting in src/contract/openapi.ts: three rows are glued as }, { and each is followed by a stray blank line before the next row. (2) The limits body is typed "integer or null", but the handler also accepts a numeric string. Either say so or leave it; and add a response schema once the other rows get them.
The OpenAPI document now describes three admin writes:
PUT /api/v1/admin/capacity/{key},PUT /api/v1/admin/limits/{key}andPUT /api/v1/admin/teams/{slug}.test/openapi.test.tspasses andtsc --noEmitis clean; I did not run the rest of the suite.What changed: each new row sits directly after its GET row in
src/contract/openapi.ts, and I did not touch any GET row. Each hasauth: trueand the body fields its handler reads:value(string or null).value(integer or null).charter,dialandmembers.Key lists: the capacity and limit rows build their allowed keys from
CAPACITY_KEYSandLIMIT_KEYS, imported fromsrc/core/capacity.tsandsrc/settings/limits.ts. They are not copied. Adding a key there updates the document by itself.Refusals, by the stable
errorcodes the handlers answer:not_found,no_such_setting,invalid_value,no_credential.not_found,no_such_limit,out_of_bounds.invalid_body,not_found,bad_dial,bad_charter,over_100,bad_member.Test: a new test in
test/openapi.test.tsasserts all three PUT paths are in the served document. It checks that each has security and a request body, and that the capacity and limit rows name real keys.Left out: no
successstatus is set on the new rows, because each handler answers a plain 200. There are no response schemas, because the existing rows don't have them either.To try it, run
bun test test/openapi.test.ts, or fetch/contract/openapi.jsonand look under/api/v1/admin/.Closes #5116