api+openapi: GET /api/ship + POST upgrade/expand/build with 400/404/409/422 mapping

This commit is contained in:
2026-09-28 23:38:11 +00:00
parent 5fe306d64d
commit fce27ff6ca
6 changed files with 354 additions and 0 deletions
+237
View File
@@ -186,6 +186,198 @@ export const openApiSpec = {
},
},
},
'/api/ship': {
get: {
summary: 'Ship state',
description:
"The ship's systems (built flag derived from level), the cargo hold and the turn counter. The starting ship is seeded on new game — core types built at base values, the rest unbuilt until a build action. Auto-initializes a new game when no save exists yet.",
operationId: 'getShip',
responses: {
200: {
description: 'Current ship state',
content: {
'application/json': {
schema: { $ref: '#/components/schemas/ShipState' },
},
},
},
},
},
},
'/api/ship/upgrade': {
post: {
summary: 'Upgrade a ship system',
description:
"Level up a built ship system by one (capped at max level). Costs `level` units of any resource, consumed from the oldest cargo row first, plus a turn. Returns the fresh ship state.",
operationId: 'upgradeShipSystem',
requestBody: {
required: true,
content: {
'application/json': {
schema: { $ref: '#/components/schemas/UpgradeRequest' },
},
},
},
responses: {
200: {
description: 'Fresh ship state after the upgrade',
content: {
'application/json': {
schema: { $ref: '#/components/schemas/ShipState' },
},
},
},
400: {
description: 'Malformed body or non-integer systemId',
content: {
'application/json': {
schema: { $ref: '#/components/schemas/Error' },
},
},
},
404: {
description: 'Unknown ship system id',
content: {
'application/json': {
schema: { $ref: '#/components/schemas/Error' },
},
},
},
409: {
description: 'System is not built or already at max level',
content: {
'application/json': {
schema: { $ref: '#/components/schemas/Error' },
},
},
},
422: {
description: 'Not enough resources in the cargo hold for the cost',
content: {
'application/json': {
schema: { $ref: '#/components/schemas/Error' },
},
},
},
},
},
},
'/api/ship/expand': {
post: {
summary: 'Expand a ship system',
description:
"Raise a built ship system's capacity by one (capped at max capacity). Costs `capacity` units of any resource, consumed from the oldest cargo row first, plus a turn. Returns the fresh ship state.",
operationId: 'expandShipSystem',
requestBody: {
required: true,
content: {
'application/json': {
schema: { $ref: '#/components/schemas/ExpandRequest' },
},
},
},
responses: {
200: {
description: 'Fresh ship state after the expansion',
content: {
'application/json': {
schema: { $ref: '#/components/schemas/ShipState' },
},
},
},
400: {
description: 'Malformed body or non-integer systemId',
content: {
'application/json': {
schema: { $ref: '#/components/schemas/Error' },
},
},
},
404: {
description: 'Unknown ship system id',
content: {
'application/json': {
schema: { $ref: '#/components/schemas/Error' },
},
},
},
409: {
description: 'System is not built or already at max capacity',
content: {
'application/json': {
schema: { $ref: '#/components/schemas/Error' },
},
},
},
422: {
description: 'Not enough resources in the cargo hold for the cost',
content: {
'application/json': {
schema: { $ref: '#/components/schemas/Error' },
},
},
},
},
},
},
'/api/ship/build': {
post: {
summary: 'Build a ship system',
description:
'Build an unbuilt ship system type at base values. Costs a flat amount of parts, consumed from the oldest cargo row first, plus a turn. Returns the fresh ship state.',
operationId: 'buildShipSystem',
requestBody: {
required: true,
content: {
'application/json': {
schema: { $ref: '#/components/schemas/BuildRequest' },
},
},
},
responses: {
200: {
description: 'Fresh ship state after the build',
content: {
'application/json': {
schema: { $ref: '#/components/schemas/ShipState' },
},
},
},
400: {
description: 'Malformed body or empty type',
content: {
'application/json': {
schema: { $ref: '#/components/schemas/Error' },
},
},
},
404: {
description: 'Unknown ship system type',
content: {
'application/json': {
schema: { $ref: '#/components/schemas/Error' },
},
},
},
409: {
description: 'System is already built',
content: {
'application/json': {
schema: { $ref: '#/components/schemas/Error' },
},
},
},
422: {
description: 'Not enough parts in the cargo hold for the cost',
content: {
'application/json': {
schema: { $ref: '#/components/schemas/Error' },
},
},
},
},
},
},
},
components: {
schemas: {
@@ -275,6 +467,51 @@ export const openApiSpec = {
},
required: ['id', 'name', 'role', 'trait_good', 'trait_bad', 'origin'],
},
ShipSystem: {
type: 'object',
properties: {
id: { type: 'integer' },
type: { type: 'string', description: "System type, e.g. REACTOR or WEAPONS" },
level: { type: 'integer', description: '0 when not built yet' },
capacity: { type: 'integer', description: '0 when not built yet' },
built: { type: 'boolean', description: 'Derived — true when level > 0' },
},
required: ['id', 'type', 'level', 'capacity', 'built'],
},
ShipState: {
type: 'object',
properties: {
systems: {
type: 'array',
description: "The ship's systems in display order",
items: { $ref: '#/components/schemas/ShipSystem' },
},
inventory: { type: 'array', items: { $ref: '#/components/schemas/InventoryItem' } },
turn: { type: 'integer', description: 'Turn counter — one per jump, exploration or ship action' },
},
required: ['systems', 'inventory', 'turn'],
},
UpgradeRequest: {
type: 'object',
properties: {
systemId: { type: 'integer', description: 'ship_systems.id of the built system to level up' },
},
required: ['systemId'],
},
ExpandRequest: {
type: 'object',
properties: {
systemId: { type: 'integer', description: 'ship_systems.id of the built system to expand' },
},
required: ['systemId'],
},
BuildRequest: {
type: 'object',
properties: {
type: { type: 'string', description: "Ship system type to build, e.g. WEAPONS (see ShipSystem.type)" },
},
required: ['type'],
},
SystemState: {
type: 'object',
properties: {