import { useValidatedParams, z, zh } from 'h3-zod'; import prisma from '~~/lib/prisma'; export default defineEventHandler(async (event) => { const { huntId } = await useValidatedParams( event, z.object({ huntId: zh.numAsString }) ); const user = await getUserSession(event); const userId = user.user?.id || 0; const _hunt = await prisma.hunt.findUnique({ where: { id: huntId, deletedAt: null }, select: { id: true, name_de: true, name_en: true, description_de: true, description_en: true, revealAnswers: true, revealQuests: true, picture: { select: { url: true } }, createdAt: true, start: true, end: true, _count: { select: { teams: true, quests: true } }, creator: { select: { name: true, id: true } }, members: { select: { member: { select: { id: true, name: true } } }, where: { memberId: userId } }, teams: { select: { id: true, name: true, password: true }, where: { OR: [ { ownerId: userId }, { members: { some: { memberId: userId } } } ] } }, quests: { select: { id: true, title_de: true, title_en: true, description_de: true, description_en: true, picture: { select: { url: true } }, textRequired: true, pictureRequired: true, points: true, extraPoints: true, optional: true, textType: true, textUnit: true, _count: { select: { answers: { where: { final: true, OR: [ { review: null }, { review: { score: null } }, { review: { review: null } } ] } } } }, answers: { select: { id: true, text: true, final: true, picture: { select: { url: true } }, review: { select: { score: true, review: true } }, member: { select: { name: true } }, createdAt: true, updatedAt: true }, orderBy: { updatedAt: 'desc' }, where: { team: { OR: [ { ownerId: userId }, { members: { some: { memberId: userId } } } ] } } } }, orderBy: [ { order: 'asc' }, { id: 'asc' } ] } } }); // TODO: add perms if (!_hunt) { throw createError({ status: 404, statusText: 'Not found!' }); } const { teams, members, quests, ...hunt } = _hunt; const isMember = hunt.creator.id === userId || members.length > 0; const ownTeam = teams.length > 0 ? teams[0] : null; const mappedQuests = quests.map(({ answers, _count, ...q }) => ({ ...q, unreviewed: isMember ? _count.answers : undefined, answer: answers.length > 0 ? answers[0] : null })); const totalScore = mappedQuests.reduce( (acc, q) => acc + (q.answer?.review?.score ?? 0), 0 ); // TODO: filter out questions before start return { isMember, ownTeam, loggedIn: !!user.user, totalScore: ownTeam !== null ? totalScore : undefined, quests: hunt.revealQuests || isMember ? mappedQuests : null, ...hunt }; });