import type { AuditEntry } from "@repo/core-shared/audit"; import { currentTraceId } from "@repo/core-shared/instrumentation"; import type { IAuditLog } from "./audit-log.interface"; /** * Decorates any IAuditLog by auto-populating AuditEntry.correlationId from * the active OTel span (when present and the caller didn't supply a value). * Caller-supplied correlationId always wins — explicit > implicit. * * Applied at bind time by bindAudit so all sinks see entries with * correlationId already set. Single source of truth for the OTel-audit bridge. */ export class TraceIdEnrichingAuditLog implements IAuditLog { constructor(readonly inner: IAuditLog) {} async record(entry: AuditEntry): Promise { if (entry.correlationId) { return this.inner.record(entry); } const traceId = currentTraceId(); if (!traceId) { return this.inner.record(entry); } return this.inner.record({ ...entry, correlationId: traceId }); } eraseSubject(actorId: string, mode: "pseudonymize" | "delete"): Promise { return this.inner.eraseSubject(actorId, mode); } }