Context
src/openapi/spec.ts registers 78 routes via registry.registerPath({...}) (@asteasolutions/zod-to-openapi). Every single one sets response-level description fields (e.g. 200: { description: "...", ... }), but none of the 78 calls sets the operation-level summary or description field that RouteConfig supports — the field that becomes each operation's title/summary in the generated openapi.json and in the rendered API browser (https://gittensory.aethereal.dev/api, built from apps/loopover-ui/public/openapi.json via npm run ui:openapi).
Verified directly: grep -c "summary:" src/openapi/spec.ts → 0, across all 78 registry.registerPath( call sites (git show origin/main:src/openapi/spec.ts | grep -c registry.registerPath → 78). Example — /health:
registry.registerPath({
method: "get",
path: "/health",
responses: {
200: { description: "Service health", content: { "application/json": { schema: HealthSchema } } },
},
});
There is no summary: "..." line at all. A human or an "Agent authors" reader (README's own audience table links straight to the API browser) sees a bare GET /health with no operation title in the rendered docs/spec navigation — only the 200-response description hints at what it does, and routes with multiple response codes (e.g. /v1/public/repos/{owner}/{repo}/quality with 200/404/503) have no single top-level description of the operation at all, only per-status-code ones.
test/unit/openapi.test.ts already asserts every path is present in the built spec (expect(spec.paths["/health"]).toBeDefined() etc. for all 78 routes) but does not assert anything about summary/description, so this gap has no regression guard today.
Requirements
- Add a concise, accurate one-line
summary (and/or description where a one-liner isn't enough — see zod-to-openapi's RouteConfig type for both fields) to every one of the 78 registry.registerPath({...}) calls in src/openapi/spec.ts, describing what the operation does (not duplicating a response-level description verbatim — summarize the endpoint's purpose in a sentence).
- Add a regression test to
test/unit/openapi.test.ts (or a new test/unit/openapi-summaries.test.ts) that iterates buildOpenApiSpec().paths and every method within each path, asserting summary (or description) is a non-empty string — so this can't silently regress again as new routes are added.
- Regenerate the committed OpenAPI artifact:
npm run ui:openapi (the ui → openapi drift CI check fails if apps/loopover-ui/public/openapi.json doesn't match).
Deliverables
Test Coverage Requirements
src/openapi/spec.ts is inside coverage.include (src/**, per codecov.yml) — this PR's changed lines (the new summary: fields) must hit 99%+ patch coverage. The new assertion test itself exercises every changed line by construction (it iterates the full built spec), so this should be close to automatic as long as the test is added in the same PR, not a follow-up.
Expected Outcome
Every operation in the generated openapi.json / API browser has a human-readable summary; a new regression test fails loudly if a future route is added without one.
Links & Resources
src/openapi/spec.ts — the file to change
test/unit/openapi.test.ts — existing path-presence test to extend or sit alongside
scripts/write-ui-openapi.ts, npm run ui:openapi — regenerates the committed spec
- README.md's "Agent authors" row links directly to the API browser this spec feeds
Context
src/openapi/spec.tsregisters 78 routes viaregistry.registerPath({...})(@asteasolutions/zod-to-openapi). Every single one sets response-leveldescriptionfields (e.g.200: { description: "...", ... }), but none of the 78 calls sets the operation-levelsummaryordescriptionfield thatRouteConfigsupports — the field that becomes each operation's title/summary in the generatedopenapi.jsonand in the rendered API browser (https://gittensory.aethereal.dev/api, built fromapps/loopover-ui/public/openapi.jsonvianpm run ui:openapi).Verified directly:
grep -c "summary:" src/openapi/spec.ts→0, across all 78registry.registerPath(call sites (git show origin/main:src/openapi/spec.ts | grep -c registry.registerPath→78). Example —/health:There is no
summary: "..."line at all. A human or an "Agent authors" reader (README's own audience table links straight to the API browser) sees a bareGET /healthwith no operation title in the rendered docs/spec navigation — only the 200-response description hints at what it does, and routes with multiple response codes (e.g./v1/public/repos/{owner}/{repo}/qualitywith 200/404/503) have no single top-level description of the operation at all, only per-status-code ones.test/unit/openapi.test.tsalready asserts every path is present in the built spec (expect(spec.paths["/health"]).toBeDefined()etc. for all 78 routes) but does not assert anything aboutsummary/description, so this gap has no regression guard today.Requirements
summary(and/ordescriptionwhere a one-liner isn't enough — seezod-to-openapi'sRouteConfigtype for both fields) to every one of the 78registry.registerPath({...})calls insrc/openapi/spec.ts, describing what the operation does (not duplicating a response-level description verbatim — summarize the endpoint's purpose in a sentence).test/unit/openapi.test.ts(or a newtest/unit/openapi-summaries.test.ts) that iteratesbuildOpenApiSpec().pathsand every method within each path, assertingsummary(ordescription) is a non-empty string — so this can't silently regress again as new routes are added.npm run ui:openapi(theui → openapi driftCI check fails ifapps/loopover-ui/public/openapi.jsondoesn't match).Deliverables
summaryadded to all 78registerPathcalls insrc/openapi/spec.tssummaryapps/loopover-ui/public/openapi.jsonregenerated vianpm run ui:openapiand committedTest Coverage Requirements
src/openapi/spec.tsis insidecoverage.include(src/**, percodecov.yml) — this PR's changed lines (the newsummary:fields) must hit 99%+ patch coverage. The new assertion test itself exercises every changed line by construction (it iterates the full built spec), so this should be close to automatic as long as the test is added in the same PR, not a follow-up.Expected Outcome
Every operation in the generated
openapi.json/ API browser has a human-readable summary; a new regression test fails loudly if a future route is added without one.Links & Resources
src/openapi/spec.ts— the file to changetest/unit/openapi.test.ts— existing path-presence test to extend or sit alongsidescripts/write-ui-openapi.ts,npm run ui:openapi— regenerates the committed spec