/** * TASK-0135 — the API→worker trace propagation helper (the spec's "job * metadata carries the W3C traceparent — the dispatcher stores it, the * processor resumes the span"). * * Carrier: BullMQ 5's `JobsOptions.telemetry.metadata` — the framework's own * context-propagation field (persisted on the job as the `tm` Redis field and * restored onto `job.opts.telemetry.metadata` when the worker fetches the * job). We store the W3C traceparent string there. The app never configures a * BullMQ `telemetry.meter`, so BullMQ's own (no-op) propagation hook leaves * the field untouched — it is a pure carrier for us. * * Every BullMQ `Queue.add` in the API merges `jobTraceMetadata()` into the * job options: * * await q.add("name", data, { ..., ...jobTraceMetadata() }); * * When there is no active span (OTel disabled, background context, unsampled) * it returns `{}` — nothing is ever written. The worker's job-observability * wrapper reads the same field (`job.opts.telemetry.metadata`) and resumes * the span under it (one trace across api → queue → worker). * * Central (this one helper, not six copies) per AGENTS rule 5: the API has * six enqueue sites; they all need the identical carrier shape. */ import { captureTraceparent } from "@factory/observability"; export function jobTraceMetadata(): { telemetry?: { metadata: string } } { const tp = captureTraceparent(); return tp ? { telemetry: { metadata: tp } } : {}; }