feat(api): POST /api/turn ticks the queue one turn; an empty queue is a free skip (#44)
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
import { getGameDb } from '@/lib/db/client'
|
||||
import { getWorldState, runTurn } from '@/lib/game/save'
|
||||
|
||||
// The manual tick (spec §3): advance exactly one turn — every ACTIVE task ages by one, tasks
|
||||
// that reach 0 resolve (the 4a resolvers + their mission hooks, 4b), and PENDING successors
|
||||
// auto-start in FIFO order. An empty queue is a FREE SKIP: turn +1 with nothing else changed —
|
||||
// the route never rejects a tick, so the UI's NEXT TURN button is never disabled. No request
|
||||
// body. Returns the same world snapshot GET /api/world returns, composed with the tick's
|
||||
// task array (the snapshot readers do not select the tasks table, so it comes from the TickResult).
|
||||
export async function POST() {
|
||||
try {
|
||||
const db = await getGameDb()
|
||||
const tick = await runTurn(db)
|
||||
return Response.json({ ...(await getWorldState(db)), tasks: tick.tasks })
|
||||
} catch (err) {
|
||||
// No domain errors escape runTurn (4b fails the task instead) — anything reaching here is
|
||||
// a non-domain rethrow, i.e. a real bug: the error-mapping pattern, 500 when no status.
|
||||
const e = err as { status?: number; message: string }
|
||||
return Response.json({ error: e.message }, { status: e.status ?? 500 })
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user