// server/api/leaderboard.get.ts export default defineEventHandler(async () => { // --- MVP Compromise: Monthly EXP --- // The current schema does not support tracking monthly EXP. // For MVP, we will use the total cumulative `User.exp` as a stand-in // for "current month's EXP". This should be revisited if true monthly // tracking becomes a requirement. const users = await prisma.user.findMany({ select: { nickname: true, avatar: true, exp: true, }, orderBy: { exp: 'desc', }, take: 50, // Limit to top 50 users }); // --- Rank Calculation --- let currentRank = 0; let previousExp = -1; // Ensure any valid EXP is greater than this // To handle shared ranks, we iterate through the sorted users. // If the current user's EXP is different from the previous user's EXP, // their rank is their position in the 1-based sorted list. // If their EXP is the same, they share the rank of the previous user. const leaderboard = users.map((user, index) => { if (user.exp !== previousExp) { currentRank = index + 1; // Ranks are 1-based } previousExp = user.exp; // Update previous EXP for the next iteration return { rank: currentRank, nickname: user.nickname, avatar: user.avatar, exp: user.exp, }; }); return { leaderboard }; });