/** * Boot-time configuration check. * * ── The problem this exists to end ─────────────────────────────────────── * Every required variable in this app is read LAZILY, on the first request * that needs it. That is deliberate and must stay that way: `next build` * collects page data with NODE_ENV=production and none of these variables * present, so reading them at module scope fails the BUILD instead of the * deployment (it did, once — "Failed to collect page data for /api/assistant", * see apiClient.ts). * * The cost of lazy reads is that a misconfigured container LOOKS healthy. It * starts, it serves the sign-in page, and the fault only appears when somebody * tries to use it — as a 500 on a form, with the real reason buried in a * response body. Three separate misconfigurations were diagnosed that way, one * round trip at a time. * * This closes the gap without touching the lazy reads. `register()` runs once * when a server instance starts and NEVER during a build — Next itself returns * early when NEXT_PHASE is 'phase-production-build' (see * server/lib/router-utils/instrumentation-globals.external.js). So the checks * below run in exactly the situation they are about: a real server, booting, * with a real environment. * * ── Why it throws ──────────────────────────────────────────────────────── * A container missing either variable cannot serve a single authenticated * request. Refusing to start turns that into a failed deploy with a named * cause in the log pane, which Dokploy surfaces immediately, instead of a * green healthcheck in front of a console nobody can sign into. It also stops * a broken image from replacing a working one. */ export async function register() { /** * Node only. `register()` is invoked once per runtime, and src/proxy.ts makes * this app compile an Edge one too — without this guard the same check would * run and log twice on every boot. The Node server is the process that serves * every route handler, so validating there is what matters. */ if (process.env.NEXT_RUNTIME !== 'nodejs') return; // Dynamic, so the Edge bundle never pulls in the Node-only module. See that // file for why a runtime guard alone was not enough. const {checkConfiguration} = await import('./instrumentation-node'); await checkConfiguration(); }