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
+28
View File
@@ -0,0 +1,28 @@
import { getGameDb } from '@/lib/db/client'
import { ShipError, buildSystem } from '@/lib/game/ship'
// Build an unbuilt ship system type at base values. Body: { "type": string }.
// Costs inventory items + a turn; returns the fresh ship state.
export async function POST(req: Request) {
let body: unknown
try {
body = await req.json()
} catch {
return Response.json({ error: 'Invalid JSON body' }, { status: 400 })
}
const type = (body as { type?: unknown }).type
if (typeof type !== 'string' || type.length === 0) {
return Response.json({ error: 'type must be a non-empty string' }, { status: 400 })
}
try {
const db = await getGameDb()
return Response.json(await buildSystem(db, type))
} catch (err) {
if (err instanceof ShipError) {
return Response.json({ error: err.message }, { status: err.status })
}
throw err
}
}
+28
View File
@@ -0,0 +1,28 @@
import { getGameDb } from '@/lib/db/client'
import { ShipError, expandSystem } from '@/lib/game/ship'
// Raise a built ship system's capacity by one (capped at max capacity). Body: { "systemId": number }.
// Costs inventory items + a turn; returns the fresh ship state.
export async function POST(req: Request) {
let body: unknown
try {
body = await req.json()
} catch {
return Response.json({ error: 'Invalid JSON body' }, { status: 400 })
}
const systemId = (body as { systemId?: unknown }).systemId
if (typeof systemId !== 'number' || !Number.isInteger(systemId)) {
return Response.json({ error: 'systemId must be an integer' }, { status: 400 })
}
try {
const db = await getGameDb()
return Response.json(await expandSystem(db, systemId))
} catch (err) {
if (err instanceof ShipError) {
return Response.json({ error: err.message }, { status: err.status })
}
throw err
}
}
+8
View File
@@ -0,0 +1,8 @@
import { getGameDb } from '@/lib/db/client'
import { getShipState } from '@/lib/game/ship'
// The ship's systems + cargo hold + turn; auto-initializes on first hit.
export async function GET() {
const db = await getGameDb()
return Response.json(await getShipState(db))
}
+28
View File
@@ -0,0 +1,28 @@
import { getGameDb } from '@/lib/db/client'
import { ShipError, upgradeSystem } from '@/lib/game/ship'
// Level up a built ship system by one (capped at max level). Body: { "systemId": number }.
// Costs inventory items + a turn; returns the fresh ship state.
export async function POST(req: Request) {
let body: unknown
try {
body = await req.json()
} catch {
return Response.json({ error: 'Invalid JSON body' }, { status: 400 })
}
const systemId = (body as { systemId?: unknown }).systemId
if (typeof systemId !== 'number' || !Number.isInteger(systemId)) {
return Response.json({ error: 'systemId must be an integer' }, { status: 400 })
}
try {
const db = await getGameDb()
return Response.json(await upgradeSystem(db, systemId))
} catch (err) {
if (err instanceof ShipError) {
return Response.json({ error: err.message }, { status: err.status })
}
throw err
}
}