> ## Documentation Index
> Fetch the complete documentation index at: https://developer.kodexa.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Audit Trail

> Track the revision history of data objects, attributes, and tags inside Kodexa documents using the audit trail to see who changed what and when.

The audit trail provides a comprehensive history of all changes made to data objects, data attributes, and tags within a document. Each modification is recorded as part of a revision, enabling you to track who changed what and when.

## Overview

The audit system records:

* **Revisions**: Snapshots representing a set of related changes
* **Data Object Audits**: Creation, modification, and deletion of data objects
* **Data Attribute Audits**: Changes to attribute values and properties
* **Tag Audits**: Changes to content node tags

## Accessing Audit Data

### List Revisions

<CodeGroup>
  ```python Python theme={null}
  from kodexa_document import Document

  with Document.from_kddb("processed.kddb") as doc:
      # List all revisions
      revisions = doc.audit.list_revisions()

      for rev in revisions:
          print(f"Revision {rev['id']}")
          print(f"  Created: {rev.get('createdAt')}")
          print(f"  Actor: {rev.get('actorUri')}")
          print(f"  Comment: {rev.get('comment')}")
  ```

  ```typescript TypeScript theme={null}
  import { Kodexa } from '@kodexa-ai/document-wasm-ts';

  async function listRevisions() {
    await Kodexa.init();
    const doc = await Kodexa.fromBlob(kddbBlob);

    try {
      // List all revisions
      const revisions = await doc.audit.listRevisions();

      for (const rev of revisions) {
        console.log(`Revision ${rev.id}`);
        console.log(`  Created: ${rev.createdAt}`);
        console.log(`  Actor: ${rev.actorUri}`);
        console.log(`  Comment: ${rev.comment}`);
      }
    } finally {
      doc.dispose();
    }
  }
  ```
</CodeGroup>

### Get Revision Details

<CodeGroup>
  ```python Python theme={null}
  with Document.from_kddb("processed.kddb") as doc:
      # Get details for a specific revision
      details = doc.audit.get_revision_details(revision_id=1)
      if details:
          print(f"Revision: {details}")

      # Get a single revision
      rev = doc.audit.get_revision(revision_id=1)
      if rev:
          print(f"Revision {rev['id']}: {rev.get('comment')}")
  ```

  ```typescript TypeScript theme={null}
  async function getRevisionDetails() {
    await Kodexa.init();
    const doc = await Kodexa.fromBlob(kddbBlob);

    try {
      // Get details for a specific revision
      const details = await doc.audit.getRevisionDetails(1);
      if (details) {
        console.log('Revision details:', details);
      }

      // Get a single revision
      const rev = await doc.audit.getRevision(1);
      if (rev) {
        console.log(`Revision ${rev.id}: ${rev.comment}`);
      }
    } finally {
      doc.dispose();
    }
  }
  ```
</CodeGroup>

## Entity History

### Data Object History

Track all changes to a specific data object across revisions:

<CodeGroup>
  ```python Python theme={null}
  with Document.from_kddb("processed.kddb") as doc:
      # Get the full history of a data object
      history = doc.audit.get_data_object_history(data_object_id=1)

      for entry in history:
          print(f"Action: {entry.get('action')}")
          print(f"  Revision: {entry.get('revisionId')}")
          print(f"  Timestamp: {entry.get('createdAt')}")
  ```

  ```typescript TypeScript theme={null}
  async function getObjectHistory() {
    await Kodexa.init();
    const doc = await Kodexa.fromBlob(kddbBlob);

    try {
      // Get the full history of a data object
      const history = await doc.audit.getDataObjectHistory(1);

      for (const entry of history) {
        console.log(`Action: ${entry.action}`);
        console.log(`  Revision: ${entry.revisionId}`);
        console.log(`  Timestamp: ${entry.createdAt}`);
      }
    } finally {
      doc.dispose();
    }
  }
  ```
</CodeGroup>

### Data Attribute History

Track changes to a specific data attribute:

