Six months of logs nobody can read
Every feature invents its own log format. Then a customer asks "who deleted this?" and the rows can't even agree on what an actor is.
A clean record of who did what, and when.
Every important change gets logged automatically: who did it, what changed, when. Admins can browse and export the history. You never build event plumbing yourself.
90 days
longest export window
10,000
record cap per export
5
kinds of actors the log can name
Without a shared foundation, every team rebuilds these edge cases — differently.
Every feature invents its own log format. Then a customer asks "who deleted this?" and the rows can't even agree on what an actor is.
A retried job writes a duplicate entry on every replay. Reviewers stop trusting a trail that repeats itself.
An unlimited download button eventually asks for years of rows in one request. You find out during a compliance review, at the worst possible moment.
The mechanism end to end, as implemented in the repository.
Every event goes through one function
Server code logs events using types from a central registry. Half-built event types throw an error instead of quietly writing junk rows.
Each event gets a stamped envelope
Version, actor, resource, outcome, and a hashed IP get added and validated before saving. Raw IP addresses are never stored.
Admins browse their own history
Listing checks admin role and plan entitlement on the server, then pages through rows 100 at a time, always scoped to one organization.
Exports run inside hard limits
Exports allow up to 90 days and 10,000 records in JSON or NDJSON, and the export itself becomes a new audit event.
Interactive example
This walkthrough demonstrates the implemented backend contract without using an account, credentials, or provider calls.
Interactive example
Deterministic sample data only. No account, provider, or network connection is used by the interaction.
Highlights
Every event goes through one function, and a retried job can't write the same entry twice.
Only org admins on plans with the audit feature can browse or export, checked on the server every time.
Exports cap at 90 days and 10,000 records, and every export is itself logged.
Engineering guarantees
The log records what happened; it doesn't control access, so every browse and export re-checks permissions on its own. Retention periods are declared in the registry, but running the purge job that enforces them is up to your deployment.
The boundary above is code, not a claim. These files carry the contract:
src/features/enterprise/server.tssrc/registries/audit-events.tssrc/features/enterprise/contracts.tsThese capabilities share contracts and boundaries with this one.
The docs describe the same contracts this page demonstrates.