feat: live game tiles on homepage + bot spectating

- GET /v1/games/live returns all active games with both players assigned,
  including current FEN (computed server-side via chess.js)
- LiveGames component on homepage: mini chessboard tiles (160px) that
  auto-refresh every 3s, clickable to join as spectator
- Tournament page: 'Zuschauen' button for non-players on ongoing rounds
  (bot vs bot, human vs human, human vs bot all spectatable)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Michess
2026-04-15 08:03:26 +02:00
parent 86fbdd39ed
commit 0b3228c9d7
6 changed files with 99 additions and 0 deletions

View File

@@ -1,9 +1,28 @@
import type { Game, User } from "@michess/types";
import type { Request, Response } from "express";
import { nanoid } from "nanoid";
import { Chess } from "chess.js";
import GameModel, { activeGames } from "../db/models/game.model.js";
export const getLiveGames = (_req: Request, res: Response) => {
const live = activeGames
.filter(g => g.white?.id && g.black?.id && !g.winner)
.map(g => {
const chess = new Chess();
if (g.pgn) chess.loadPgn(g.pgn);
return {
code: g.code,
white: { name: g.white?.name },
black: { name: g.black?.name },
fen: chess.fen(),
timeControl: g.timeControl,
tournamentCode: g.tournamentCode
};
});
res.status(200).json(live);
};
export const getGames = async (req: Request, res: Response) => {
try {
if (!req.query.id && !req.query.userid) {

View File

@@ -4,6 +4,7 @@ import * as controller from "../controllers/games.controller.js";
const router = Router();
router.get("/live", controller.getLiveGames);
router.route("/").get(controller.getGames).post(controller.createGame);
router.route("/:code").get(controller.getActiveGame);