diff --git a/app/api/shots/[shotId]/route.ts b/app/api/shots/[shotId]/route.ts index d0b0f5d..b69a076 100644 --- a/app/api/shots/[shotId]/route.ts +++ b/app/api/shots/[shotId]/route.ts @@ -82,7 +82,7 @@ export async function GET( session.user.role as string ); - // Serialize BigInt fields (fileSize) so JSON.stringify doesn't throw + // Serialize BigInt fields (fileSize, highResSize) so JSON.stringify doesn't throw const shotSerialized = { ...shot, footagePlates: shot.footagePlates.map((p) => ({ @@ -92,6 +92,7 @@ export async function GET( versions: shot.versions.map((v) => ({ ...v, fileSize: v.fileSize != null ? v.fileSize.toString() : null, + highResSize: v.highResSize != null ? v.highResSize.toString() : null, })), }; diff --git a/lib/db.ts b/lib/db.ts index 9bb9ce6..7752e14 100644 --- a/lib/db.ts +++ b/lib/db.ts @@ -1,5 +1,25 @@ import { PrismaClient } from "@prisma/client"; +// Safety net: Prisma returns BigInt columns (fileSize, highResSize, …) as +// BigInt, which JSON.stringify refuses — one such column anywhere in an API +// response turns the whole route into a 500. Serialize them as strings, the +// same shape the routes that convert them by hand already produce. Routes +// that spread whole rows into NextResponse.json are then safe by default. +declare global { + interface BigInt { + toJSON(): string; + } +} +if (!("toJSON" in BigInt.prototype)) { + Object.defineProperty(BigInt.prototype, "toJSON", { + value: function toJSON(this: bigint) { + return this.toString(); + }, + writable: true, + configurable: true, + }); +} + const globalForPrisma = globalThis as unknown as { prisma: PrismaClient | undefined; };