Dyrected
Features

Audit Trail

Automatic system metadata on every document and optional full activity logging via the __audit collection.

Dyrected tracks document lifecycle through two complementary layers: system metadata that is always injected, and activity logs that are opt-in per collection.


System Metadata (Always On)

Every collection automatically receives the following fields. You do not need to declare them in your fields array — Dyrected injects them during config normalization.

FieldTypeDescription
createdAtdateISO timestamp set on creation.
updatedAtdateISO timestamp updated on every write.
createdBytextID of the user who created the document.
updatedBytextID of the user who last modified the document.

These fields are read-only and hidden in the Admin UI. They are populated automatically from the authenticated user's JWT on every POST (create) and PATCH (update) request.


Activity Logs (audit: true)

For a complete change history — including document snapshots and field-level diffs — enable audit logging on a collection:

const posts = defineCollection({
  slug: 'posts',
  audit: true, // enables logging to __audit
  fields: [
    { name: 'title', type: 'text' },
    { name: 'body',  type: 'richText' },
  ],
})

When audit: true, every create, update, and delete operation writes an entry to the built-in __audit collection.

The __audit Schema

FieldDescription
entitySlug of the collection affected.
entityIdID of the document affected.
actioncreate, update, delete, or publish.
userIdID of the user who performed the action.
userCollectionWhich auth collection the user belongs to (e.g. __admins).
userEmailEmail of the acting user at the time of the action.
changesJSON diff — for update, an object of { field: { old, new } } pairs.
snapshotFull document copy at the time of the action, useful for rollback.
timestampISO timestamp of the action.

Example Audit Entry (update)

{
  "entity": "posts",
  "entityId": "abc123",
  "action": "update",
  "userId": "user_01",
  "userEmail": "[email protected]",
  "changes": {
    "title": { "old": "Hello World", "new": "Hello Dyrected" }
  },
  "snapshot": {
    "id": "abc123",
    "title": "Hello Dyrected",
    "body": "..."
  },
  "timestamp": "2026-05-11T10:23:00.000Z"
}

Querying Audit Logs

The __audit collection is queryable via the standard collections API:

// Fetch audit history for a specific document
const logs = await client.collection('__audit').find({
  where: { entity: { equals: 'posts' }, entityId: { equals: 'abc123' } },
  sort: '-timestamp',
})

Notes

  • Audit logging never blocks the primary write operation — if logging fails, the error is recorded to the server console but the original request succeeds.
  • The __audit collection is hidden in the Admin UI by default. You can surface it by adding it to your config explicitly with admin: { hidden: false }.
  • Diffs are computed as a shallow comparison. Nested objects are compared by JSON serialization.

On this page