import { useValidatedParams, z, zh } from 'h3-zod'; import prisma from '~~/lib/prisma'; export default defineEventHandler(async (event) => { // TODO: re-enable perms // const user = await requireUserSession(event); // // if (user.user.role !== 'ADMIN') { // throw createError({ // status: 403, // statusText: 'Not allowed!' // }); // } // const userId = user.user.id; const { huntId } = await useValidatedParams( event, z.object({ huntId: zh.numAsString }) ); const _hunt = await prisma.hunt.findUnique({ where: { id: huntId // OR: [ // { // creatorId: userId // }, // { // members: { // some: { // memberId: userId // } // } // } // ] }, select: { id: true, name: true, start: true, end: true, _count: { select: { teams: true, members: true, quests: true } }, teams: { select: { _count: { select: { members: true, answers: { where: { score: { gt: 0 } } } } }, id: true, name: true, description: true, answers: { select: { score: true }, where: { score: { not: null } } } } }, quests: { select: { id: true, title: true, question: true, textSolution: true, points: true, extraPoints: true, answers: { select: { id: true, text: true, score: true, picture: { select: { url: true, createdAt: true, creator: { select: { id: true, name: true } } } }, team: { select: { id: true, name: true } } }, where: { showcase: true }, orderBy: [ { rankingValue: { sort: 'asc', nulls: 'last' } }, { score: { sort: 'asc', nulls: 'last' } }, { createdAt: 'asc' } ] } }, where: { OR: [ { answers: { some: { showcase: true } } } // TODO: showcase solutions to quests // { // textSolution: { not: null } // } ] } } } }); if (!_hunt) { throw createError({ status: 404, statusText: 'Not found!' }); } const { teams, ...hunt } = _hunt; const userCount = teams.reduce( (sum, team) => sum + team._count.members + 1, 0 ); const leaderboard = teams .map(({ name, id, description, answers, _count }) => ({ name, id, description, answers: _count.answers, score: answers.reduce((sum, a) => sum + (a.score || 0), 0) })) .toSorted((a, b) => b.score - a.score); const totalScore = leaderboard.reduce((sum, team) => sum + team.score, 0); const pictureCount = await prisma.file.count({ where: { answer: { quest: { huntId } } } }); return { userCount, pictureCount, totalScore, leaderboard, ...hunt }; });