# Audit History
URL: https://pro.rv-grid.com/api/audit-history/
Source: src/content/docs/api/audit-history.md
## Module Extensions

### `HTMLRevoGridElement` (Extended from `@revolist/revogrid`)

```ts
interface HTMLRevoGridElement {
  auditHistory?: AuditHistoryConfig
}
```

---

### `AdditionalData` (Extended from `@revolist/revogrid`)

```ts
interface AdditionalData {
  /**
       * @deprecated Use the direct `grid.auditHistory` property instead.
       */
      auditHistory?: AuditHistoryConfig
}
```

---

### `HTMLRevoGridElementEventMap` (Extended from `global`)

```ts
interface HTMLRevoGridElementEventMap {
  auditrecord: AuditRecord;
  auditrecordsloaded: AuditRecord[];
  auditerror: AuditHistoryError;
  beforeauditrestore: AuditRestoreEvent;
  auditrestore: AuditRestoreEvent
}
```

## Plugin API

### `createLocalStorageAuditHistoryAdapter`

```ts
export function createLocalStorageAuditHistoryAdapter(storageKey = DEFAULT_STORAGE_KEY): AuditHistoryStorageAdapter;
```

---

### `AuditHistoryPlugin`

#### Dependencies

- **Required** `EventManagerPlugin`: Requires EventManagerPlugin to receive normalized edit and paste events.
- **Auto-installed** `HistoryPlugin`: Auto-installs or reuses HistoryPlugin for undo/redo shortcuts and replay integration.

```ts
class AuditHistoryPlugin {
  getRecords(filter?: AuditHistoryFilter): AuditRecord[];

  getCellHistory(rowId: string | number, column: ColumnProp): AuditRecord[];

  getRowHistory(rowId: string | number): AuditRecord[];

  getRecord(id: string): AuditRecord | undefined;

  getTransaction(transactionId: string): AuditRecord[];

  getLastChange(rowId: string | number, column?: ColumnProp): AuditChange | undefined;

  getStats(filter?: AuditHistoryFilter): AuditHistoryStats;

  getRowIdentity(row: DataType | undefined, rowIndex: number, rowType: DimensionRows): string | undefined;

  clear(): boolean;

  replaceRecords(records: AuditRecord[], options:;

  recordEvent(input: AuditRecordEventInput): AuditRecord | undefined;

  createSnapshot(label: string, options: AuditSnapshotOptions =;

  restoreSnapshot(recordOrId: AuditRecord | string): boolean;

  async refreshRecords(options:;

  exportRecords(options: AuditHistoryExportOptions =;

  canRestoreRecord(context: AuditHistoryRestoreContext): boolean;

  restoreCell(change: AuditChange): boolean;

  restoreRow(recordOrRowId: AuditRecord | string | number): boolean;

  restoreTransaction(transactionId: string): boolean;
}
```

---

### `AuditUser`

```ts
export type AuditUser = {
  id: string;
  name?: string;
  email?: string;
};
```

---

### `BuiltInAuditActionType`

```ts
export type BuiltInAuditActionType =
  | 'cell-change'
  | 'bulk-paste'
  | 'row-added'
  | 'row-deleted'
  | 'row-restored'
  | 'undo'
  | 'redo'
  | 'restore-cell'
  | 'restore-row'
  | 'restore-transaction'
  | 'api-sync'
  | 'formula-update'
  | 'snapshot-created'
  | 'snapshot-restored';
```

---

### `AuditActionType`

```ts
export type AuditActionType = BuiltInAuditActionType | (string & {});
```

---

### `AuditHistorySource`

```ts
export type AuditHistorySource =
  | 'manual'
  | 'paste'
  | 'api'
  | 'formula'
  | 'restore'
  | 'snapshot'
  | 'system';
```

---

### `AuditRecordPresentation`

```ts
export type AuditRecordPresentation = {
  source?: AuditHistorySource;
  verb?: string;
  targetLabel?: string;
  detailLabel?: string;
  rangeLabel?: string;
  avatarLabel?: string;
  avatarIndex?: number;
  avatarColor?: string;
  accent?: boolean;
};
```

---

### `AuditChangePresentation`

```ts
export type AuditChangePresentation = {
  cellLabel?: string;
  columnLabel?: string;
};
```

---

### `AuditChange`

```ts
export type AuditChange = {
  id: string;
  rowId?: string;
  rowIndex?: number;
  rowType: DimensionRows;
  column?: ColumnProp;
  oldValue?: unknown;
  newValue?: unknown;
  oldRow?: DataType;
  newRow?: DataType;
  metadata?: Record<string, unknown>;
  presentation?: AuditChangePresentation;
};
```

