fix(game): #59 — per-command rejection on PUT /api/v1/order
Validation of a player's order now applies every command against a transient game-state snapshot and records the per-command outcome (cmdApplied, cmdErrorCode) in each command's meta. The order is persisted even when some commands are rejected, and the response is 202 + UserGamesOrder so clients can surface the partial failure without the chain collapsing into "downstream service is unavailable". Pkg/error consts are reshelved onto three explicit ranges with a package doc and helpers (IsInternalCode/IsInputCode/IsGameStateCode): 1xxx internal/server (500/501), 2xxx structural input (400), 3xxx game-state per-command rejection (400 when escaping HTTP, otherwise recorded as cmdErrorCode). Two pre-existing typos fixed mechanically (ErrBeakGroupNumberNotEnough -> ErrBreakGroupNumberNotEnough, ErrRaceExinct -> ErrRaceExtinct) along with all callsites. Engine errorResponse maps *GenericError by shelf rather than mapping everything to 500. The Quit-not-last structural check in Controller.ValidateOrder is preserved and its type assertion fixed (was a value assertion against a pointer-typed command, so the check silently never fired). Backend, gateway and UI are unchanged — they were already correct on the 202 path; only the engine collapsing per-command rejection into 500 was needed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -648,6 +648,20 @@ validity and ordering of in-game decisions. Gateway needs to know
|
||||
the typed FB shape only to transcode the wire format; the per-command
|
||||
semantics live in the engine.
|
||||
|
||||
For `user.games.order` specifically, the engine validates every
|
||||
command in the submitted order against a transient view of the
|
||||
current game state and reports the outcome per command on each
|
||||
command's meta (`cmdApplied`, `cmdErrorCode`) inside the same
|
||||
`UserGamesOrder` body. The order is persisted with these per-command
|
||||
verdicts even when some commands are rejected — for example, deleting
|
||||
the "create ship class X" command from an order that still contains
|
||||
"produce ship X" makes the second command fail with a per-command
|
||||
`cmdErrorCode` for "entity does not exist", while the rest of the
|
||||
order remains stored and the response is still a `202 Accepted`. A
|
||||
`400` is returned only for order-level structural rejections
|
||||
(`quit` not the last command, unrecognized command type, malformed
|
||||
input); `500` only for genuine engine-internal failures.
|
||||
|
||||
### 6.3 Turn cutoff and auto-pause
|
||||
|
||||
A running game continuously alternates between a command-accepting
|
||||
|
||||
Reference in New Issue
Block a user