The committed openapi.json bootstraps the Kong gateway and is what clients would be generated from, but two v1 response contracts in it do not match what the app actually returns. Both are route-declaration gaps, not spec-generation bugs — the spec faithfully reports what FastAPI is told.
Surfaced by Codex review on #115.
1. 422 body shape
app/core/errors.py installs a RequestValidationError handler returning the Range42 envelope:
{"error": "...", "message": "...", "code": "...", "details": [], "trace_id": "...", "timestamp": "..."}
…but every v1 operation still advertises FastAPI's default HTTPValidationError ({"detail": [...]}). Generated clients will deserialize validation failures with the wrong shape. Affects all v1 routes, not just POST /v1/projects/.
Fix: a shared responses={422: {"model": <envelope model>}} default, ideally set once at router level rather than per route.
2. SSE stream documented as JSON
GET /v1/deployments/{deployment_id}/events returns EventSourceResponse (app/routes/v1/deployments/events.py), so successful responses are text/event-stream. The spec advertises application/json, so a consumer generated from it will await a JSON body instead of opening a stream.
Fix: response_class=EventSourceResponse and/or an explicit text/event-stream response declaration.
Notes
Both were invisible until #115 regenerated the spec, because the committed file had rotted back to the pre-v1 API (84 paths, zero /v1). Regenerating after this lands is required for the fix to reach Kong — see the drift-guard issue.
The committed
openapi.jsonbootstraps the Kong gateway and is what clients would be generated from, but two v1 response contracts in it do not match what the app actually returns. Both are route-declaration gaps, not spec-generation bugs — the spec faithfully reports what FastAPI is told.Surfaced by Codex review on #115.
1. 422 body shape
app/core/errors.pyinstalls aRequestValidationErrorhandler returning the Range42 envelope:{"error": "...", "message": "...", "code": "...", "details": [], "trace_id": "...", "timestamp": "..."}…but every v1 operation still advertises FastAPI's default
HTTPValidationError({"detail": [...]}). Generated clients will deserialize validation failures with the wrong shape. Affects all v1 routes, not justPOST /v1/projects/.Fix: a shared
responses={422: {"model": <envelope model>}}default, ideally set once at router level rather than per route.2. SSE stream documented as JSON
GET /v1/deployments/{deployment_id}/eventsreturnsEventSourceResponse(app/routes/v1/deployments/events.py), so successful responses aretext/event-stream. The spec advertisesapplication/json, so a consumer generated from it will await a JSON body instead of opening a stream.Fix:
response_class=EventSourceResponseand/or an explicittext/event-streamresponse declaration.Notes
Both were invisible until #115 regenerated the spec, because the committed file had rotted back to the pre-v1 API (84 paths, zero
/v1). Regenerating after this lands is required for the fix to reach Kong — see the drift-guard issue.