rebreak-monorepo/backend/server/api/games/leaderboard.get.ts

61 lines
1.6 KiB
TypeScript

import { usePrisma } from "../../utils/prisma";
export default defineEventHandler(async (event) => {
setResponseHeaders(event, { "Content-Type": "application/json" });
const user = await requireUser(event);
const query = getQuery(event);
const gameName = String(query.game || "").toLowerCase();
const limit = Math.min(Number(query.limit) || 10, 50);
if (!gameName) {
throw createError({
statusCode: 400,
message: "game parameter erforderlich",
});
}
try {
const db = usePrisma();
const scores = await db.gameHighScore.findMany({
where: { gameName },
orderBy: { score: "desc" },
take: limit,
select: { userId: true, nickname: true, score: true, updatedAt: true },
});
const myEntry = scores.find((s) => s.userId === user.id);
let myRank = myEntry ? scores.indexOf(myEntry) + 1 : null;
if (!myEntry) {
const myScore = await db.gameHighScore.findUnique({
where: { userId_gameName: { userId: user.id, gameName } },
});
if (myScore) {
const above = await db.gameHighScore.count({
where: { gameName, score: { gt: myScore.score } },
});
myRank = above + 1;
}
}
return {
leaderboard: scores.map((s, i) => ({
rank: i + 1,
nickname: s.nickname,
score: s.score,
isMe: s.userId === user.id,
updatedAt: s.updatedAt,
})),
myRank,
myScore: myEntry?.score ?? null,
};
} catch (err: any) {
throw createError({
statusCode: 500,
message: err?.message ?? "Interner Fehler",
});
}
});