import { NextRequest, NextResponse } from "next/server"; import { db } from "@/lib/db"; async function validateToken(token: string) { const session = await db.reviewSession.findUnique({ where: { token } }); if (!session || !session.isActive) return null; if (session.expiresAt && session.expiresAt < new Date()) return null; return session; } /** GET /api/client/[token]/project — returns project + shots with tasks that have client-visible versions */ export async function GET( req: NextRequest, { params }: { params: Promise<{ token: string }> } ) { const { token } = await params; const session = await validateToken(token); if (!session) { return NextResponse.json({ error: "Invalid or expired review link" }, { status: 403 }); } const project = await db.project.findUnique({ where: { id: session.projectId }, select: { id: true, name: true, code: true, description: true, status: true }, }); if (!project) { return NextResponse.json({ error: "Project not found" }, { status: 404 }); } // Find shots that have at least one task with a client-visible version const shots = await db.shot.findMany({ where: { projectId: session.projectId, tasks: { some: { versions: { some: { isClientVisible: true } }, }, }, }, orderBy: [{ sequence: "asc" }, { shotCode: "asc" }], select: { id: true, shotCode: true, sequence: true, description: true, status: true, thumbnailUrl: true, tasks: { where: { versions: { some: { isClientVisible: true } }, }, select: { id: true, title: true, type: true, status: true, versions: { where: { isClientVisible: true, isLatest: true }, take: 1, select: { id: true, versionNumber: true, approvalStatus: true, fps: true, duration: true, thumbnailUrl: true, notes: true, createdAt: true, }, }, }, }, }, }); // Asset tasks with client-visible versions (no shotId) const assetTasks = await db.task.findMany({ where: { projectId: session.projectId, shotId: null, versions: { some: { isClientVisible: true } }, }, select: { id: true, title: true, type: true, status: true, asset: { select: { id: true, assetCode: true, name: true } }, versions: { where: { isClientVisible: true, isLatest: true }, take: 1, select: { id: true, versionNumber: true, approvalStatus: true, fps: true, duration: true, thumbnailUrl: true, notes: true, createdAt: true, }, }, }, }); // Increment access count await db.reviewSession.update({ where: { id: session.id }, data: { accessCount: { increment: 1 } }, }); return NextResponse.json({ project, shots, assetTasks, sessionLabel: session.label, }); }