Files
flatrender/src/lib/render-jobs.ts
T

77 lines
1.9 KiB
TypeScript

import { createAdminClient } from "@/lib/supabase/admin";
import type { RenderRequest, RenderJobStatus } from "@/lib/render-schemas";
export interface RenderJobRow {
id: string;
project_id: string;
status: RenderJobStatus;
progress: number;
progress_message: string | null;
output_url: string | null;
scenes: RenderRequest["scenes"];
settings: RenderRequest["settings"];
error_message: string | null;
created_at: string;
updated_at: string;
}
export async function createRenderJob(
payload: RenderRequest
): Promise<{ jobId: string } | { error: string }> {
const supabase = createAdminClient();
const { data, error } = await supabase
.from("render_jobs")
.insert({
project_id: payload.projectId,
status: "queued",
progress: 0,
progress_message: "Queued for rendering",
scenes: payload.scenes,
settings: payload.settings,
})
.select("id")
.single();
if (error || !data) {
return { error: error?.message ?? "Failed to create render job" };
}
return { jobId: data.id };
}
export async function getRenderJob(
jobId: string
): Promise<RenderJobRow | null> {
const supabase = createAdminClient();
const { data, error } = await supabase
.from("render_jobs")
.select("*")
.eq("id", jobId)
.maybeSingle();
if (error || !data) return null;
return data as RenderJobRow;
}
export async function triggerRenderWorker(jobId: string): Promise<void> {
const workerUrl = process.env.RENDER_WORKER_URL;
if (!workerUrl) return;
const secret = process.env.RENDER_WORKER_SECRET;
try {
await fetch(`${workerUrl.replace(/\/$/, "")}/process`, {
method: "POST",
headers: {
"Content-Type": "application/json",
...(secret ? { Authorization: `Bearer ${secret}` } : {}),
},
body: JSON.stringify({ jobId }),
});
} catch {
// Worker may be offline; job stays queued for retry/poll
}
}