Checks fail on renders that are genuinely fine — a plate the engine cannot reach, an expectation that does not apply to this shot — and a VALIDATION_FAILED export was a dead end, blocking delivery on a shot a human can see is correct. Override validation on the Export detail page resumes the pipeline where a pass would have handed off: preview, then READY_FOR_QC. It never skips QC and never delivers directly, so the frames are still looked at — the override waives the automated check, not the human one. The failed ValidationResult rows are left untouched rather than rewritten, so the QC queue keeps listing them as warnings and whoever QCs the shot sees what was waved through. The reason is required and recorded with the checks it covered on the export's timeline, and the validation panel keeps an "overridden" badge long after the event scrolls away. Restricted to admin/producer/supervisor: waving a failed check through is a supervisor's call. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { toErrorResponse } from "@/lib/render-pipeline/errors";
|
||||
import { requirePipelineAdmin } from "@/lib/render-pipeline/session-auth";
|
||||
import { overrideValidation, overrideValidationSchema } from "@/lib/render-pipeline/validation";
|
||||
|
||||
// ── POST /api/render/exports/{exportId}/override-validation ──────────────────
|
||||
//
|
||||
// A human overruling a failed validation run. Resumes the pipeline at the
|
||||
// preview stage, so the export still goes through QC; the failed checks stay on
|
||||
// record and keep showing up as warnings in the QC queue.
|
||||
|
||||
export async function POST(
|
||||
req: NextRequest,
|
||||
{ params }: { params: Promise<{ exportId: string }> }
|
||||
) {
|
||||
try {
|
||||
// Waving a failed check through is a supervisor's call, not any user's.
|
||||
const user = await requirePipelineAdmin();
|
||||
const { exportId } = await params;
|
||||
|
||||
let raw: unknown;
|
||||
try {
|
||||
raw = await req.json();
|
||||
} catch {
|
||||
return NextResponse.json({ error: "Invalid JSON" }, { status: 400 });
|
||||
}
|
||||
|
||||
const parsed = overrideValidationSchema.safeParse(raw);
|
||||
if (!parsed.success) {
|
||||
return NextResponse.json({ error: "A reason is required", details: parsed.error.issues }, { status: 422 });
|
||||
}
|
||||
|
||||
const result = await overrideValidation(exportId, {
|
||||
reason: parsed.data.reason,
|
||||
userId: user.id,
|
||||
userName: user.name ?? user.email ?? null,
|
||||
});
|
||||
return NextResponse.json(result);
|
||||
} catch (err) {
|
||||
const { body, status } = toErrorResponse(err);
|
||||
return NextResponse.json(body, { status });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user