feat(game): canonical gameId in POST /api/v1/admin/init
Engine no longer mints its own game UUID. The orchestrator (backend)
generates the game UUID at game-create time and passes it in the
admin/init request body as the required `gameId` field, so the value
that names the engine container and host bind-mount directory also
ends up inside the engine's state.json.
The engine rejects the zero UUID with 400 and any init that conflicts
with an existing state.json with 409 (a second init on the same gameId
is also a conflict; full idempotency is not part of the contract).
Updates rest.InitRequest, openapi.yaml (schema + 409 response),
controller.GenerateGame/NewGame/buildGameOnMap signatures, the engine
HTTP handler/executor, the backend runtime worker, and the relevant
unit and contract tests. Documentation in game/README.md,
docs/ARCHITECTURE.md, backend/README.md, and backend/docs/{runtime,flows}.md
is updated in the same patch.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+19
-1
@@ -43,7 +43,7 @@ described below. Endpoints split into two route classes:
|
||||
|
||||
| Class | Path | Caller | Purpose |
|
||||
| --- | --- | --- | --- |
|
||||
| Admin (GM-only) | `POST /api/v1/admin/init` | `Game Master` | Initialise the engine with the race roster. |
|
||||
| Admin (GM-only) | `POST /api/v1/admin/init` | `Game Master` | Initialise the engine with a canonical `gameId` and the race roster. |
|
||||
| Admin (GM-only) | `GET /api/v1/admin/status` | `Game Master` | Read the full game state. |
|
||||
| Admin (GM-only) | `PUT /api/v1/admin/turn` | `Game Master` | Generate the next turn. |
|
||||
| Admin (GM-only) | `POST /api/v1/admin/race/banish` | `Game Master` | Deactivate a race after a permanent platform removal. |
|
||||
@@ -65,6 +65,24 @@ Documented in [`openapi.yaml`](openapi.yaml). When the engine has not been
|
||||
initialised through `POST /api/v1/admin/init`, game endpoints respond
|
||||
`501 Not Implemented` to make the uninitialised state unambiguous.
|
||||
|
||||
### `POST /api/v1/admin/init`
|
||||
|
||||
The canonical game identity is owned by the orchestrator (`Game Master`),
|
||||
not by the engine. The request body is `{ "gameId": "<uuid>", "races": [...] }`
|
||||
where:
|
||||
|
||||
- `gameId` is a non-zero UUID generated by the orchestrator before the
|
||||
engine container is launched. The same value names the engine's host
|
||||
storage directory and is persisted into `state.json`. The engine
|
||||
rejects the zero UUID with `400 Bad Request` and any value that
|
||||
conflicts with an existing `state.json` on disk with
|
||||
`409 Conflict`. A second `init` on the same `gameId` is also
|
||||
rejected with `409`; idempotency is not part of the contract.
|
||||
- `races` is the race roster; minimum 10 entries.
|
||||
|
||||
On success the engine responds `201 Created` with a `StateResponse`
|
||||
whose `id` echoes the supplied `gameId`.
|
||||
|
||||
### `StateResponse.finished`
|
||||
|
||||
`StateResponse` (returned by `GET /api/v1/admin/status` and
|
||||
|
||||
Reference in New Issue
Block a user