docs(website): document the OpenAPI path-key normalization

Matches website PR "build(swagger): normalize and sort generated OpenAPI path
keys", which post-processes swagger-autogen's output ahead of the admin router
domain split (API_V2_PLAN.md § Phase 2).

- website-README.md § Regenerating the spec: why trailing slashes are stripped
  (a capability router mounted at /users declaring router.get('/') would document
  /api/v1/admin/users/, a URL no client calls) and why path keys are sorted.
- BACKEND_DESIGN.md § generated artifacts: note that both the route manifest and
  the spec are emitted sorted, so a diff in either is proportional to the change.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-07-27 15:50:01 -05:00
parent 8c46af7e54
commit 31c91fb307
2 changed files with 17 additions and 0 deletions

View File

@@ -367,6 +367,18 @@ cd server
npm run swagger # → server/swagger/swagger-output.json
```
`swagger.js` post-processes the generator's output in two ways before writing it:
- **Trailing slashes are stripped from path keys.** swagger-autogen builds a path by
string-concatenating the mount prefix with the route argument, so a capability router mounted at
`/users` whose collection route is `router.get('/')` would document as `/api/v1/admin/users/`
a URL no client calls, while dropping the one they all do. Express is indifferent (non-strict
routing treats the two as one route), but the published spec is a contract.
- **Path keys are sorted.** The generator emits them in router-traversal order, so moving a route
between files rewrote most of this ~5k-line committed artifact even when the API was provably
unchanged. Sorting keeps the diff proportional to the change. OpenAPI attaches no meaning to path
order, and `scripts/routeManifest.js` already sorts for the same reason.
If the generated spec is missing, the server logs a warning and simply disables `/api/docs` (it does
not crash).