Files
vfxreview/lib/shot-status.ts
T
twotalesanimation 0fbe856dce Initial commit
2026-05-19 22:20:29 +02:00

54 lines
1.6 KiB
TypeScript

import { ShotStatus, TaskStatus } from "@prisma/client";
import { db } from "@/lib/db";
import type { PrismaClient } from "@prisma/client";
type TxClient = Omit<
PrismaClient,
"$connect" | "$disconnect" | "$on" | "$transaction" | "$use" | "$extends"
>;
/**
* Derive the shot status from its tasks.
* Priority order (highest → lowest):
* CHANGES on any task → REVISIONS
* INTERNAL_REVIEW / CLIENT_REVIEW on any task → IN_REVIEW
* TODO / IN_PROGRESS on any task → IN_PROGRESS
* All tasks DONE → COMPLETE
* No tasks → WAITING
*/
export function deriveShotStatus(
tasks: { status: TaskStatus }[]
): ShotStatus {
if (tasks.length === 0) return "WAITING";
if (tasks.some((t) => t.status === "CHANGES")) return "REVISIONS";
if (tasks.some((t) => t.status === "INTERNAL_REVIEW" || t.status === "CLIENT_REVIEW"))
return "IN_REVIEW";
if (tasks.some((t) => t.status === "TODO" || t.status === "IN_PROGRESS"))
return "IN_PROGRESS";
if (tasks.every((t) => t.status === "DONE")) return "COMPLETE";
return "WAITING";
}
/**
* Query all tasks for a shot, derive the correct ShotStatus, and persist it.
* Accepts an optional Prisma transaction client (tx) for use inside transactions.
*/
export async function recalcShotStatus(
shotId: string,
tx?: TxClient
): Promise<void> {
const client = tx ?? db;
const tasks = await client.task.findMany({
where: { shotId },
select: { status: true },
});
const newStatus = deriveShotStatus(tasks);
await client.shot.update({
where: { id: shotId },
data: { status: newStatus },
});
}