import { NextRequest, NextResponse } from "next/server"; import { db } from "@/lib/db"; // ── Auth ───────────────────────────────────────────────────────────────────── function isAuthorized(req: NextRequest): boolean { const apiKey = process.env.API_SECRET_KEY; if (!apiKey) return false; const authHeader = req.headers.get("authorization") ?? ""; if (authHeader.startsWith("Bearer ")) return authHeader.slice(7) === apiKey; return (req.headers.get("x-api-key") ?? "") === apiKey; } // ── GET /api/ext/projects/[projectCode]/shots ───────────────────────────────── // // Returns all shots for a project, optionally filtered by episode and/or sequence. // Uses the human-readable project code (e.g. UNG_108) not the DB id. // // Query params (all optional): // episode e.g. 108 // sequence e.g. 004 // status e.g. IN_PROGRESS // page (default 1) // limit (default 200, max 500) // // Example: // GET /api/ext/projects/UNG_108/shots?episode=108&sequence=004 // GET /api/ext/projects/UNG_108/shots export async function GET( req: NextRequest, { params }: { params: Promise<{ projectCode: string }> } ) { if (!isAuthorized(req)) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } const { projectCode } = await params; const { searchParams } = new URL(req.url); const episode = searchParams.get("episode")?.trim() || undefined; const sequence = searchParams.get("sequence")?.trim() || undefined; const status = searchParams.get("status")?.trim() || undefined; const page = Math.max(1, parseInt(searchParams.get("page") ?? "1", 10)); const limit = Math.min(500, Math.max(1, parseInt(searchParams.get("limit") ?? "200", 10))); const skip = (page - 1) * limit; const project = await db.project.findUnique({ where: { code: projectCode }, select: { id: true, name: true, code: true, showId: true }, }); if (!project) { return NextResponse.json({ error: "Project not found" }, { status: 404 }); } const [shots, total] = await Promise.all([ db.shot.findMany({ where: { projectId: project.id, ...(episode ? { episode } : {}), ...(sequence ? { sequence } : {}), ...(status ? { status: status as never } : {}), }, orderBy: [{ episode: "asc" }, { shotCode: "asc" }], skip, take: limit, select: { id: true, shotCode: true, scene: true, episode: true, sequence: true, shotNumber: true, description: true, status: true, priority: true, frameStart: true, frameEnd: true, fps: true, dueDate: true, // EDL / pull CSV fields sourceClip: true, timecodeStart: true, timecodeEnd: true, clipDuration: true, exrOutput: true, thumbnailUrl: true, artist: { select: { id: true, name: true, email: true }, }, _count: { select: { versions: true, tasks: true } }, }, }), db.shot.count({ where: { projectId: project.id, ...(episode ? { episode } : {}), ...(sequence ? { sequence } : {}), ...(status ? { status: status as never } : {}), }, }), ]); return NextResponse.json({ project, pagination: { page, limit, total, pages: Math.ceil(total / limit) }, shots, }); }