import { NextResponse } from "next/server"; import { authorizeWorkerRequest } from "yt-dlp-transcript-common/lib/workerToken"; import { getOperation } from "yt-dlp-transcript-common/lib/operations"; import { startWorkerUnit, type StartWorkerUnitInput, } from "yt-dlp-transcript-common/controller/workerServer"; export const dynamic = "force-dynamic"; // Accept ONE backfill unit (attribution, diarization, …) from another // instance: a JSON envelope carrying the kind id, the input files (base64 by // name), the primary's resolved freshness target and its identity config. // Returns { remoteJobId } (202); the requester polls // /api/worker/unit//events and pulls /result. Same token guard as the // transcription protocol. // // Anything that is not a backfill KIND is refused at the door — download and // transcription are ExternalOperations, and letting a second host run a // download would double the per-platform politeness this repo is careful // about. export async function POST(request: Request) { const auth = authorizeWorkerRequest(request.headers.get("authorization")); if (!auth.ok) { return NextResponse.json({ error: auth.error }, { status: auth.status }); } let body: StartWorkerUnitInput; try { body = (await request.json()) as StartWorkerUnitInput; } catch { return NextResponse.json({ error: "malformed JSON body" }, { status: 400 }); } if (!body.op || !body.channelSlug || !body.videoId) { return NextResponse.json( { error: "op, channelSlug and videoId are required" }, { status: 400 }, ); } if (!getOperation(body.op)) { return NextResponse.json( { error: `"${body.op}" is not a backfill kind this executor can run` }, { status: 400 }, ); } try { const { remoteJobId } = await startWorkerUnit(body); return NextResponse.json({ remoteJobId }, { status: 202 }); } catch (e) { return NextResponse.json({ error: (e as Error).message }, { status: 500 }); } }