Files
agentic-dev/packages/core-audit/src/trace-id-enriching-audit-log.ts
Danijel Martinek 07548c4620 feat(core-audit): TraceIdEnrichingAuditLog decorator for OTel correlation
Decorator implementing IAuditLog that auto-populates AuditEntry.correlationId
from the active OTel span via currentTraceId(). Caller-supplied correlationId
always wins (explicit > implicit). eraseSubject passes through unmodified.
Adds @opentelemetry/{api,sdk-trace-base,context-async-hooks} as devDeps for
test infrastructure.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 16:29:15 +02:00

31 lines
1.1 KiB
TypeScript

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<void> {
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<void> {
return this.inner.eraseSubject(actorId, mode);
}
}