from __future__ import annotations from fastapi import APIRouter, HTTPException from web.api import db router = APIRouter() def _nullify(row: dict, keys: tuple[str, ...]) -> dict: for k in keys: if row.get(k) == "": row[k] = None return row @router.get("/api/tss/tournaments") async def tournaments(status: str | None = None, game_mode: str | None = None, cluster: str | None = None, limit: int = 100) -> dict: clauses: list[str] = [] params: list = [] if status: clauses.append("status = ?"); params.append(status) if game_mode: clauses.append("game_mode = ?"); params.append(game_mode) if cluster: clauses.append("cluster = ?"); params.append(cluster) where = ("WHERE " + " AND ".join(clauses)) if clauses else "" params.append(max(1, min(limit, 500))) rows = await db.query(db.tournaments_path(), f"SELECT * FROM tournaments {where} ORDER BY date_end DESC LIMIT ?", tuple(params)) return {"total": len(rows), "tournaments": rows} async def _matches(tid: int) -> list[dict]: rows = await db.query(db.tournaments_path(), "SELECT * FROM tournament_matches WHERE tournament_id = ? ORDER BY round, position", (tid,)) battles = await db.query(db.tournaments_path(), "SELECT match_id, type_bracket, session_hex FROM tournament_battles WHERE tournament_id = ?", (tid,)) by_match: dict[tuple, list[str]] = {} for b in battles: by_match.setdefault((b["match_id"], b["type_bracket"]), []).append(b["session_hex"]) out = [] for m in rows: _nullify(m, ("round", "position")) m["session_ids"] = by_match.get((m["match_id"], m["type_bracket"]), []) out.append(m) return out @router.get("/api/tss/tournament/{tid}") async def tournament(tid: int) -> dict: meta = await db.query_one(db.tournaments_path(), "SELECT * FROM tournaments WHERE tournament_id = ?", (tid,)) if not meta: raise HTTPException(status_code=404, detail=f"tournament {tid} not found") standings = await db.query(db.tournaments_path(), "SELECT * FROM tournament_standings WHERE tournament_id = ? ORDER BY group_index, rank", (tid,)) return {"tournament": meta, "standings": standings, "matches": await _matches(tid)} @router.get("/api/tss/tournament/{tid}/standings") async def standings(tid: int) -> dict: rows = await db.query(db.tournaments_path(), "SELECT * FROM tournament_standings WHERE tournament_id = ? ORDER BY group_index, rank", (tid,)) return {"tournament_id": tid, "standings": rows} @router.get("/api/tss/tournament/{tid}/matches") async def tournament_matches(tid: int) -> dict: rows = await _matches(tid) return {"tournament_id": tid, "total": len(rows), "matches": rows}