multiple plates
Deploy / deploy (push) Successful in 2m32s

This commit is contained in:
twotalesanimation
2026-05-21 19:16:03 +02:00
parent 32073fbe4c
commit 3e3a8f7a26
7 changed files with 377 additions and 250 deletions
+87
View File
@@ -392,3 +392,90 @@ export async function getShotsByProject(projectId: string) {
orderBy: [{ sequence: "asc" }, { shotCode: "asc" }],
});
}
// ─── Footage Plates ────────────────────────────────────────────────────────────
const addFootagePlateSchema = z.object({
shotId: z.string().min(1),
fileUrl: z.string().url(),
fileKey: z.string().default(""),
fileName: z.string().default(""),
fileSize: z.number().int().positive().optional(),
label: z.string().max(100).default(""),
});
export async function addFootagePlate(raw: unknown) {
const session = await auth();
if (!session?.user) throw new Error("Unauthorized");
const data = addFootagePlateSchema.parse(raw);
// Determine next sortOrder
const last = await db.footagePlate.findFirst({
where: { shotId: data.shotId },
orderBy: { sortOrder: "desc" },
select: { sortOrder: true },
});
const plate = await db.footagePlate.create({
data: {
shotId: data.shotId,
fileUrl: data.fileUrl,
fileKey: data.fileKey,
fileName: data.fileName,
fileSize: data.fileSize != null ? BigInt(data.fileSize) : null,
label: data.label,
sortOrder: (last?.sortOrder ?? -1) + 1,
},
});
const shot = await db.shot.findUnique({ where: { id: data.shotId }, select: { projectId: true } });
if (shot) {
revalidatePath(`/projects/${shot.projectId}`);
revalidatePath(`/projects/${shot.projectId}/shots/${data.shotId}`);
}
return { success: true, plate: { ...plate, fileSize: plate.fileSize?.toString() ?? null } };
}
export async function removeFootagePlate(plateId: string) {
const session = await auth();
if (!session?.user) throw new Error("Unauthorized");
const role = session.user.role as string;
if (!["ADMIN", "PRODUCER", "SUPERVISOR"].includes(role)) throw new Error("Insufficient permissions");
const plate = await db.footagePlate.findUnique({
where: { id: plateId },
include: { shot: { select: { projectId: true } } },
});
if (!plate) throw new Error("Plate not found");
await db.footagePlate.delete({ where: { id: plateId } });
revalidatePath(`/projects/${plate.shot.projectId}`);
revalidatePath(`/projects/${plate.shot.projectId}/shots/${plate.shotId}`);
return { success: true };
}
export async function renameFootagePlate(plateId: string, label: string) {
const session = await auth();
if (!session?.user) throw new Error("Unauthorized");
const role = session.user.role as string;
if (!["ADMIN", "PRODUCER", "SUPERVISOR"].includes(role)) throw new Error("Insufficient permissions");
const trimmed = label.trim().slice(0, 100);
const plate = await db.footagePlate.update({
where: { id: plateId },
data: { label: trimmed },
include: { shot: { select: { projectId: true } } },
});
revalidatePath(`/projects/${plate.shot.projectId}`);
revalidatePath(`/projects/${plate.shot.projectId}/shots/${plate.shotId}`);
return { success: true };
}