---

### `AuditRecord`

```ts
export type AuditRecord = {
  id: string;
  transactionId: string;
  type: AuditActionType;
  changedAt: string;
  changedBy: AuditUser;
  changes: AuditChange[];
  metadata?: Record<string, unknown>;
  presentation?: AuditRecordPresentation;
};
```

---

### `AuditHistoryFilter`

```ts
export type AuditHistoryFilter = {
  rowId?: string | number;
  column?: ColumnProp;
  userId?: string;
  userEmail?: string;
  actionType?: AuditActionType;
  transactionId?: string;
  dateFrom?: string | Date;
  dateTo?: string | Date;
};
```

---

### `AuditHistoryStorageAdapter`

```ts
export type AuditHistoryStorageAdapter = {
  load?: () => AuditRecord[] | Promise<AuditRecord[]>;
  save?: (records: AuditRecord[]) => void | Promise<void>;
  append?: (record: AuditRecord, records: AuditRecord[]) => void | Promise<void>;
  clear?: () => void | Promise<void>;
};
```

---

### `AuditHistoryError`

```ts
export type AuditHistoryError = {
  phase:
    | 'get-current-user'
    | 'metadata'
    | 'sanitize'
    | 'storage-load'
    | 'storage-save'
    | 'storage-append'
    | 'storage-clear'
    | 'on-record'
    | 'restore'
    | 'export'
    | 'replace-records'
    | 'record-event'
    | 'track-record'
    | 'snapshot';
  error: unknown;
  record?: AuditRecord;
};
```

---

### `AuditHistoryRestoreContext`

```ts
export type AuditHistoryRestoreContext = {
  type: AuditRestoreType;
  record?: AuditRecord;
  change?: AuditChange;
  transactionId?: string;
};
```

---

### `AuditHistoryStats`

```ts
export type AuditHistoryStats = {
  totalRecords: number;
  totalChanges: number;
  firstChangedAt?: string;
  lastChangedAt?: string;
  byType: Partial<Record<AuditActionType, number>>;
  byUser: Record<string, number>;
};
```

---

### `AuditHistoryExportFormat`

```ts
export type AuditHistoryExportFormat = 'json' | 'csv';
```

---

### `AuditHistoryExportOptions`

```ts
export type AuditHistoryExportOptions = {
  format?: AuditHistoryExportFormat;
  filter?: AuditHistoryFilter;
  includeMetadata?: boolean;
};
```

---

### `AuditRecordTrackContext`

```ts
export type AuditRecordTrackContext = {
  type: AuditActionType;
  changes: AuditChange[];
  source?: AuditHistorySource;
  metadata?: Record<string, unknown>;
  record: AuditRecord;
  event?: unknown;
};
```

---

### `AuditHistoryConfig`

```ts
export type AuditHistoryConfig = {
  getCurrentUser?: () => AuditUser;
  getMetadata?: (context: { type: AuditActionType; changes: AuditChange[] }) => Record<string, unknown> | undefined;
  rowIdProp?: string;
  getRowId?: (
    row: DataType,
    context: { rowIndex: number; rowType: DimensionRows },
  ) => string | number | undefined;
  sanitizeValue?: (
    value: unknown,
    context: {
      rowId?: string;
      rowIndex?: number;
      rowType: DimensionRows;
      column?: ColumnProp;
      direction: 'old' | 'new';
    },
  ) => unknown;
  shouldTrackChange?: (
    change: Omit<AuditChange, 'id'>,
    context: { type: AuditActionType },
  ) => boolean;
  shouldTrackRecord?: (context: AuditRecordTrackContext) => boolean;
  trackedActionTypes?: AuditActionType[];
  ignoredActionTypes?: AuditActionType[];
  ignoredColumns?: ColumnProp[] | ((context: { column?: ColumnProp; rowType: DimensionRows; rowId?: string }) => boolean);
  captureSourceUpdates?: boolean;
  immutable?: boolean;
  canRestore?: (context: AuditHistoryRestoreContext) => boolean;
  storage?: 'memory' | 'localStorage' | 'custom';
  storageKey?: string;
  storageAdapter?: AuditHistoryStorageAdapter;
  storageProviders?: AuditHistoryStorageAdapter[];
  mergeStorageProviders?: boolean;
  records?: AuditRecord[];
  maxRecords?: number;
  disabled?: boolean;
  onAuditRecord?: (record: AuditRecord) => void | Promise<void>;
  onAuditError?: (error: AuditHistoryError) => void;
  onRecordsLoaded?: (records: AuditRecord[]) => void;
};
```

