fertig-classic-games/server/history/recordRoutes.js

67 lines
2.2 KiB
JavaScript

import { Router } from 'express';
import db from '../db/index.js';
import { requireAuth } from '../auth/middleware.js';
import { getGame } from '../multiplayer/gameRegistry.js';
const router = Router();
const RESULTS = new Set(['win', 'loss', 'draw']);
// POST /api/history/single-player
// Body: { slug, score, opponentScores: number[], result }
// Records a finished single-player vs-AI match for the signed-in user.
// AI opponents do not get match_players rows (user_id is a FK to users).
router.post('/single-player', requireAuth, (req, res) => {
const { slug, score, opponentScores, result } = req.body ?? {};
if (typeof slug !== 'string' || !slug) {
return res.status(400).json({ error: 'Missing slug.' });
}
const def = getGame(slug);
if (!def) {
return res.status(400).json({ error: 'Unknown game slug.' });
}
if (!Number.isFinite(score) || score < 0 || score > 100000) {
return res.status(400).json({ error: 'Invalid score.' });
}
if (!Array.isArray(opponentScores) || !opponentScores.every((n) => Number.isFinite(n))) {
return res.status(400).json({ error: 'Invalid opponentScores.' });
}
if (!RESULTS.has(result)) {
return res.status(400).json({ error: 'Invalid result.' });
}
const tx = db.transaction(() => {
db.prepare(
`INSERT INTO games (slug, name, category, max_players, supports_multiplayer)
VALUES (?, ?, ?, ?, ?)
ON CONFLICT(slug) DO NOTHING`,
).run(def.slug, def.name, def.category, def.maxPlayers, def.supportsMultiplayer ? 1 : 0);
const gameRow = db.prepare('SELECT id FROM games WHERE slug = ?').get(def.slug);
const matchRes = db.prepare(
`INSERT INTO matches (game_id, ended_at, status)
VALUES (?, datetime('now'), 'completed')`,
).run(gameRow.id);
const matchId = matchRes.lastInsertRowid;
db.prepare(
`INSERT INTO match_players (match_id, user_id, seat, result, score)
VALUES (?, ?, 0, ?, ?)`,
).run(matchId, req.user.id, result, Math.round(score));
return matchId;
});
try {
const matchId = tx();
res.json({ matchId });
} catch (err) {
console.error('[history/single-player]', err);
res.status(500).json({ error: 'Failed to record match.' });
}
});
export default router;