Skip to content

Query API

Use AuditService.query() to search audit log entries with wildcard filters, deterministic keyset pagination, and tenant scoping.

Example

typescript
const result = await auditService.query({
  actorId: 'user-123',
  action: 'invoice.*',     // wildcard support
  targetType: 'Invoice',
  source: 'auto',
  result: 'success',
  from: new Date('2026-01-01'),
  to: new Date('2026-04-01'),
  limit: 50,
  includeTotal: false,
});
// -> { entries: AuditEntry[], nextCursor: string | null, hasMore: boolean }

if (result.hasMore) {
  await auditService.query({
    actorId: 'user-123',
    action: 'invoice.*',
    targetType: 'Invoice',
    source: 'auto',
    result: 'success',
    from: new Date('2026-01-01'),
    to: new Date('2026-04-01'),
    cursor: result.nextCursor!,
    limit: 50,
    includeTotal: false,
  });
}

Query Parameters

ParameterTypeDescription
actorIdstringFilter by actor ID
actionstringFilter by action name (supports wildcards, e.g. invoice.*)
targetTypestringFilter by target type
source'auto' | 'manual'Filter by automatic or manual audit source
result'success' | 'failure'Filter by audit result
fromDateStart of date range
toDateEnd of date range
limitnumberMaximum number of entries to return
cursorstringContinue after a previous page's nextCursor
includeTotalbooleanWhen false, skips the COUNT(*) query and omits total
tenantIdstringExplicitly scope to a tenant
allTenantsbooleanIntentional authorized cross-tenant admin read

Response Format

typescript
{
  entries: AuditEntry[];
  nextCursor: string | null;
  hasMore: boolean;
  total?: number;
}

Rows are ordered newest-first by (created_at, id). Cursors do not encode filters; keep the same filter set on each page unless you intentionally want a new filtered scan below the cursor boundary.

Single Entry Lookup

Use getById(id, options?) with the same tenant scoping rules:

typescript
const entry = await auditService.getById('audit-row-id', {
  tenantId: 'tenant-1',
});

Use allTenants: true only for deliberately authorized cross-tenant admin reads. tenantId and allTenants are mutually exclusive.

Released under the MIT License.