diff --git a/public/specs/service-leaderboard/openapi.json b/public/specs/service-leaderboard/openapi.json index 651cbe0..18c87c1 100644 --- a/public/specs/service-leaderboard/openapi.json +++ b/public/specs/service-leaderboard/openapi.json @@ -2,6 +2,41 @@ "openapi" : "3.1.0", "components" : { "schemas" : { + "BoardSummary" : { + "description" : "One board in its active season.", + "type" : "object", + "required" : [ "boardId", "seasonId" ], + "properties" : { + "boardId" : { + "type" : "string", + "description" : "The board.", + "examples" : [ "bedwars-solo" ] + }, + "seasonId" : { + "type" : "string", + "description" : "The board's active season." + }, + "players" : { + "type" : "integer", + "format" : "int32", + "description" : "How many players have an entry in that season." + } + } + }, + "BoardsResponse" : { + "description" : "Every board with entries in its active season.", + "type" : "object", + "required" : [ "boards" ], + "properties" : { + "boards" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/BoardSummary" + }, + "description" : "Sorted by board id." + } + } + }, "LeaderboardEntry" : { "description" : "One row of a board.", "type" : "object", @@ -28,6 +63,46 @@ }, "required" : [ "playerId", "lastUpdated" ] }, + "PlayerBoard" : { + "description" : "One player's standing on one board.", + "type" : "object", + "required" : [ "boardId", "seasonId" ], + "properties" : { + "boardId" : { + "type" : "string", + "description" : "The board.", + "examples" : [ "bedwars-solo" ] + }, + "seasonId" : { + "type" : "string", + "description" : "The season this standing belongs to." + }, + "rank" : { + "type" : "integer", + "format" : "int32", + "description" : "1-indexed rank; players with the same score share one." + }, + "score" : { + "type" : "integer", + "format" : "int64", + "description" : "The player's score." + } + } + }, + "PlayerBoardsResponse" : { + "description" : "Every board one player is on.", + "type" : "object", + "required" : [ "boards" ], + "properties" : { + "boards" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/PlayerBoard" + }, + "description" : "Sorted by board id. Empty when the player never scored." + } + } + }, "PlayerRankResponse" : { "description" : "One player's standing on a board.", "type" : "object", @@ -198,13 +273,68 @@ "info" : { "description" : "Persistent player rankings. A board is a (boardId, seasonId) pair: the board id is stable per gamemode (`bedwars.solos`), the season rolls over on ops's schedule and the scores from the closed season are archived rather than deleted.\n\nScores are submitted by whoever owns the result — service-match after a rated match, not the gamemode — and read by anything that renders a board. A submission says how it combines with what is stored: overwrite, add, or keep the better of the two.\n\nA retried submission is the hazard this API is shaped around: a double-counted score is visible to players and stays wrong for a season. Send an idempotency key and a retry costs nothing.", "title" : "Leaderboard API", - "version" : "v2.0.0" + "version" : "v2.3.0" }, "tags" : [ { "name" : "Leaderboards", "description" : "Persistent player rankings per board and season." } ], "paths" : { + "/v1/leaderboards/boards" : { + "get" : { + "summary" : "List the boards", + "description" : "Every board with at least one entry in its active season, with how many players it ranks there. Sorted by board id.", + "tags" : [ "Leaderboards" ], + "responses" : { + "200" : { + "description" : "The boards.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/BoardsResponse" + } + } + } + } + } + } + }, + "/v1/leaderboards/players/{playerId}" : { + "get" : { + "summary" : "Read every board one player is on", + "description" : "Rank and score per board, each in that board's active season unless `seasonId` pins one season for all of them. A player who never scored reads as an empty list, not a 404. Sorted by board id.", + "tags" : [ "Leaderboards" ], + "parameters" : [ { + "name" : "playerId", + "in" : "path", + "required" : true, + "schema" : { + "type" : [ "string", "null" ] + } + }, { + "name" : "seasonId", + "in" : "query", + "schema" : { + "type" : [ "string", "null" ] + } + } ], + "responses" : { + "200" : { + "description" : "The player's standings.", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/PlayerBoardsResponse" + } + } + } + }, + "400" : { + "description" : "`playerId` is not a UUID." + } + } + } + }, "/v1/leaderboards/{boardId}/players/{playerId}" : { "get" : { "summary" : "Read one player's standing",