implement basic express server + api

This commit is contained in:
2025-09-10 17:38:25 +02:00
parent c6affc4181
commit fcea8f5ea7
5 changed files with 904 additions and 2 deletions

77
backend/src/api.js Normal file
View File

@@ -0,0 +1,77 @@
import { Router } from "express";
const router = Router();
router.get("/healthcheck", (req, res) => {
res.json({ status: "ok" })
});
router.post("/scores", async (req, res) => {
const { name, game, score } = req.body;
if (!name || !game || !Number.isFinite(score) || !Number.isInteger(score) || score < 0) {
return res.status(400).json({ error: "Missing or invalid parameters" });
}
const conn = await pool.getConnection();
try {
await conn.beginTransaction();
const [userRows] = await conn.query(
`INSERT INTO users (name) VALUES (?)`,
[name]
);
const userId = userRows.insertId;
const [gameRows] = await conn.query(
`INSERT INTO games (name) VALUES (?) ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id)`,
[game]
);
const gameId = gameRows.insertId;
await conn.query(
`
INSERT INTO scores (user_id, game_id, score)
VALUES (?, ?, ?)
ON DUPLICATE KEY UPDATE score = GREATEST(score, VALUES(score))
`,
[userId, gameId, score]
);
await conn.commit();
res.json({ success: true });
} catch (err) {
await conn.rollback();
console.error(err);
res.status(500).json({ error: "Database error" });
} finally {
conn.release();
}
});
router.get("/leaderboard/:game", async (req, res) => {
const gameName = req.params.game;
try {
const [rows] = await pool.query(
`
SELECT u.name AS user, s.score, s.created_at
FROM scores s
JOIN users u ON s.user_id = u.id
JOIN games g ON s.game_id = g.id
WHERE g.name = ?
ORDER BY s.score DESC, s.created_at ASC
LIMIT 10
`,
[gameName]
);
res.json({ leaderboard: rows });
} catch (err) {
console.error(err);
res.status(500).json({ error: "Database error" });
}
});
export default router;

View File

@@ -1,5 +1,22 @@
import dotenv from 'dotenv';
import express from 'express';
import path from 'path';
import { fileURLToPath } from 'url';
import apiRouter from './api.js';
dotenv.config();
const db = await import('./db.js');
db.initDB();
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.join(path.dirname(__filename), ".."); // going back a dir cuz code is in src/
const db = await import('./db.js'); // dynamic import because otherwise dotenv will not work correctly
const app = express();
db.initDB();
app.use(express.static(path.join(__dirname, "public"), {
dotfiles: "ignore"
}));
app.use("/api", apiRouter);
const server = app.listen(0, () => {
console.log(`Server running on http://localhost:${server.address().port}`);
});