feat: NCS-37 Quarkus integration (#35)
Reviewed-on: #35 Reviewed-by: Leon Hermann <lq@blackhole.local>
This commit is contained in:
@@ -0,0 +1,771 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: NowChess Board API
|
||||
description: |
|
||||
REST API for the NowChess application. Designed to feel familiar to users
|
||||
of the [lichess API](https://lichess.org/api).
|
||||
|
||||
## Authentication
|
||||
Most endpoints require a Bearer token:
|
||||
```
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
Authentication is reserved for future implementation — endpoints are currently
|
||||
open unless noted otherwise.
|
||||
|
||||
## Move notation
|
||||
Moves are expressed in **UCI notation**: `{from}{to}[promotion]`
|
||||
- Normal move: `e2e4`
|
||||
- Capture: `d5e6`
|
||||
- Promotion: `e7e8q` (q=queen, r=rook, b=bishop, n=knight)
|
||||
- Castling: `e1g1` (kingside white), `e1c1` (queenside white)
|
||||
|
||||
## Streaming
|
||||
Endpoints that support streaming return **NDJSON** (newline-delimited JSON).
|
||||
Request them with:
|
||||
```
|
||||
Accept: application/x-ndjson
|
||||
```
|
||||
Each line of the response is a complete JSON object. Empty lines are
|
||||
keep-alive heartbeats.
|
||||
|
||||
## Rate limiting
|
||||
Requests that exceed the rate limit receive `429 Too Many Requests`.
|
||||
Honour the `Retry-After` response header and wait before retrying.
|
||||
version: 1.0.0
|
||||
contact:
|
||||
name: NowChess
|
||||
license:
|
||||
name: MIT
|
||||
|
||||
servers:
|
||||
- url: http://localhost:8080
|
||||
description: Local development server
|
||||
|
||||
tags:
|
||||
- name: game
|
||||
description: Create and manage chess games
|
||||
- name: move
|
||||
description: Make moves and navigate game history
|
||||
- name: draw
|
||||
description: Draw offers and claims
|
||||
- name: import
|
||||
description: Load a game from FEN or PGN
|
||||
- name: export
|
||||
description: Export a game as FEN or PGN
|
||||
|
||||
paths:
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Game lifecycle
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
/api/board/game:
|
||||
post:
|
||||
operationId: createGame
|
||||
tags: [game]
|
||||
summary: Create a new game
|
||||
description: |
|
||||
Creates a new chess game starting from the initial position.
|
||||
Returns the full game state including the generated `gameId`.
|
||||
security:
|
||||
- bearerAuth: []
|
||||
requestBody:
|
||||
required: false
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/CreateGameRequest'
|
||||
responses:
|
||||
'201':
|
||||
description: Game created
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GameFull'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'429':
|
||||
$ref: '#/components/responses/TooManyRequests'
|
||||
|
||||
/api/board/game/{gameId}:
|
||||
get:
|
||||
operationId: getGame
|
||||
tags: [game]
|
||||
summary: Get game state
|
||||
description: Returns the full current state of a game.
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/gameId'
|
||||
responses:
|
||||
'200':
|
||||
description: Current game state
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GameFull'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'429':
|
||||
$ref: '#/components/responses/TooManyRequests'
|
||||
|
||||
/api/board/game/{gameId}/stream:
|
||||
get:
|
||||
operationId: streamGame
|
||||
tags: [game]
|
||||
summary: Stream game events
|
||||
description: |
|
||||
Opens a persistent NDJSON stream for a game. The first object sent is
|
||||
a `gameFull` event containing the complete game state. Subsequent
|
||||
objects are `gameState` events sent whenever the game changes (move
|
||||
made, draw offered, game over, etc.).
|
||||
|
||||
Empty lines are heartbeats to keep the connection alive.
|
||||
|
||||
Connect with:
|
||||
```
|
||||
Accept: application/x-ndjson
|
||||
```
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/gameId'
|
||||
responses:
|
||||
'200':
|
||||
description: NDJSON event stream
|
||||
content:
|
||||
application/x-ndjson:
|
||||
schema:
|
||||
oneOf:
|
||||
- $ref: '#/components/schemas/GameFullEvent'
|
||||
- $ref: '#/components/schemas/GameStateEvent'
|
||||
- $ref: '#/components/schemas/ErrorEvent'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'429':
|
||||
$ref: '#/components/responses/TooManyRequests'
|
||||
|
||||
/api/board/game/{gameId}/resign:
|
||||
post:
|
||||
operationId: resignGame
|
||||
tags: [game]
|
||||
summary: Resign the game
|
||||
description: The active player resigns. The game ends immediately.
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/gameId'
|
||||
responses:
|
||||
'200':
|
||||
description: Resignation accepted
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/OkResponse'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'429':
|
||||
$ref: '#/components/responses/TooManyRequests'
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Move-making
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
/api/board/game/{gameId}/move/{uci}:
|
||||
post:
|
||||
operationId: makeMove
|
||||
tags: [move]
|
||||
summary: Make a move
|
||||
description: |
|
||||
Submit a move in UCI notation. The move must be legal for the side
|
||||
currently to move.
|
||||
|
||||
For promotion moves include the target piece as the fifth character:
|
||||
`e7e8q`, `a2a1r`, etc. Promotion moves without the fifth character
|
||||
are rejected with `400 INVALID_MOVE`.
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/gameId'
|
||||
- name: uci
|
||||
in: path
|
||||
required: true
|
||||
description: Move in UCI notation (e.g. `e2e4`, `e7e8q`)
|
||||
schema:
|
||||
type: string
|
||||
pattern: '^[a-h][1-8][a-h][1-8][qrbn]?$'
|
||||
example: e2e4
|
||||
responses:
|
||||
'200':
|
||||
description: Move applied — returns updated game state
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GameState'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'429':
|
||||
$ref: '#/components/responses/TooManyRequests'
|
||||
|
||||
/api/board/game/{gameId}/moves:
|
||||
get:
|
||||
operationId: getLegalMoves
|
||||
tags: [move]
|
||||
summary: Get legal moves
|
||||
description: |
|
||||
Returns all legal moves for the side currently to move.
|
||||
Optionally filter to moves originating from a single square.
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/gameId'
|
||||
- name: square
|
||||
in: query
|
||||
required: false
|
||||
description: Filter to moves from this square (e.g. `e2`)
|
||||
schema:
|
||||
type: string
|
||||
pattern: '^[a-h][1-8]$'
|
||||
example: e2
|
||||
responses:
|
||||
'200':
|
||||
description: List of legal moves
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/LegalMovesResponse'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'429':
|
||||
$ref: '#/components/responses/TooManyRequests'
|
||||
|
||||
/api/board/game/{gameId}/undo:
|
||||
post:
|
||||
operationId: undoMove
|
||||
tags: [move]
|
||||
summary: Undo the last move
|
||||
description: Reverts the most recent move. Returns the updated game state.
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/gameId'
|
||||
responses:
|
||||
'200':
|
||||
description: Move undone
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GameState'
|
||||
'400':
|
||||
description: No moves to undo
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ApiError'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'429':
|
||||
$ref: '#/components/responses/TooManyRequests'
|
||||
|
||||
/api/board/game/{gameId}/redo:
|
||||
post:
|
||||
operationId: redoMove
|
||||
tags: [move]
|
||||
summary: Redo a previously undone move
|
||||
description: Re-applies the next move in the undo stack. Returns the updated game state.
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/gameId'
|
||||
responses:
|
||||
'200':
|
||||
description: Move redone
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GameState'
|
||||
'400':
|
||||
description: No moves to redo
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ApiError'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'429':
|
||||
$ref: '#/components/responses/TooManyRequests'
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Draw handling
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
/api/board/game/{gameId}/draw/{action}:
|
||||
post:
|
||||
operationId: drawAction
|
||||
tags: [draw]
|
||||
summary: Offer, accept, decline, or claim a draw
|
||||
description: |
|
||||
Perform a draw-related action:
|
||||
|
||||
| Action | Description |
|
||||
|-----------|-------------|
|
||||
| `offer` | Offer a draw to the opponent |
|
||||
| `accept` | Accept the opponent's draw offer |
|
||||
| `decline` | Decline the opponent's draw offer |
|
||||
| `claim` | Claim a draw under the fifty-move rule (only valid when `status` is `fiftyMoveAvailable`) |
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/gameId'
|
||||
- name: action
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
enum: [offer, accept, decline, claim]
|
||||
responses:
|
||||
'200':
|
||||
description: Action accepted
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/OkResponse'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'429':
|
||||
$ref: '#/components/responses/TooManyRequests'
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Import
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
/api/board/game/import/fen:
|
||||
post:
|
||||
operationId: importFen
|
||||
tags: [import]
|
||||
summary: Load a position from FEN
|
||||
description: |
|
||||
Creates a new game from a FEN string. The game starts at the position
|
||||
described by the FEN; move history prior to that position is not
|
||||
available.
|
||||
security:
|
||||
- bearerAuth: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ImportFenRequest'
|
||||
responses:
|
||||
'201':
|
||||
description: Game created from FEN
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GameFull'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'429':
|
||||
$ref: '#/components/responses/TooManyRequests'
|
||||
|
||||
/api/board/game/import/pgn:
|
||||
post:
|
||||
operationId: importPgn
|
||||
tags: [import]
|
||||
summary: Load a game from PGN
|
||||
description: |
|
||||
Creates a new game by replaying all moves in a PGN string. The game
|
||||
starts at the position after the final move in the PGN; undo is
|
||||
available for every replayed move.
|
||||
security:
|
||||
- bearerAuth: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ImportPgnRequest'
|
||||
responses:
|
||||
'201':
|
||||
description: Game created from PGN
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GameFull'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'429':
|
||||
$ref: '#/components/responses/TooManyRequests'
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Export
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
/api/board/game/{gameId}/export/fen:
|
||||
get:
|
||||
operationId: exportFen
|
||||
tags: [export]
|
||||
summary: Export current position as FEN
|
||||
description: Returns the FEN string representing the current board position.
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/gameId'
|
||||
responses:
|
||||
'200':
|
||||
description: FEN string
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
example: rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'429':
|
||||
$ref: '#/components/responses/TooManyRequests'
|
||||
|
||||
/api/board/game/{gameId}/export/pgn:
|
||||
get:
|
||||
operationId: exportPgn
|
||||
tags: [export]
|
||||
summary: Export game as PGN
|
||||
description: Returns the full PGN for the game including headers and move text.
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/gameId'
|
||||
responses:
|
||||
'200':
|
||||
description: PGN text
|
||||
content:
|
||||
application/x-chess-pgn:
|
||||
schema:
|
||||
type: string
|
||||
example: |
|
||||
[Event "NowChess game"]
|
||||
[White "Player1"]
|
||||
[Black "Player2"]
|
||||
[Result "*"]
|
||||
|
||||
1. e4 e5 2. Nf3 *
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'429':
|
||||
$ref: '#/components/responses/TooManyRequests'
|
||||
|
||||
# =============================================================================
|
||||
# Components
|
||||
# =============================================================================
|
||||
|
||||
components:
|
||||
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
description: 'Personal access token — `Authorization: Bearer <token>`'
|
||||
|
||||
parameters:
|
||||
gameId:
|
||||
name: gameId
|
||||
in: path
|
||||
required: true
|
||||
description: 8-character alphanumeric game ID (e.g. `Qa7FJNk2`)
|
||||
schema:
|
||||
type: string
|
||||
pattern: '^[A-Za-z0-9]{8}$'
|
||||
example: Qa7FJNk2
|
||||
|
||||
responses:
|
||||
BadRequest:
|
||||
description: Invalid input
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ApiError'
|
||||
Unauthorized:
|
||||
description: Missing or invalid authentication token
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ApiError'
|
||||
NotFound:
|
||||
description: Game not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ApiError'
|
||||
TooManyRequests:
|
||||
description: Rate limit exceeded — see `Retry-After` header
|
||||
headers:
|
||||
Retry-After:
|
||||
description: Seconds to wait before retrying
|
||||
schema:
|
||||
type: integer
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ApiError'
|
||||
|
||||
schemas:
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Requests
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
CreateGameRequest:
|
||||
type: object
|
||||
description: Parameters for creating a new game. All fields are optional.
|
||||
properties:
|
||||
white:
|
||||
$ref: '#/components/schemas/PlayerInfo'
|
||||
black:
|
||||
$ref: '#/components/schemas/PlayerInfo'
|
||||
|
||||
ImportFenRequest:
|
||||
type: object
|
||||
required: [fen]
|
||||
properties:
|
||||
fen:
|
||||
type: string
|
||||
description: Complete FEN string (6 fields)
|
||||
example: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
|
||||
white:
|
||||
$ref: '#/components/schemas/PlayerInfo'
|
||||
black:
|
||||
$ref: '#/components/schemas/PlayerInfo'
|
||||
|
||||
ImportPgnRequest:
|
||||
type: object
|
||||
required: [pgn]
|
||||
properties:
|
||||
pgn:
|
||||
type: string
|
||||
description: PGN text (headers and move list)
|
||||
example: "1. e4 e5 2. Nf3 Nc6 *"
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Game state
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
GameFull:
|
||||
type: object
|
||||
description: Complete game information including players and current state.
|
||||
required: [gameId, white, black, state]
|
||||
properties:
|
||||
gameId:
|
||||
type: string
|
||||
description: Unique 8-character game identifier
|
||||
example: Qa7FJNk2
|
||||
white:
|
||||
$ref: '#/components/schemas/PlayerInfo'
|
||||
black:
|
||||
$ref: '#/components/schemas/PlayerInfo'
|
||||
state:
|
||||
$ref: '#/components/schemas/GameState'
|
||||
|
||||
GameState:
|
||||
type: object
|
||||
description: |
|
||||
The current game state. Included in `GameFull` and returned by move
|
||||
endpoints and stream events.
|
||||
required: [fen, pgn, turn, status, moves, undoAvailable, redoAvailable]
|
||||
properties:
|
||||
fen:
|
||||
type: string
|
||||
description: FEN string for the current position
|
||||
example: rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1
|
||||
pgn:
|
||||
type: string
|
||||
description: PGN move text for the full game so far
|
||||
example: "1. e4"
|
||||
turn:
|
||||
type: string
|
||||
enum: [white, black]
|
||||
description: The side to move
|
||||
status:
|
||||
$ref: '#/components/schemas/GameStatus'
|
||||
winner:
|
||||
type: string
|
||||
enum: [white, black]
|
||||
description: Set when `status` is `checkmate` or `resign`
|
||||
nullable: true
|
||||
moves:
|
||||
type: array
|
||||
description: All moves played so far, in UCI notation
|
||||
items:
|
||||
type: string
|
||||
example: [e2e4, e7e5, g1f3]
|
||||
undoAvailable:
|
||||
type: boolean
|
||||
description: Whether `POST /undo` is currently valid
|
||||
redoAvailable:
|
||||
type: boolean
|
||||
description: Whether `POST /redo` is currently valid
|
||||
|
||||
GameStatus:
|
||||
type: string
|
||||
description: |
|
||||
Current game status:
|
||||
|
||||
| Value | Meaning |
|
||||
|-------|---------|
|
||||
| `started` | Game in progress, no special condition |
|
||||
| `check` | Side to move is in check |
|
||||
| `checkmate` | Side to move is checkmated — game over |
|
||||
| `stalemate` | Side to move has no legal moves, not in check — game over (draw) |
|
||||
| `resign` | A player resigned — game over |
|
||||
| `draw` | Draw agreed or claimed — game over |
|
||||
| `drawOffered` | Waiting for the opponent to accept or decline a draw offer |
|
||||
| `fiftyMoveAvailable` | Fifty-move rule threshold reached; active player may claim draw |
|
||||
| `insufficientMaterial` | Neither side has enough pieces to deliver checkmate — game over (draw) |
|
||||
enum:
|
||||
- started
|
||||
- check
|
||||
- checkmate
|
||||
- stalemate
|
||||
- resign
|
||||
- draw
|
||||
- drawOffered
|
||||
- fiftyMoveAvailable
|
||||
- insufficientMaterial
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Moves
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
LegalMovesResponse:
|
||||
type: object
|
||||
required: [moves]
|
||||
properties:
|
||||
moves:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/LegalMove'
|
||||
|
||||
LegalMove:
|
||||
type: object
|
||||
required: [from, to, uci, moveType]
|
||||
properties:
|
||||
from:
|
||||
type: string
|
||||
description: Origin square in algebraic notation
|
||||
example: e2
|
||||
to:
|
||||
type: string
|
||||
description: Destination square in algebraic notation
|
||||
example: e4
|
||||
uci:
|
||||
type: string
|
||||
description: Full move in UCI notation
|
||||
example: e2e4
|
||||
moveType:
|
||||
$ref: '#/components/schemas/MoveType'
|
||||
promotion:
|
||||
type: string
|
||||
enum: [queen, rook, bishop, knight]
|
||||
description: Target piece for promotion moves
|
||||
nullable: true
|
||||
|
||||
MoveType:
|
||||
type: string
|
||||
description: Classification of the move
|
||||
enum:
|
||||
- normal
|
||||
- capture
|
||||
- castleKingside
|
||||
- castleQueenside
|
||||
- enPassant
|
||||
- promotion
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Streaming events
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
GameFullEvent:
|
||||
type: object
|
||||
description: |
|
||||
First event on a game stream. Contains the complete game snapshot.
|
||||
required: [type, game]
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
enum: [gameFull]
|
||||
game:
|
||||
$ref: '#/components/schemas/GameFull'
|
||||
|
||||
GameStateEvent:
|
||||
type: object
|
||||
description: |
|
||||
Emitted on a game stream whenever the game state changes (move played,
|
||||
draw offered, game over, etc.).
|
||||
required: [type, state]
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
enum: [gameState]
|
||||
state:
|
||||
$ref: '#/components/schemas/GameState'
|
||||
|
||||
ErrorEvent:
|
||||
type: object
|
||||
description: Emitted on a game stream when an error occurs.
|
||||
required: [type, error]
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
enum: [error]
|
||||
error:
|
||||
$ref: '#/components/schemas/ApiError'
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Shared types
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
PlayerInfo:
|
||||
type: object
|
||||
required: [id, displayName]
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: Unique player identifier
|
||||
example: player1
|
||||
displayName:
|
||||
type: string
|
||||
description: Human-readable display name
|
||||
example: Alice
|
||||
|
||||
OkResponse:
|
||||
type: object
|
||||
required: [ok]
|
||||
properties:
|
||||
ok:
|
||||
type: boolean
|
||||
enum: [true]
|
||||
|
||||
ApiError:
|
||||
type: object
|
||||
required: [code, message]
|
||||
properties:
|
||||
code:
|
||||
type: string
|
||||
description: Machine-readable error code
|
||||
example: INVALID_MOVE
|
||||
message:
|
||||
type: string
|
||||
description: Human-readable error description
|
||||
example: e2e5 is not a legal move
|
||||
field:
|
||||
type: string
|
||||
description: Request field that caused the error, if applicable
|
||||
example: uci
|
||||
nullable: true
|
||||
Reference in New Issue
Block a user