1/** 2 * Web OTel bootstrap (TASK-0135). 3 * 4 * Next.js calls `register()` ONCE per runtime. It runs in the Node.js 5 * server runtime (the App Router's RSC/server-action/request path); the 6 * edge runtime is NOT used by this app (the middleware is pure cookie 7 * gating, no `export const runtime`), so a single guard is sufficient. 8 * 9 * Same init contract as the API/worker/realtime: `OTEL_ENABLED=true` + 10 * `OTEL_EXPORTER_OTLP_ENDPOINT` → export spans/metrics to the collector; 11 * otherwise every primitive in `@factory/observability` is a no-op (the 12 * package's lazy instruments bind to nothing). OTEL_* are read from 13 * process.env directly — the web app has no central env schema to extend. 14 */ 15import { initOtel, shutdownOtel } from "@factory/observability"; 16 17export async function register(): Promise<void> { 18 if (typeof window !== "undefined") return; // browser bundle — never init here 19 const otelEndpoint = process.env.OTEL_EXPORTER_OTLP_ENDPOINT; 20 await initOtel({ 21 serviceName: "factory-web", 22 environment: process.env.NODE_ENV, 23 ...(process.env.OTEL_ENABLED === "true" && otelEndpoint ? { endpoint: otelEndpoint } : {}) 24 }); 25 26 // Flush on graceful shutdown (Next dev: Ctrl-C / SIGTERM). 27 const flush = (): void => { 28 shutdownOtel().catch(() => undefined); 29 }; 30 process.on("SIGINT", flush); 31 process.on("SIGTERM", flush); 32} 33