perf(backend): batch audit_log inserts into a buffered transaction (#817)

Every mutating /api/* request runs an individual INSERT into audit_log
which serializes against other writers under burst load (SQLite's
single-writer model). Buffer the writes in DatabaseService and flush
them in a single transaction either every second or once the buffer
reaches 100 entries, whichever comes first.

Read paths (getAuditLogs, getAuditLogsInRange, cleanupOldAuditLogs)
drain the buffer first so callers always see a consistent view, which
keeps the existing test pattern of insert-then-read working.

Graceful shutdown flushes before db.close() so no entries are lost on
clean exit. The 1s flush timer is unref'd so the buffer cannot keep
the process alive on its own. The CLI resetMfa script flushes
explicitly before returning since it exits before the timer fires.
This commit is contained in:
Anso
2026-04-28 00:59:04 -04:00
committed by GitHub
parent 18cf2e65e8
commit 5cf4323511
3 changed files with 84 additions and 3 deletions
+3
View File
@@ -47,6 +47,9 @@ export function resetMfaForUser(username: string): ResetMfaResult {
// Audit failure should not block the reset itself.
console.warn('[reset-mfa] audit log write failed:', (err as Error).message);
}
// The audit log buffer flushes on a 1s timer that the CLI process exits
// before reaching, so flush explicitly to make sure the entry persists.
db.flushAuditLogBuffer();
return { ok: true, message: `Two-factor authentication cleared for ${username}` };
}