diff --git a/app/(dashboard)/playlist/PlaylistClient.tsx b/app/(dashboard)/playlist/PlaylistClient.tsx index d2b2d13..96c70b1 100644 --- a/app/(dashboard)/playlist/PlaylistClient.tsx +++ b/app/(dashboard)/playlist/PlaylistClient.tsx @@ -38,6 +38,7 @@ interface PlaylistVersion { posterUrl: string | null; fps: number; approvalStatus: string; + taskTitle: string; } interface PlaylistShot { @@ -315,6 +316,7 @@ function ShotThumbnail({ {/* Info */}

{shot.shotCode}

+

{shot.latestVersion.taskTitle}

c.startsWith("text-")) ?? "text-zinc-400" diff --git a/app/api/playlist/route.ts b/app/api/playlist/route.ts index f87fb89..9cebae0 100644 --- a/app/api/playlist/route.ts +++ b/app/api/playlist/route.ts @@ -13,13 +13,14 @@ export async function GET(req: NextRequest) { return NextResponse.json({ error: "projectId required" }, { status: 400 }); } + // All versions are linked to tasks (taskId), not directly to shots. + // We query shots with their tasks, and for each task get the latest version. const shots = await db.shot.findMany({ where: { projectId, - versions: { + tasks: { some: { - shotId: { not: null }, - mimeType: { startsWith: "video/" }, + versions: { some: { isLatest: true } }, }, }, }, @@ -30,36 +31,60 @@ export async function GET(req: NextRequest) { episode: true, status: true, thumbnailUrl: true, - versions: { - where: { - isLatest: true, - mimeType: { startsWith: "video/" }, - }, - take: 1, + tasks: { select: { id: true, - versionNumber: true, - fileUrl: true, - thumbnailUrl: true, - posterUrl: true, - fps: true, - approvalStatus: true, + title: true, + versions: { + where: { isLatest: true }, + take: 1, + orderBy: { createdAt: "desc" }, + select: { + id: true, + versionNumber: true, + fileUrl: true, + thumbnailUrl: true, + posterUrl: true, + fps: true, + approvalStatus: true, + mimeType: true, + createdAt: true, + }, + }, }, }, }, }); - // Only return shots that actually have a latest video version + // For each shot, pick the most recently uploaded latest version across all tasks const playlist = shots - .map((shot) => ({ - id: shot.id, - shotCode: shot.shotCode, - episode: shot.episode, - status: shot.status, - thumbnailUrl: shot.thumbnailUrl, - latestVersion: shot.versions[0] ?? null, - })) - .filter((shot) => shot.latestVersion !== null); + .map((shot) => { + const versions = shot.tasks + .flatMap((t) => t.versions.map((v) => ({ ...v, taskTitle: t.title }))) + .sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()); + + const latest = versions[0] ?? null; + if (!latest) return null; + + return { + id: shot.id, + shotCode: shot.shotCode, + episode: shot.episode, + status: shot.status, + thumbnailUrl: shot.thumbnailUrl, + latestVersion: { + id: latest.id, + versionNumber: latest.versionNumber, + fileUrl: latest.fileUrl, + thumbnailUrl: latest.thumbnailUrl, + posterUrl: latest.posterUrl, + fps: latest.fps, + approvalStatus: latest.approvalStatus, + taskTitle: latest.taskTitle, + }, + }; + }) + .filter((s): s is NonNullable => s !== null); return NextResponse.json({ shots: playlist }); }