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, /** * How far a preview job outranks the render it follows. A preview is only * created when its render finishes, so at equal priority it sorts behind * every render queued alongside it — 10 shots run as 10 renders then 10 * previews, and nothing is reviewable until the end. A boost of 1 finishes * shots end to end instead. Set to 0 for the old phase behaviour. */ "render.previewPriorityBoost": 1, "render.outputRoot": "//SAN", // Validation stage (§8). Disabling it restores the pre-Phase-3 flow // (render → preview) without a redeploy, for a bad engine release. "validation.enabled": "true", "validation.sampleEvery": 25, /** Per-check severity overrides, e.g. {"exr_type":"warn"} (§17.3). */ "validation.overrides": "{}", /** Frames of head handle the plates carry; only used for the API timecode fallback (§8.1a). */ "validation.handleFrames": 8, /** * Studio-wide delivery defaults (§11.2). A project's own `deliveryConfig` * column overrides these key by key; `{}` falls through to the built-ins in * lib/render-pipeline/deliveries.ts. */ "delivery.defaultConfig": "{}", "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, validationEnabled, validationSampleEvery, validationHandleFrames, ] = await Promise.all([ getConfigNumber("render.pollSeconds"), getConfigNumber("render.heartbeatSeconds"), getConfigNumber("render.leaseSeconds"), getConfigNumber("render.maxAttempts"), getConfigNumber("render.stallTimeoutSeconds"), getConfigBoolean("validation.enabled"), getConfigNumber("validation.sampleEvery"), getConfigNumber("validation.handleFrames"), ]); return { pollSeconds, heartbeatSeconds, leaseSeconds, maxAttempts, stallTimeoutSeconds, // Whether the validation stage runs is the server's call, so switching it // off is a config change here rather than a redeploy of every worker (§8). validationEnabled, validationSampleEvery, validationHandleFrames, }; }