Skip to content

Commit c721a5a

Browse files
CryptoJonesAaron K. Clarkclaude
authored
docs(openapi): fix POST /v1/customer 201 response-shape drift (#317)
Companion to #312 (which fixed the same drift on the GET endpoint). The OpenAPI spec declared the POST 201 body as a bare Customer (`$ref: '#/components/schemas/Customer'`). The controller actually wraps the row in a `{message, customer}` envelope (no `customers` plural alias here — that wart is GET-only). SDK generators reading the spec built clients that expected the bare row and then failed to find the fields at runtime because they live one level deeper inside the envelope. Same client-side breakage; same fix here. Pin the new shape with a test in `tests/api/openapi.test.js` mirroring the GET-endpoint assertion. Co-authored-by: Aaron K. Clark <akclark@thenetwerk.net> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 09e9f5c commit c721a5a

2 files changed

Lines changed: 29 additions & 1 deletion

File tree

app/config/openapi.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,21 @@ const spec = {
694694
// Declare it so SDK generators surface the field
695695
// on the client side.
696696
headers: idempotencyReplayResponseHeader,
697-
content: { 'application/json': { schema: { $ref: '#/components/schemas/Customer' } } },
697+
// Controller wraps the row in {message, customer} —
698+
// same envelope pattern fixed for GET in #312.
699+
// Surface the envelope here so SDK code-gen
700+
// doesn't model the body as a bare Customer.
701+
content: {
702+
'application/json': {
703+
schema: {
704+
type: 'object',
705+
properties: {
706+
message: { type: 'string' },
707+
customer: { $ref: '#/components/schemas/Customer' },
708+
},
709+
},
710+
},
711+
},
698712
},
699713
400: { description: 'Bad request' },
700714
403: { description: 'Missing or invalid authKey' },

tests/api/openapi.test.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,20 @@ describe('OpenAPI spec', () => {
7070
expect(schemas.TimeEntry.properties.teStartedAt).toBeDefined();
7171
});
7272

73+
test('POST /v1/customer 201 declares the {message, customer} envelope', async () => {
74+
// Same envelope-drift fix as the GET endpoint below (#312)
75+
// but for the create path. The controller responds with
76+
// `{message, customer}` on a successful 201; the spec
77+
// previously said the body was a bare Customer, so SDK
78+
// generators built clients that failed to find the row.
79+
const res = await request(app).get('/openapi.json');
80+
const r201 = res.body.paths['/v1/customer'].post.responses['201'];
81+
const schema = r201.content['application/json'].schema;
82+
expect(schema.type).toBe('object');
83+
expect(schema.properties.message).toBeDefined();
84+
expect(schema.properties.customer.$ref).toBe('#/components/schemas/Customer');
85+
});
86+
7387
test('GET /v1/customer/{id} 200 declares the {message, customer, customers} envelope', async () => {
7488
// Pre-#292 the spec said the body was a bare Customer. The
7589
// controller actually returns a `{message, customer, customers}`

0 commit comments

Comments
 (0)