import { db } from "@/lib/db"; /** * Pipeline-wide settings live in the existing SystemConfig key/value table * (RenderPipeline2 §14.1) so the fleet can be tuned without redeploys. */ export const PIPELINE_CONFIG_DEFAULTS = { "render.pollSeconds": 10, "render.heartbeatSeconds": 30, "render.leaseSeconds": 300, "render.maxAttempts": 3, "render.stallTimeoutSeconds": 600, "render.urgentPriorityThreshold": 20, "render.outputRoot": "//SAN/renders", "validation.sampleEvery": 25, "preview.maxWidth": 1920, // Preview stage (§9): headless AE rebuild of the render with slate/burn-ins "preview.enabled": "true", "preview.templateAep": "X:/shared_projects_2026/UNGO_VFX/production/working_files/UNG_VFXOVERLAY_SLATE_TEMPLATE.aep", "preview.templateComp": "UNG_EXPORT_TEMPLATE", "preview.overlayComp": "UNG_VFX_OVERLAY", "preview.lutComp": "_SHOW LUT", "preview.movTemplate": "4444 Tri", "preview.mp4Template": "REVIEW_PREVIEW", // Essential Property names on the NETFLIX_SLATE layer for the per-submission // fields. If a name is wrong the build logs the template's actual property // names as a warning, so it is a config fix rather than a code change. "preview.slateScopeProp": "Scope", "preview.slateSubmissionProp": "Notes", } as const; export type PipelineConfigKey = keyof typeof PIPELINE_CONFIG_DEFAULTS; export async function getConfigValue(key: PipelineConfigKey): Promise { const row = await db.systemConfig.findUnique({ where: { key } }); return row?.value ?? String(PIPELINE_CONFIG_DEFAULTS[key]); } export async function getConfigNumber(key: PipelineConfigKey): Promise { const raw = await getConfigValue(key); const n = Number(raw); return Number.isFinite(n) ? n : Number(PIPELINE_CONFIG_DEFAULTS[key]); } export async function getConfigBoolean(key: PipelineConfigKey): Promise { const raw = (await getConfigValue(key)).trim().toLowerCase(); return raw === "true" || raw === "1" || raw === "yes"; } /** Preview-stage settings handed to the worker inside the PREVIEW_ONLY manifest. */ export async function getPreviewConfig() { const [ enabled, templateAep, templateComp, overlayComp, lutComp, movTemplate, mp4Template, slateScopeProp, slateSubmissionProp, ] = await Promise.all([ getConfigBoolean("preview.enabled"), getConfigValue("preview.templateAep"), getConfigValue("preview.templateComp"), getConfigValue("preview.overlayComp"), getConfigValue("preview.lutComp"), getConfigValue("preview.movTemplate"), getConfigValue("preview.mp4Template"), getConfigValue("preview.slateScopeProp"), getConfigValue("preview.slateSubmissionProp"), ]); return { enabled, templateAep, templateComp, overlayComp, lutComp, movTemplate, mp4Template, slateScopeProp, slateSubmissionProp, }; } /** Worker-facing config bundle returned by E6 registration. */ export async function getWorkerConfig() { const [pollSeconds, heartbeatSeconds, leaseSeconds, maxAttempts, stallTimeoutSeconds] = await Promise.all([ getConfigNumber("render.pollSeconds"), getConfigNumber("render.heartbeatSeconds"), getConfigNumber("render.leaseSeconds"), getConfigNumber("render.maxAttempts"), getConfigNumber("render.stallTimeoutSeconds"), ]); return { pollSeconds, heartbeatSeconds, leaseSeconds, maxAttempts, stallTimeoutSeconds }; }