feat(api): GET /api/events endpoint + OpenAPI

Latest game events, newest first; auto-initializes like the other reads.
?limit= defaults to 50 (cap 200), non-integer/out-of-range → 400. OpenAPI
spec gains the path + Event schema (14 -> 15 paths).
This commit is contained in:
2026-09-29 02:45:38 +00:00
parent 8d678d73ce
commit 21abf8768f
3 changed files with 83 additions and 0 deletions
+17
View File
@@ -6,6 +6,7 @@ describe('OpenAPI spec', () => {
it('documents every public endpoint', () => {
expect(Object.keys(openApiSpec.paths).sort()).toEqual([
'/api/crew',
'/api/events',
'/api/explore',
'/api/jump',
'/api/missions',
@@ -77,6 +78,22 @@ describe('OpenAPI spec', () => {
}
});
it('describes GET /api/events → Event[] with a limit query param and a 400 error response', () => {
const events = openApiSpec.paths['/api/events'].get.responses[200].content['application/json'].schema;
expect(events.type).toBe('array');
expect((events.items as { $ref: string }).$ref).toBe('#/components/schemas/Event');
const props = openApiSpec.components.schemas.Event.properties;
expect(Object.keys(props)).toEqual(['id', 'turn', 'type', 'message', 'createdAt']);
expect((props.type as { enum: string[] }).enum).toEqual(['new_game', 'jump', 'explore', 'research', 'upgrade', 'expand', 'build', 'mission']);
const get = openApiSpec.paths['/api/events'].get;
const limit = (get.parameters ?? []).find((p) => p.name === 'limit');
expect(limit?.in).toBe('query');
expect(limit?.required).toBe(false);
expect(get.responses['400'].content['application/json'].schema.$ref).toBe('#/components/schemas/Error');
});
it('describes /api/crew as an array of CrewMember and crewFound on ExploreResult', () => {
const crew = openApiSpec.paths['/api/crew'].get.responses[200].content['application/json'].schema;
expect(crew.type).toBe('array');