<CodeGroup>
  ```python Python theme={null}
  with Document.from_kddb("processed.kddb") as doc:
      # Get the full history of a data attribute
      history = doc.audit.get_data_attribute_history(data_attribute_id=1)

      for entry in history:
          print(f"Action: {entry.get('action')}")
          print(f"  Old Value: {entry.get('oldValue')}")
          print(f"  New Value: {entry.get('newValue')}")
  ```

  ```typescript TypeScript theme={null}
  async function getAttributeHistory() {
    await Kodexa.init();
    const doc = await Kodexa.fromBlob(kddbBlob);

    try {
      const history = await doc.audit.getDataAttributeHistory(1);

      for (const entry of history) {
        console.log(`Action: ${entry.action}`);
        console.log(`  Old Value: ${entry.oldValue}`);
        console.log(`  New Value: ${entry.newValue}`);
      }
    } finally {
      doc.dispose();
    }
  }
  ```
</CodeGroup>

### Tag History

Track changes to content node tags:

<CodeGroup>
  ```python Python theme={null}
  with Document.from_kddb("processed.kddb") as doc:
      # Get the full history of a tag
      history = doc.audit.get_tag_history(tag_id=1)

      for entry in history:
          print(f"Action: {entry.get('action')}")
          print(f"  Revision: {entry.get('revisionId')}")
  ```

  ```typescript TypeScript theme={null}
  async function getTagHistory() {
    await Kodexa.init();
    const doc = await Kodexa.fromBlob(kddbBlob);

    try {
      const history = await doc.audit.getTagHistory(1);

      for (const entry of history) {
        console.log(`Action: ${entry.action}`);
        console.log(`  Revision: ${entry.revisionId}`);
      }
    } finally {
      doc.dispose();
    }
  }
  ```
</CodeGroup>

## Revision-Based Queries

Get all changes of a specific type for a given revision:

<CodeGroup>
  ```python Python theme={null}
  with Document.from_kddb("processed.kddb") as doc:
      revisions = doc.audit.list_revisions()

      for rev in revisions:
          rev_id = rev['id']

          # Get all data object changes in this revision
          obj_audits = doc.audit.get_data_object_audits_by_revision(rev_id)

          # Get all data attribute changes in this revision
          attr_audits = doc.audit.get_data_attribute_audits_by_revision(rev_id)

          # Get all tag changes in this revision
          tag_audits = doc.audit.get_tag_audits_by_revision(rev_id)

          print(f"Revision {rev_id}: "
                f"{len(obj_audits)} object changes, "
                f"{len(attr_audits)} attribute changes, "
                f"{len(tag_audits)} tag changes")
  ```

  ```typescript TypeScript theme={null}
  async function revisionBasedQueries() {
    await Kodexa.init();
    const doc = await Kodexa.fromBlob(kddbBlob);

    try {
      const revisions = await doc.audit.listRevisions();

      for (const rev of revisions) {
        // Get all data object changes in this revision
        const objAudits = await doc.audit.getDataObjectAuditsByRevision(rev.id);

        // Get all data attribute changes in this revision
        const attrAudits = await doc.audit.getDataAttributeAuditsByRevision(rev.id);

        // Get all tag changes in this revision
        const tagAudits = await doc.audit.getTagAuditsByRevision(rev.id);

        console.log(`Revision ${rev.id}: ` +
          `${objAudits.length} object changes, ` +
          `${attrAudits.length} attribute changes, ` +
          `${tagAudits.length} tag changes`);
      }
    } finally {
      doc.dispose();
    }
  }
  ```
</CodeGroup>

## API Reference

### AuditAccessor Methods

| Method (Python)                             | Method (TypeScript)                    | Description                   |
| ------------------------------------------- | -------------------------------------- | ----------------------------- |
| `list_revisions()`                          | `listRevisions()`                      | List all revisions            |
| `get_revision(id)`                          | `getRevision(id)`                      | Get a specific revision       |
| `get_revision_details(id)`                  | `getRevisionDetails(id)`               | Get detailed revision info    |
| `get_data_object_history(id)`               | `getDataObjectHistory(id)`             | History of a data object      |
| `get_data_attribute_history(id)`            | `getDataAttributeHistory(id)`          | History of a data attribute   |
| `get_tag_history(id)`                       | `getTagHistory(id)`                    | History of a tag              |
| `get_data_object_audits_by_revision(id)`    | `getDataObjectAuditsByRevision(id)`    | Object changes in revision    |
| `get_data_attribute_audits_by_revision(id)` | `getDataAttributeAuditsByRevision(id)` | Attribute changes in revision |
| `get_tag_audits_by_revision(id)`            | `getTagAuditsByRevision(id)`           | Tag changes in revision       |
