How NocoDB Generates and Accesses Audit Logs: A Technical Deep Dive
NocoDB automatically captures every data-changing operation as structured audit entries using model hooks and the generateAuditV1Payload utility in utils/audit.ts, persists them to the nc_audit_v2 table via the Audit model, and exposes them through the AuditsService REST API layer consumed by the frontend Pinia store.
NocoDB is an open-source Airtable alternative that provides comprehensive audit logging to track all data modifications across your projects. Understanding how NocoDB generates and accesses audit logs enables administrators to monitor changes, ensure compliance, and debug issues with full visibility into who changed what and when.
How NocoDB Generates Audit Logs
Audit log generation in NocoDB follows a structured pipeline that begins at the database model layer and ends with a persisted JSON payload containing complete contextual metadata.
Triggering Events via Model Hooks
NocoDB intercepts data operations through lifecycle hooks defined in the model layer. When operations such as afterInsert, afterUpdate, or afterDelete execute, they trigger the audit logging mechanism. These hooks capture the mutation event along with the request context, user identity, and affected row data.
Building the Audit Payload
The generateAuditV1Payload function in utils/audit.ts constructs a standardized JSON payload adhering to the AuditV1<T> schema. This function aggregates:
- Request context:
user,ip,workspace,base, andmodelidentifiers - Row identification:
row_idparameters linking the audit to specific records - Human-readable details: Objects containing before/after values and operation metadata
Extracting Metadata for Context
To ensure audit logs contain sufficient structural context, utils/audit.ts provides specialized extraction utilities:
extractColMetaForAudit: Captures column metadata and data typesextractRefColumnIfFound: Identifies reference/foreign key relationshipsextractViewRelatedProps: Includes view-specific properties when changes occur within specific views
Storing Audit Logs in the Database
Once generated, audit payloads persist through a dedicated model layer designed for high-volume logging operations.
The Audit Model and nc_audit_v2 Table
The Audit model defined in models/Audit.ts handles database persistence. Its static insert method writes records to the nc_audit_v2 table, which stores the complete JSON payload along with indexing fields for efficient querying.
The model also exposes recordAuditList(context, params), a query method supporting filtered retrieval by project, model, operation type, date range, and pagination parameters. This method enables the service layer to fetch audit logs with precise granularity while maintaining performance across large datasets.
Accessing and Retrieving Audit Logs
NocoDB exposes audit data through a layered architecture separating data access, business logic, and presentation concerns.
The AuditsService API Layer
The AuditsService in services/audits.service.ts wraps the Audit.recordAuditList method, applying additional formatting and business logic before exposing data to API controllers. This service layer handles authorization checks and data transformation to ensure clients receive properly structured audit entries.
REST API Endpoints
Clients retrieve audit logs via the standard REST endpoint:
GET /api/v1/db/meta/projects/:projectId/audits
This endpoint accepts query parameters for limit, offset, operation type filtering, and date ranges, returning paginated JSON responses containing the audit entry list and total count.
Frontend Integration with Pinia Store
The NocoDB GUI consumes audit data through the reactive Pinia store located at packages/nc-gui/store/audits.ts. This store manages state for the Audit tab interface, fetching data from the REST API and maintaining reactive state for UI components. The store handles loading states, caching, and real-time updates when new audit entries are created.
Implementation Examples
The following examples demonstrate how to generate audit entries programmatically and retrieve them via API calls.
Generating Audit Entries in Model Hooks
When implementing custom model hooks, use the generateAuditV1Payload utility to create compliant audit records:
import { generateAuditV1Payload } from '~/utils/audit';
import { Audits } from '~/models';
// Example: after a row is updated
async function afterUpdateHook(context: NcContext, model: Model, rowId: string, oldRow, newRow) {
const payload = await generateAuditV1Payload('UPDATE', {
context,
row_id: rowId,
details: {
// include only non-system fields that changed
...newRow,
},
// optional: pass the HTTP request if you have it
req: context?.req,
});
// Persist the audit record
await Audits.insert(payload);
}
Fetching Audit Logs via REST API
To retrieve audit logs from client applications or external integrations:
// Using fetch from the front-end
const projectId = '12345';
const response = await fetch(
`/api/v1/db/meta/projects/${projectId}/audits?limit=50&offset=0`,
{
credentials: 'include',
headers: { 'Content-Type': 'application/json' },
}
);
const { list, count } = await response.json(); // list = array of audit entries
Using the Vue Store in NC-GUI
For frontend development within the NocoDB ecosystem, leverage the existing Pinia store:
import { useAuditsStore } from '@/store/audits';
const auditsStore = useAuditsStore();
await auditsStore.fetchAudits({ projectId: '12345', limit: 100 });
console.log(auditsStore.audits); // Reactive list shown in the Audit tab
Summary
- Audit generation occurs through model hooks (
afterInsert,afterUpdate,afterDelete) that invokegenerateAuditV1Payloadinutils/audit.tsto create structuredAuditV1<T>schema payloads. - Metadata enrichment happens via helper functions including
extractColMetaForAuditandextractRefColumnIfFoundto capture column and relationship context. - Persistence flows through the
Auditmodel inmodels/Audit.ts, which writes to thenc_audit_v2table and provides therecordAuditListquery method. - API access is managed by
AuditsServiceinservices/audits.service.ts, exposing theGET /api/v1/db/meta/projects/:projectId/auditsendpoint with full filtering and pagination support. - Frontend consumption utilizes the Pinia store at
packages/nc-gui/store/audits.tsto provide reactive audit data to the user interface.
Frequently Asked Questions
What database operations trigger audit logs in NocoDB?
NocoDB generates audit logs for all data-changing operations including insertions, updates, deletions, bulk actions, and link/unlink operations between records. These triggers activate through model lifecycle hooks that capture the operation type, user context, and row modifications automatically.
How are audit logs structured in the NocoDB database?
Audit logs follow the AuditV1<T> JSON schema stored in the nc_audit_v2 table. Each record contains request metadata (user ID, IP address, workspace), model references, row identifiers, and a detailed changes object. The schema supports extensible metadata through functions like extractColMetaForAudit that append column definitions and view properties.
Can I query audit logs programmatically via the NocoDB API?
Yes, the REST API endpoint GET /api/v1/db/meta/projects/:projectId/audits provides programmatic access to audit logs with support for filtering by operation type, date ranges, and pagination parameters. The endpoint returns a JSON object containing a list array of audit entries and a count integer for total records matching your criteria.
Where are audit logs displayed in the NocoDB user interface?
Audit logs are displayed in the dedicated Audit tab within the NocoDB interface. This tab consumes data through the Pinia store defined in packages/nc-gui/store/audits.ts, which fetches records from the backend API and presents them in a searchable, paginated table showing operation history, user details, and change summaries.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →