41 lines
src/audit/auditLogger.ts
Captures before-and-after snapshots of record mutations and writes audit entries.
// Audit logger — records field-level changes to the compliance trail.
 
export interface RecordSnapshot {
  id: string;
  [key: string]: unknown;
}
 
export interface AuditEntry {
  recordId: string;
  before: RecordSnapshot;
  after: RecordSnapshot;
  changedBy: string;
  timestamp: number;
}
 
/**
 * Records a before-and-after snapshot of a record mutation.
 * before must capture the field values as they existed before mutation is called.
 * after must capture the state returned by mutation.
 *
 * @param record    - the record object to be mutated
 * @param mutation  - applies the change to record and returns the modified record
 * @param changedBy - user ID responsible for the change
 * @returns         - audit entry with independent before and after snapshots
 */
export function recordChange(
  record: RecordSnapshot,
  mutation: (r: RecordSnapshot) => RecordSnapshot,
  changedBy: string,
): AuditEntry {
  const before = record;
  const after = mutation(record);
 
  return {
    recordId: record.id,
    before,
    after,
    changedBy,
    timestamp: Date.now(),
  };
}