import { cleanAudioAction, cleanExtraAudioFormatsAction, clearFailedTranscriptionsAction, removeWrongFormatAudioAction, } from "../../../channels/[slug]/whisperActions"; import { jobResponse, oneOf, ops, reqSlug } from "../_lib"; export const dynamic = "force-dynamic"; // POST { slug, sweep: "transcribed" | "extra-formats" | "wrong-format" | // "failed-transcriptions" } // // One of a channel's cleanup sweeps — the channel page's Cleanup buttons, as a // job on the channel's queue ({ ok, jobId }; --wait follows it): // transcribed "Clean audio": delete the audio of every video that // has a transcript (cleanAudioAction) — the sweep the // /cleanup total counts; // extra-formats delete a video's audio in formats other than the // channel's target, where the target is on disk; // wrong-format delete every finalized audio file not in the target // format, including failed-extract orphans; // failed-transcriptions clear the channel's failed-transcriptions list, so // "Transcribe missing" retries them (deletes no media). // Each is the page's own action, so it keeps what the page's keeps: every // sweep skips a do-not-clean video; "transcribed" also keeps the channel's // keep-latest window and audio still awaiting diarization; every one deletes // through the media tier's remover (removeMediaFile), never a bare link. // `get cleanup ` says what each would reclaim. const SWEEPS = { transcribed: cleanAudioAction, "extra-formats": cleanExtraAudioFormatsAction, "wrong-format": removeWrongFormatAudioAction, "failed-transcriptions": clearFailedTranscriptionsAction, } as const; export async function POST(request: Request) { return ops(request, ["slug", "sweep"], async (body) => { const slug = reqSlug(body, "slug"); const sweep = oneOf(body, "sweep", Object.keys(SWEEPS) as (keyof typeof SWEEPS)[]); return jobResponse(await SWEEPS[sweep](slug)); }); }