---

### `AuditEventChangeInput` (Extended from `index.ts`)

```ts
export type AuditEventChangeInput = Omit<AuditChange, 'id'> & { id?: string };
```

---

### `AuditRecordEventInput`

```ts
export type AuditRecordEventInput = {
  type: AuditActionType;
  changes?: AuditEventChangeInput[];
  changedAt?: string;
  changedBy?: AuditUser;
  transactionId?: string;
  metadata?: Record<string, unknown>;
  presentation?: AuditRecordPresentation;
  allowEmpty?: boolean;
};
```

---

### `AuditSnapshotOptions`

```ts
export type AuditSnapshotOptions = {
  rowType?: DimensionRows;
  rows?: DataType[];
  metadata?: Record<string, unknown>;
  presentation?: AuditRecordPresentation;
};
```

---

### `AuditRestoreType`

```ts
export type AuditRestoreType = 'cell' | 'row' | 'transaction' | 'snapshot';
```

---

### `AuditRestoreEvent`

```ts
export type AuditRestoreEvent = {
  type: AuditRestoreType;
  record?: AuditRecord;
  change?: AuditChange;
  transactionId?: string;
};
```

---

### `defineAuditHistoryPanel`

Renders the Audit History panel into `el` for the given RevoGrid element.

The grid must have `AuditHistoryPlugin` installed.

```ts
export function defineAuditHistoryPanel(el: HTMLElement, grid: HTMLRevoGridElement, options: AuditHistoryPanelOptions =;
```

---

### `AuditHistoryPanelDateFormatContext`

```ts
export type AuditHistoryPanelDateFormatContext = {
  mode: 'time' | 'day' | 'filter';
  record?: AuditRecord;
};
```

---

### `AuditHistoryPanelEvents`

```ts
export type AuditHistoryPanelEvents = {
  beforeRecordSelect?: (context: AuditHistoryPanelRecordContext) => boolean | void;
  beforeCompareOpen?: (context: AuditHistoryPanelRecordContext) => boolean | void;
  beforeJumpToCell?: (context: AuditHistoryPanelJumpContext) => boolean | void;
  beforeRestore?: (context: AuditHistoryPanelRestoreContext) => boolean | void;
  beforeExport?: (context: AuditHistoryPanelExportContext) => boolean | void;
};
```

---

### `AuditHistoryPanelExportContext`

```ts
export type AuditHistoryPanelExportContext = {
  format: AuditHistoryExportFormat;
};
```

---

### `AuditHistoryPanelJumpContext`

```ts
export type AuditHistoryPanelJumpContext = {
  record: AuditRecord;
  change: AuditChange;
};
```

---

### `AuditHistoryPanelLabels`

```ts
export type AuditHistoryPanelLabels = {
  title: string;
  liveStatus: string;
  recordsSummary: (count: number) => string;
  changesSummary: (count: number) => string;
  allTab: string;
  rowTab: string;
  cellTab: string;
  tableTab: string;
  selectedCell: (rowId: string, column: ColumnProp) => string;
  selectedRow: (rowId: string) => string;
  export: string;
  exportCsv: string;
  exportJson: string;
  exportCsvTitle: string;
  exportJsonTitle: string;
  close: string;
  openPanel: string;
  searchPlaceholder: string;
  searchAriaLabel: string;
  searchShortcut: string;
  userPlaceholder: string;
  userAriaLabel: string;
  columnAriaLabel: string;
  actionAriaLabel: string;
  dateFromAriaLabel: string;
  dateToAriaLabel: string;
  allColumns: string;
  allActions: string;
  clearFilters: string;
  addFilter: string;
  removeFilter: (label: string) => string;
  noRecords: string;
  noComparableRecord: string;
  scopedRecordCount: (visibleChanges: number, totalChanges: number) => string;
  changedBy: (changedAt: string, user: string) => string;
  rowTarget: (rowId: string | undefined, column: ColumnProp | undefined) => string;
  cellValues: (oldValue: string, newValue: string) => string;
  rowSnapshotAvailable: string;
  rowRemoved: string;
  restoreCell: string;
  restoreRow: string;
  restoreTransaction: string;
  restoreSnapshot: string;
  jumpToCell: string;
  revertAll: string;
  moreActions: string;
  compare: string;
  compareTitle: string;
  compareBefore: string;
  compareAfter: string;
  closeCompare: string;
  compareEmpty: string;
  viewChanges: (count: number) => string;
  previousPage: string;
  nextPage: string;
  pageStatus: (currentPage: number, pageCount: number) => string;
  dayToday: string;
  dayYesterday: string;
  sourceLabels: Record<AuditHistorySource, string>;
  actions: Partial<Record<AuditActionType, string>>;
  actionVerbs: Partial<Record<AuditActionType, string>>;
};
```

