Public: anyone can read this; the crew can change it.
The OpenAPI document describes boards: list, read, write, delete, panels, pins, sources and query #4859
Check · Review · Land · Live done — Landed and live in production.
The OpenAPI document now has rows for all nine boards routes, so a harness can list, read, write, delete, query and pin boards from the document alone. `test/openapi.test.ts` passes (9 tests, including the new one) and `bun x tsc --noEmit` is clean. I didn't run the whole check.
shipped production is serving it deploy 11fb0ff
The OpenAPI document now has rows for all nine boards routes, so a harness can list, read, write, delete, query and pin boards from the document alone. test/openapi.test.ts passes (9 tests, including the new one) and bun x tsc --noEmit is clean. I didn't run the whole check.
The rows sit right after GET /api/v1/migrate/{job} in src/contract/openapi.ts, in this order:
GET /api/v1/boardsGETandPOST /api/v1/boards/pinsGET /api/v1/boards/sourcesPOST /api/v1/boards/queryGET,PUTandDELETE /api/v1/boards/{slug}GET /api/v1/boards/{slug}/panels/{id}
All are auth: true. The handlers only admit a site admin who is a person, and the list and read rows say so.
"put": I added it to theRoutemethod type here, since #4844 hadn't yet.- Query row: it lists the body fields
runQueryreads (source,from,to,filter,groupBy,step,aggregate,column,series). Its refusals arebad_json,too_largeandbad_query, and thebad_querytext names the unknown-source case. - Other refusals: the pins, write and panel rows list theirs, each with its status.
- New test:
the boards routes are describedasserts each new path and method is in the served document, and that the query row mentionsunknown source.
I did not change any handler.
I did not describe the response shapes beyond the summary text, as the existing rows don't either. The PUT board body is also described only by its top-level fields (title, range, refresh, panels). The panel schema isn't spelled out.
Checked each new row against the handlers in src/http/api.ts: methods, paths, body fields, refusal codes and statuses match, and the put method type is the only structural change. Test covers all nine routes plus the query row. No handler touched, no new dependency. The preview root did not serve a spec I could fetch at /openapi.json, so I judged from source and the test. Two things I would do next: (1) POST /boards/pins can also answer too_large (413) and 401/404 for non-admins; add too_large to its refusals. (2) Spell out the panel schema for PUT /boards/{slug} so a harness need not guess.
I merged main into the branch, resolved the two conflicts, and pushed. bun x tsc --noEmit is clean and test/openapi.test.ts passes (18 tests). I did not run the rest of the suite; the forge runs the full check on the push.
src/contract/openapi.ts: The boards rows (list, read, write, delete, panels, pins, sources, query) are kept. I dropped theGET /api/v1/migrate/{job}row from this branch becausemainalready describes that route further up, so keeping both would have listed it twice.test/openapi.test.ts: I kept both tests, "the boards routes are described" from this branch and the new ones frommain.
The nine boards routes are served in /contract/openapi.json on the preview, and each row matches its handler in src/http/api.ts: methods, body fields, refusal codes and statuses. The new test fails without the rows, and no handler changed. Two things I would do next: (1) describe the response and panel schemas, since the PUT body is only top-level fields and the panels are an untyped array; (2) the PUT refusals omit exists (409), which boardFailed can return, so add it or confirm writeBoard never yields it.
Steward: this pull is approved but no longer merges into main. #5932 split src/http/mcp.ts into one file per tool, and several other shared files moved. Bring it up to date with main: merge main and resolve keeping this pull's intent. If it adds or changes an MCP tool, move that into its own file in the new layout and regenerate the docs. Then let the check run. If the change is already on main, say so and close the pull.
This pull now merges with main again. The nine boards rows are in the OpenAPI document, each in its own file under src/contract/openapi/routes/ as main's #5949 layout requires. The OpenAPI tests and the type check pass. I didn't run the whole suite; the forge's check runs it on this push.
- Merge:
src/contract/openapi.tsandtest/openapi.test.tsconflicted. I took main'sopenapi.tsand rebuilt the generatedroutes/index.tswithbun scripts/openapi-routes.ts. The boards test and main's repository-reads test both stay intest/openapi.test.ts. - MCP: this pull adds no MCP tool, so the #5932 split didn't touch it.
- Review point 2: the PUT refusals now list
exists(409).boardFailedcan return it, and I didn't check whetherwriteBoardever produces it, so I added it rather than confirm it never does. - Allowlist: I removed the nine boards entries from
NOT_YET_DESCRIBEDintest/openapi-coverage.test.ts. That test warns when a described route is still on the list. - Not done: review point 1, typed response and panel schemas. The
Routeshape has no way to express them yet, so a PUT body is still top-level fields andpanelsis still an untyped array. That is a follow-up covering every route.
To try it, open /contract/openapi.json on the preview and look for /api/v1/boards and the eight paths under it.
Nine boards rows, one file each, generated index, allowlist entries removed, and a test that fails without them. Preview serves the boards paths in /contract/openapi.json. Docs-only, no handler change, no new dependency; in line with the direction (small, single-purpose, does not touch the frozen files). Next two: (1) give Route a way to type response and panel schemas so PUT body panels is not an untyped array; (2) confirm writeBoard can really return exists (409), else drop that refusal from putApiV1BoardsSlug.ts.
The OpenAPI document now has rows for all nine boards routes, so a harness can list, read, write, delete, query and pin boards from the document alone.
test/openapi.test.tspasses (9 tests, including the new one) andbun x tsc --noEmitis clean. I didn't run the whole check.The rows sit right after
GET /api/v1/migrate/{job}insrc/contract/openapi.ts, in this order:GET /api/v1/boardsGETandPOST /api/v1/boards/pinsGET /api/v1/boards/sourcesPOST /api/v1/boards/queryGET,PUTandDELETE /api/v1/boards/{slug}GET /api/v1/boards/{slug}/panels/{id}All are
auth: true. The handlers only admit a site admin who is a person, and the list and read rows say so."put": I added it to theRoutemethod type here, since #4844 hadn't yet.runQueryreads (source,from,to,filter,groupBy,step,aggregate,column,series). Its refusals arebad_json,too_largeandbad_query, and thebad_querytext names the unknown-source case.the boards routes are describedasserts each new path and method is in the served document, and that the query row mentionsunknown source.I did not change any handler.
I did not describe the response shapes beyond the summary text, as the existing rows don't either. The
PUTboard body is also described only by its top-level fields (title,range,refresh,panels). The panel schema isn't spelled out.Closes #4852