habits.andr33v.ru/server/api/leaderboard.get.ts

51 lines
1.4 KiB
TypeScript

// 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({
where: {
isAnonymous: false,
nickname: {
not: null,
},
},
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 };
});