Add preliminary support for multiple card games
CI / Build and push docker image (push) Successful in 3m5s

A game-type registry (server/src/tavolo/games.py) is now the single
source of truth for the games the platform can host; only scopone
scientifico is registered so far. GET /api/game-types exposes it for the
lobby's new game dropdown, and POST /api/games accepts a validated
game_type (default scopone_scientifico) which is carried on the live
GameState and onto each finished Match row (new indexed column,
migration 1_20260916235833_update), so statistics can be scoped per
game: /api/me/matches and /api/leaderboard take an optional game_type
filter and every serialized match includes its game_type.

Game states serialized before this change still load with the default
game type.
This commit is contained in:
2026-09-17 08:26:46 +08:00
parent 876b4abd8b
commit ab4130a4ca
15 changed files with 376 additions and 28 deletions
+15 -2
View File
@@ -22,9 +22,22 @@ pub async fn me() -> Result<Option<User>, String> {
resp.json().await.map(Some).map_err(|e| e.to_string())
}
pub async fn create_game(target_score: i32) -> Result<GameView, String> {
/// Fetch the card games the platform can host (for the creation dropdown).
pub async fn game_types() -> Result<Vec<GameTypeInfo>, String> {
let resp = Request::get("/api/game-types")
.send()
.await
.map_err(|e| e.to_string())?;
if !resp.ok() {
return Err(server_error(resp.status()));
}
let page: GameTypesPage = resp.json().await.map_err(|e| e.to_string())?;
Ok(page.results)
}
pub async fn create_game(game_type: &str, target_score: i32) -> Result<GameView, String> {
let resp = Request::post("/api/games")
.json(&serde_json::json!({ "target_score": target_score }))
.json(&serde_json::json!({ "game_type": game_type, "target_score": target_score }))
.map_err(|e| e.to_string())?
.send()
.await