import type { UserTrail } from '#shared/types/map'; import { useValidatedParams, z, zh } from 'h3-zod'; import prisma from '~~/lib/prisma'; /** * Full TrackPoint trail for a single user in a hunt, fetched lazily when an * organizer clicks a user on the live map. * * Gated by HuntMember membership AND `hunt.trackDistance` (404 otherwise). * Plain JSON: `recordedAt` as ISO strings, coordinates coerced to numbers. */ export default defineEventHandler(async (event): Promise => { const user = await requireUserSession(event); const callerId = user.user.id; const { huntId, userId } = await useValidatedParams( event, z.object({ huntId: zh.numAsString, userId: zh.numAsString }) ); const hunt = await prisma.hunt.findUnique({ where: { id: huntId, trackDistance: true, members: { some: { memberId: callerId } } }, select: { id: true } }); if (!hunt) { throw createError({ status: 404, statusText: 'Not found!' }); } const points = await prisma.trackPoint.findMany({ where: { huntId, userId }, orderBy: { recordedAt: 'asc' }, select: { lat: true, lon: true, accuracy: true, recordedAt: true } }); return { points: points.map((p) => ({ lat: Number(p.lat), lon: Number(p.lon), accuracy: p.accuracy, recordedAt: p.recordedAt.toISOString() })) }; });