feat: AI-game refinements (GCG, your_turn, admin, metrics)
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 13s
CI / ui (pull_request) Successful in 49s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m7s

Follow-ups on the honest-AI game, same PR:
- GCG export labels the robot seat "AI" instead of its pool name (ExportGCG
  overrides via accounts.IsRobot); the in-app 🤖 is unchanged.
- vs_ai games emit no your_turn (the robot replies instantly, so it would be
  redundant); opponent_moved still advances the UI.
- Admin console shows the AI flag: a 🤖 column in /games and an "AI game" line
  on the game card (GameRow/GameDetailView gain VsAI).
- games_started_total / games_abandoned_total gain a vs_ai attribute; the
  Grafana Game-domain dashboard splits started/abandoned into human and AI
  panels.

Tests: metrics unit (vs_ai split); integration (no your_turn, GCG "AI").
This commit is contained in:
Ilia Denisov
2026-06-15 20:49:49 +02:00
parent aa765a0c06
commit d2a9441287
12 changed files with 166 additions and 41 deletions
+5 -1
View File
@@ -192,6 +192,8 @@ type GameRow struct {
Status string
Players int
UpdatedAt string
// VsAI marks an honest-AI game (rendered as 🤖 in the list's AI column).
VsAI bool
}
// GamesView is the paginated games list, optionally filtered by status.
@@ -214,7 +216,9 @@ type GameDetailView struct {
CreatedAt string
UpdatedAt string
FinishedAt string
Seats []SeatRow
// VsAI marks an honest-AI game (shown as a 🤖 flag in the summary).
VsAI bool
Seats []SeatRow
// HasRobot is true when any seat is a robot, gating the robot-target caption;
// RobotTargetPct is the configured global play-to-win rate, in percent.
HasRobot bool