fix: BigInt serialization in shoot-log API responses
Deploy / deploy (push) Successful in 2m41s

This commit is contained in:
twotalesanimation
2026-07-11 19:38:54 +02:00
parent 3ff70cc5e3
commit b9953ff543
3 changed files with 22 additions and 6 deletions
@@ -6,6 +6,11 @@ function requireRole(role: string) {
return ["ADMIN", "PRODUCER", "SUPERVISOR"].includes(role); return ["ADMIN", "PRODUCER", "SUPERVISOR"].includes(role);
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function bigIntSafe(obj: any): any {
return JSON.parse(JSON.stringify(obj, (_, v) => (typeof v === "bigint" ? Number(v) : v)));
}
// GET /api/shoot-log/setups/[setupId]/takes // GET /api/shoot-log/setups/[setupId]/takes
export async function GET( export async function GET(
_req: NextRequest, _req: NextRequest,
@@ -24,7 +29,7 @@ export async function GET(
include: { attachments: { orderBy: { sortOrder: "asc" } } }, include: { attachments: { orderBy: { sortOrder: "asc" } } },
}); });
return NextResponse.json({ takes }); return NextResponse.json(bigIntSafe({ takes }));
} }
// POST /api/shoot-log/setups/[setupId]/takes // POST /api/shoot-log/setups/[setupId]/takes
@@ -56,7 +61,7 @@ export async function POST(
include: { attachments: { orderBy: { sortOrder: "asc" } } }, include: { attachments: { orderBy: { sortOrder: "asc" } } },
}); });
return NextResponse.json({ take }, { status: 201 }); return NextResponse.json(bigIntSafe({ take }), { status: 201 });
} }
function sanitize(data: Record<string, unknown>) { function sanitize(data: Record<string, unknown>) {
@@ -7,6 +7,11 @@ function requireRole(role: string) {
return ["ADMIN", "PRODUCER", "SUPERVISOR"].includes(role); return ["ADMIN", "PRODUCER", "SUPERVISOR"].includes(role);
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function bigIntSafe(obj: any): any {
return JSON.parse(JSON.stringify(obj, (_, v) => (typeof v === "bigint" ? Number(v) : v)));
}
// GET /api/shoot-log/takes/[takeId]/attachments // GET /api/shoot-log/takes/[takeId]/attachments
export async function GET( export async function GET(
_req: NextRequest, _req: NextRequest,
@@ -24,7 +29,7 @@ export async function GET(
include: { uploadedBy: { select: { id: true, name: true } } }, include: { uploadedBy: { select: { id: true, name: true } } },
}); });
return NextResponse.json({ attachments }); return NextResponse.json(bigIntSafe({ attachments }));
} }
// POST /api/shoot-log/takes/[takeId]/attachments // POST /api/shoot-log/takes/[takeId]/attachments
@@ -65,5 +70,5 @@ export async function POST(
}, },
}); });
return NextResponse.json({ attachment }, { status: 201 }); return NextResponse.json(bigIntSafe({ attachment }), { status: 201 });
} }
+8 -2
View File
@@ -6,6 +6,12 @@ function requireRole(role: string) {
return ["ADMIN", "PRODUCER", "SUPERVISOR"].includes(role); return ["ADMIN", "PRODUCER", "SUPERVISOR"].includes(role);
} }
/** Convert BigInt values to Number so JSON.stringify doesn't throw */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function bigIntSafe(obj: any): any {
return JSON.parse(JSON.stringify(obj, (_, v) => (typeof v === "bigint" ? Number(v) : v)));
}
function sanitize(data: Record<string, unknown>) { function sanitize(data: Record<string, unknown>) {
const allowed = new Set([ const allowed = new Set([
"scene","shotLabel","unitLabel","cameraLetter","clipName","roll","cameraModel", "scene","shotLabel","unitLabel","cameraLetter","clipName","roll","cameraModel",
@@ -49,7 +55,7 @@ export async function GET(
}); });
if (!take) return NextResponse.json({ error: "Not found" }, { status: 404 }); if (!take) return NextResponse.json({ error: "Not found" }, { status: 404 });
return NextResponse.json({ take }); return NextResponse.json(bigIntSafe({ take }));
} }
// PATCH /api/shoot-log/takes/[takeId] // PATCH /api/shoot-log/takes/[takeId]
@@ -71,7 +77,7 @@ export async function PATCH(
include: { attachments: { orderBy: { sortOrder: "asc" } } }, include: { attachments: { orderBy: { sortOrder: "asc" } } },
}); });
return NextResponse.json({ take }); return NextResponse.json(bigIntSafe({ take }));
} }
// DELETE /api/shoot-log/takes/[takeId] // DELETE /api/shoot-log/takes/[takeId]