import type { AuditEntry } from "@repo/core-shared/audit"; import type { IAuditLog } from "./audit-log.interface"; /** * Writes one structured JSON line per audit entry to stdout. A log shipper * (Vector, Fluent Bit) picks these up and forwards to the centralized * aggregator (Grafana Cloud, Datadog, Loki EU, etc.). * * Lines include a `_type` discriminator so the shipper can route: * "audit" → audit entry * "audit-erasure" → GDPR erasure tombstone * * `eraseSubject` is best-effort: past stdout lines can't be retroactively * removed. The tombstone informs the downstream aggregator to filter/delete. */ export class StdoutJsonAuditLog implements IAuditLog { async record(entry: AuditEntry): Promise { const serialized = JSON.stringify({ _type: "audit", ...entry, at: entry.at.toISOString(), }); process.stdout.write(serialized + "\n"); } async eraseSubject(actorId: string, mode: "pseudonymize" | "delete"): Promise { const tombstone = { _type: "audit-erasure", actorId, mode, at: new Date().toISOString(), }; process.stdout.write(JSON.stringify(tombstone) + "\n"); } }