Axerity Docs
Concepts

Audit trail

Why financial software needs append-only history, and how Axerity guarantees it.

In any accounting system, the answer to "what happened on date X, and who did it?" has to exist — regardless of subsequent edits or deletions. Otherwise the system isn't trustworthy enough for tax filings, dispute resolution, or formal audit.

Axerity guarantees this for both books and files.

The two audit logs

JournalEntryAudit captures every change to a transaction:

  • CREATE — when posted, with the full snapshot.
  • UPDATE — before + after snapshots.
  • DELETE — the snapshot at the moment of deletion.

FileAuditLog captures every file action:

  • UPLOAD, DOWNLOAD, RENAME, MOVE, DELETE.

Append-only

Both tables are append-only by convention. The code never updates or deletes rows. There's no UI or API path that does.

This is enforced at the kernel level (server-side helpers), not at the UI level. There is no client toggle that bypasses the audit write. Every mutation goes through helpers that write the audit row inside the same transaction.

What survives deletion

When you delete a transaction:

  • The row in journal_entry is gone.
  • The row in journal_entry_audit survives.
  • The entryId foreign key is nulled (via SetNull), but the before-snapshot in the audit row preserves everything: date, memo, reference, lines, attachments.

So even a deleted transaction is fully reconstructable from the audit log. This matters for "we deleted that by accident, what was on it?" moments — common in real bookkeeping.

How to query it

In the UI:

  • Transactions list → hover any row → clock icon → drawer slides in with full history for that entry.

In the REST API:

  • GET /v1/audit_log for files.
  • Journal entry audit isn't exposed via REST yet (it's via the in-app journal.audit RPC). Roadmap.

What it isn't

  • Not immutable in a cryptographic sense. There's no hash chain or blockchain. A privileged Postgres user with raw SQL access could modify rows directly. The guarantee is "no app path modifies the log" — sufficient for normal trust models, not sufficient for high-stakes adversarial scenarios.
  • Not legally binding without external audit. The log helps you prove things; it isn't itself a legal artifact.

Why this is a kernel-level concern

If audit logging lived in the UI ("write a log entry from the form submit handler"), any code path that skipped the form — the REST API, a future webhook handler, an admin tool — would bypass logging. By putting the writer alongside the mutation in the same transaction, every path that changes data leaves a trail. There is no way to mutate the books without it.

On this page