Audit
Immutable trail of every data operation
The audit block records who did what, to which record, and when. When enabled, a database audit transport is attached to the logger and writes structured rows to the audit_logs table — capturing the entity name, entity id, acting user, operation and outcome.
Because it hangs off the central logger, audit coverage spans both generated entity routes (create/update/delete) and the auth routes (login, logout, password change, session revocation), giving you one coherent security timeline.
You control the cost/coverage trade-off per operation type: log every read, or only the writes that mutate state.
Enabling audit#
A single switch attaches the database audit transport. Without it, audit entries are not persisted.
enabledbooleanOptionalTurn on persistent audit logging. On startup the framework wires a DatabaseAuditTransport to the audit_logs table; every audited operation then writes a row with entity_name, entity_id, user_id, action and timestamp.
falsePer-operation toggles#
Choose exactly which operation types are recorded. Reads (GET) are high-volume and often left off; mutations are usually all on. Omit actions entirely to accept the framework defaults.
1{2 "audit": {3 "enabled": true,4 "actions": {5 "GET": false,6 "INSERT": true,7 "UPDATE": true,8 "DELETE": true,9 "TOGGLE": true,10 "VERIFICATION": true11 }12 }13}actionsobjectOptionalBoolean switch per operation type.
GETbooleanOptionalRecord read access. High volume — enable only when you need read auditing (e.g. sensitive data access).
INSERTbooleanOptionalRecord row creation.
UPDATEbooleanOptionalRecord row updates.
DELETEbooleanOptionalRecord row deletions.
TOGGLEbooleanOptionalRecord soft enable/disable (is_active) toggles.
VERIFICATIONbooleanOptionalRecord verification decisions (approve/reject) from the approval flows.
Under the hood — what a row captures#
Audit isn't a separate subsystem — it's the logger's audit path. logger.audit() (and trace() when auditEnabled) builds an entry and the DatabaseAuditTransport writes it, so audit and logs share one component and one correlation id.
captured columnsaudit_logs rowOptionalEach row records id, entity_name, entity_id, operation_type, user_id, ip_address, user_agent, a human summary, the before/after old_values and new_values, plus the request path and query — a complete forensic record, not just 'who and when'.
old / new valuesstructured diffOptionalWrites capture the prior and resulting field values, so an audit row is also a diff: you can see exactly what changed, which is what makes the trail useful for compliance reviews and incident forensics.
correlationshared with logsOptionalBecause the same Logger writes both, an audit row and the request's log lines carry the same correlation id — you can pivot from 'this record changed' to the full request trace that changed it.
Related sections