diff --git a/app/config/openapi.js b/app/config/openapi.js index 4ecd5be..b2a8679 100644 --- a/app/config/openapi.js +++ b/app/config/openapi.js @@ -870,7 +870,34 @@ const spec = { { name: 'to', in: 'query', schema: { type: 'string', format: 'date-time' } }, { name: 'limit', in: 'query', schema: { type: 'integer', default: 100, maximum: 500 } }, ], - responses: { 200: { description: 'OK' }, 400: { description: 'Invalid company id' }, 403: { description: 'Auth failure' } }, + responses: { + 200: { + description: 'OK — paginated time-entry list', + // Controller emits the standard pagination envelope — + // same shape every list endpoint uses. Mirrors the + // customer/bycompany declaration from #340 so SDK + // code-gen models the Link-header-paired response. + content: { + 'application/json': { + schema: { + type: 'object', + properties: { + message: { type: 'string' }, + count: { type: 'integer' }, + limit: { type: 'integer' }, + offset: { type: 'integer' }, + timeEntries: { + type: 'array', + items: { $ref: '#/components/schemas/TimeEntry' }, + }, + }, + }, + }, + }, + }, + 400: { description: 'Invalid company id' }, + 403: { description: 'Auth failure' }, + }, }, }, '/v1/worker': { diff --git a/tests/api/openapi.test.js b/tests/api/openapi.test.js index 53141f8..3841705 100644 --- a/tests/api/openapi.test.js +++ b/tests/api/openapi.test.js @@ -92,6 +92,22 @@ describe('OpenAPI spec', () => { expect(err.required).toEqual(['message']); }); + test('GET /v1/timeentry/bycompany/{id} 200 declares the {message, count, limit, offset, timeEntries} envelope', async () => { + // Parallel to the customer/bycompany declaration in #340. + // Pre-fix the spec said only `description: 'OK'`; SDK code-gen + // had no way to model the pagination envelope. + const res = await request(app).get('/openapi.json'); + const r200 = res.body.paths['/v1/timeentry/bycompany/{id}'].get.responses['200']; + const schema = r200.content['application/json'].schema; + expect(schema.type).toBe('object'); + expect(schema.properties.message.type).toBe('string'); + expect(schema.properties.count.type).toBe('integer'); + expect(schema.properties.limit.type).toBe('integer'); + expect(schema.properties.offset.type).toBe('integer'); + expect(schema.properties.timeEntries.type).toBe('array'); + expect(schema.properties.timeEntries.items.$ref).toBe('#/components/schemas/TimeEntry'); + }); + test('GET /v1/customer/bycompany/{id} 200 declares the {message, count, limit, offset, customers} envelope', async () => { // Paginated list endpoint — controller emits the same envelope // every list endpoint uses. Pre-fix the spec said only