---

### `AuditHistoryPanelLabelsOptions` (Extended from `index.ts`)

```ts
export type AuditHistoryPanelLabelsOptions = Partial<Omit<AuditHistoryPanelLabels, 'actions' | 'actionVerbs' | 'sourceLabels'>> & {
  actions?: Partial<Record<AuditActionType, string>>;
  actionVerbs?: Partial<Record<AuditActionType, string>>;
  sourceLabels?: Partial<Record<AuditHistorySource, string>>;
};
```

---

### `AuditHistoryPanelHandle`

```ts
export type AuditHistoryPanelHandle = {
  destroy: () => void;
  setPlacement: (placement: AuditHistoryPanelPlacement) => void;
  refresh: () => Promise<void>;
};
```

---

### `AuditHistoryPanelOptions`

```ts
export type AuditHistoryPanelOptions = {
  pageSize?: number;
  allowExport?: boolean;
  allowCompare?: boolean | ((context: AuditHistoryPanelRecordContext) => boolean);
  allowClose?: boolean;
  miniOnClose?: boolean;
  restoreActions?: false | AuditRestoreType[] | ((context: AuditHistoryPanelRestoreContext) => boolean);
  formatDate?: (value: string, context: AuditHistoryPanelDateFormatContext) => string;
  events?: AuditHistoryPanelEvents;
  placement?: AuditHistoryPanelPlacement;
  tooltips?: false | Partial<Record<AuditHistoryPanelTooltipKey, string | false>>;
  labels?: AuditHistoryPanelLabelsOptions;
};
```

---

### `AuditHistoryPanelRecordContext`

```ts
export type AuditHistoryPanelRecordContext = {
  record: AuditRecord;
  changes: AuditChange[];
};
```

---

### `AuditHistoryPanelRestoreContext`

```ts
export type AuditHistoryPanelRestoreContext = {
  type: AuditRestoreType;
  record?: AuditRecord;
  change?: AuditChange;
  transactionId?: string;
};
```

---

### `AuditHistoryPanelPlacement`

```ts
export type AuditHistoryPanelPlacement = 'right' | 'left' | 'top' | 'bottom' | 'none';
```

---

### `AuditHistoryPanelTooltipKey`

```ts
export type AuditHistoryPanelTooltipKey =
  | 'totalRecords'
  | 'totalChanges'
  | 'selectedScope'
  | 'searchFilter'
  | 'userFilter'
  | 'columnFilter'
  | 'actionFilter'
  | 'dateFromFilter'
  | 'dateToFilter'
  | 'clearFilters';
```

---

### `AUDIT_HISTORY_STORAGE_KEY`

```ts
AUDIT_HISTORY_STORAGE_KEY: string;
```

---

### `cloneValue`

```ts
export function cloneValue<T>(value: T): T;
```

---

### `cloneChange`

```ts
export function cloneChange(change: AuditChange): AuditChange;
```

---

### `cloneRecord`

```ts
export function cloneRecord(record: AuditRecord): AuditRecord;
```

---

### `normalizeRowId`

```ts
export function normalizeRowId(rowId: string | number | undefined): string | undefined;
```

---

### `toTime`

```ts
export function toTime(value: string | Date | undefined, fallback: number);
```

---

### `shouldIncludeRecord`

```ts
export function shouldIncludeRecord(record: AuditRecord, filter?: AuditHistoryFilter);
```

---

### `trimRecords`

```ts
export function trimRecords(records: AuditRecord[], maxRecords: number): AuditRecord[];
```

---

### `mergeRecords`

```ts
export function mergeRecords(current: AuditRecord[], next: AuditRecord[]): AuditRecord[];
```

---

### `createAuditStats`

```ts
export function createAuditStats(records: AuditRecord[], filter?: AuditHistoryFilter): AuditHistoryStats;
```

---

### `stringifyExportValue`

```ts
export function stringifyExportValue(value: unknown): string;
```

---

### `exportAuditRecords`

```ts
export function exportAuditRecords(records: AuditRecord[], options: AuditHistoryExportOptions =;
```
