hazo_audit 1.0.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/CHANGE_LOG.md +72 -0
  2. package/README.md +138 -1
  3. package/SETUP_CHECKLIST.md +9 -0
  4. package/config/hazo_audit_config.ini.sample +14 -4
  5. package/dist/client/AuditViewer.d.ts +13 -0
  6. package/dist/client/AuditViewer.d.ts.map +1 -0
  7. package/dist/client/AuditViewer.js +52 -0
  8. package/dist/client/AuditViewer.js.map +1 -0
  9. package/dist/client/FieldAuditIcon.d.ts.map +1 -1
  10. package/dist/client/FieldAuditIcon.js +2 -2
  11. package/dist/client/FieldAuditIcon.js.map +1 -1
  12. package/dist/client/FieldAuditTrail.d.ts.map +1 -1
  13. package/dist/client/FieldAuditTrail.js +71 -8
  14. package/dist/client/FieldAuditTrail.js.map +1 -1
  15. package/dist/client/RevertConfirmDialog.d.ts +11 -0
  16. package/dist/client/RevertConfirmDialog.d.ts.map +1 -0
  17. package/dist/client/RevertConfirmDialog.js +31 -0
  18. package/dist/client/RevertConfirmDialog.js.map +1 -0
  19. package/dist/client/index.d.ts +4 -0
  20. package/dist/client/index.d.ts.map +1 -1
  21. package/dist/client/index.js +2 -0
  22. package/dist/client/index.js.map +1 -1
  23. package/dist/index.d.ts +73 -0
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +9 -0
  26. package/dist/index.js.map +1 -1
  27. package/dist/nextjs/index.d.ts +5 -0
  28. package/dist/nextjs/index.d.ts.map +1 -1
  29. package/dist/nextjs/index.js +78 -1
  30. package/dist/nextjs/index.js.map +1 -1
  31. package/dist/server/diff.js +11 -3
  32. package/dist/server/diff.js.map +1 -1
  33. package/dist/server/errors.d.ts +6 -0
  34. package/dist/server/errors.d.ts.map +1 -0
  35. package/dist/server/errors.js +9 -0
  36. package/dist/server/errors.js.map +1 -0
  37. package/dist/server/index.d.ts +8 -0
  38. package/dist/server/index.d.ts.map +1 -1
  39. package/dist/server/index.js +8 -0
  40. package/dist/server/index.js.map +1 -1
  41. package/dist/server/intent.d.ts +9 -0
  42. package/dist/server/intent.d.ts.map +1 -0
  43. package/dist/server/intent.js +102 -0
  44. package/dist/server/intent.js.map +1 -0
  45. package/dist/server/query.d.ts +22 -0
  46. package/dist/server/query.d.ts.map +1 -0
  47. package/dist/server/query.js +52 -0
  48. package/dist/server/query.js.map +1 -0
  49. package/dist/server/revert.d.ts +20 -0
  50. package/dist/server/revert.d.ts.map +1 -0
  51. package/dist/server/revert.js +89 -0
  52. package/dist/server/revert.js.map +1 -0
  53. package/dist/server/snapshot.d.ts +38 -0
  54. package/dist/server/snapshot.d.ts.map +1 -0
  55. package/dist/server/snapshot.js +68 -0
  56. package/dist/server/snapshot.js.map +1 -0
  57. package/dist/server/worker.d.ts.map +1 -1
  58. package/dist/server/worker.js +8 -0
  59. package/dist/server/worker.js.map +1 -1
  60. package/package.json +8 -3
package/CHANGE_LOG.md CHANGED
@@ -1,5 +1,77 @@
1
1
  # Change log
2
2
 
3
+ ## 2.0.2 — 2026-05-27
4
+
5
+ ### Added
6
+
7
+ - **`opLabels` prop** on `<FieldAuditTrail />` and `<FieldAuditIcon />` for
8
+ overriding the op badge text per app. Shape: `{ insert?, update?, delete? }`.
9
+ Exported alongside `DEFAULT_OP_LABELS` for apps that want to compose on top
10
+ of the defaults. Empty-string override falls back to the raw DB op so apps
11
+ can opt back into the legacy uppercase rendering per-op.
12
+
13
+ ### Changed
14
+
15
+ - **Op badge defaults** — `INSERT` / `UPDATE` / `DELETE` are now rendered as
16
+ `Added` / `Changed` / `Removed` (action-oriented, past tense). This reads
17
+ naturally next to the actor line: `Added · Pubs Abayasiri`. The uppercase
18
+ text-transform on the badge was dropped so casing in `opLabels` is honoured.
19
+
20
+ ## 2.0.1 — 2026-05-20
21
+
22
+ ### Fixed
23
+
24
+ - **`revert()` API cleanup** — removed redundant `app_adapter` field from `RevertArgs`.
25
+ The first positional parameter is now the canonical write adapter; `audit_adapter`
26
+ (optional in args) falls back to it when omitted. Previous callers that passed
27
+ `app_adapter` inside the args object should remove that key.
28
+ - **Worker ISO timestamp normalization** — the `includes('T')` guard in `worker.ts`
29
+ failed to normalize no-timezone ISO strings. The guard now detects SQLite's
30
+ space-separated format via `includes(' ')`, guaranteeing all `occurred_at` values
31
+ stored in `hazo_audit_field` are well-formed ISO-8601 regardless of input format.
32
+ - **Test-app scripted scenarios** — `/revert_demo` and `/snapshot_demo` each have a
33
+ one-click "Run scripted scenario" button that exercises both fixes end-to-end.
34
+
35
+ ## 2.0.0 — 2026-05-20
36
+
37
+ ### Added
38
+
39
+ - **`auditIntent(adapter, name, callback, opts?)`** server helper for grouping
40
+ multi-write transactions under a shared `correlation_id`. Writes opening +
41
+ closing `hazo_audit_intent` rows; nested calls reuse the outer `correlation_id`.
42
+ - **`snapshot(adapter, { table, recordId, asOf })`** server function: replays
43
+ `hazo_audit_field` events to compute field state at a timestamp.
44
+ - **`revert(adapter, { table, recordId, toTimestamp, actorUserId, reason })`**
45
+ server function: applies the inverse writes to restore a record. Wrapped in
46
+ its own `audit.revert` intent. Throws `RecordNotFoundError` when no history
47
+ exists.
48
+ - **`auditQuery(adapter, { table, recordId, fromTimestamp, toTimestamp })`**
49
+ server function: server-side history fetch (used internally by snapshot/revert).
50
+ - **`<AuditViewer />`** client component — cross-record admin viewer with CSV
51
+ export. Hits the new `viewer.GET` handler on `createAuditEventsRoutes`.
52
+ - **`<RevertConfirmDialog />`** client component — modal helper for confirming
53
+ a revert with a typed reason.
54
+ - New optional `viewer_permission` on `AuditEventsRoutesOptions`.
55
+
56
+ ### Changed
57
+
58
+ - Sample INI's default `exclude_tables` now includes `hazo_logs, hazo_notifications`.
59
+ - Sample INI now documents the deterministic capture matrix inline.
60
+ - The package now ships a jest test suite (31 tests across 7 scenarios).
61
+ - Worker now writes ISO-8601 `occurred_at` on field rows (was SQLite space-separated format).
62
+
63
+ ### Not changed
64
+
65
+ - Database schema: no migrations beyond `001_init.sql`.
66
+ - Existing exports (`wrapWithAudit`, `startAuditWorker`, `createAuditedCrudService`,
67
+ `emitIntentEvent`, `runWithAuditContext`, `<FieldAuditIcon>`, `<FieldAuditTrail>`,
68
+ `createAuditEventsRoutes`) are unchanged and backward-compatible.
69
+ - INI remains the primary source of truth for capture rules.
70
+
71
+ ### Deferred
72
+
73
+ - `replayAudit()` — moved to v2.1.0.
74
+
3
75
  ## v1.0.0 — 2026-05-20
4
76
 
5
77
  Initial release. Implements PRD `design/PRD.md` end-to-end.
package/README.md CHANGED
@@ -72,7 +72,7 @@ hazo_audit_field ◄──────────── /api/audit/events
72
72
 
73
73
  | Import | What |
74
74
  |---|---|
75
- | `hazo_audit` | Client-safe types and permission constants (`AUDIT_VIEW_HISTORY`, etc.). |
75
+ | `hazo_audit` | Client-safe types and permission constants (`AUDIT_VIEW_HISTORY`, etc.). Also exports `OpLabels` interface and `DEFAULT_OP_LABELS` constant. |
76
76
  | `hazo_audit/server` | `wrapWithAudit`, `startAuditWorker`, `runWithAuditContext`, `createAuditedCrudService`, `emitIntentEvent`. Server-only. |
77
77
  | `hazo_audit/nextjs` | `createAuditEventsRoutes` — Next.js GET + reveal POST handlers. |
78
78
  | `hazo_audit/client` | `<FieldAuditIcon />`, `<FieldAuditTrail />`. Safe in client components. |
@@ -172,6 +172,43 @@ await svc.updateById(folderId, patch, {
172
172
  Direct Layer-1 intent emission (no piggyback). `withAudit(name, payload, fn)`
173
173
  ergonomic is Phase 2.
174
174
 
175
+ ### `OpLabels` / `DEFAULT_OP_LABELS`
176
+
177
+ Override the badge labels rendered on each event in `<FieldAuditTrail />`:
178
+
179
+ ```ts
180
+ import { DEFAULT_OP_LABELS } from 'hazo_audit'
181
+ import { FieldAuditTrail } from 'hazo_audit/client'
182
+
183
+ // Keep defaults for insert/delete; rename update → "Edited"
184
+ <FieldAuditTrail
185
+ {...props}
186
+ opLabels={{ ...DEFAULT_OP_LABELS, update: 'Edited' }}
187
+ />
188
+ ```
189
+
190
+ Default labels: `insert → Added`, `update → Changed`, `delete → Removed`.
191
+ Pass an empty string for an op to fall back to the raw DB op.
192
+
193
+ ### Intent labels (`intentLabels`)
194
+
195
+ When events are fired inside `auditIntent(adapter, name, callback)`, the
196
+ trail can annotate each event with a human-readable source label:
197
+
198
+ ```tsx
199
+ <FieldAuditTrail
200
+ {...props}
201
+ intentLabels={{
202
+ survey_prefill_key_info: 'auto-fill',
203
+ wp_pdf_prefill: 'PDF import',
204
+ }}
205
+ />
206
+ // Renders: "Changed · Pubs Abayasiri (via auto-fill)"
207
+ ```
208
+
209
+ The component fetches the correlated intent events automatically when
210
+ `intentLabels` is non-empty; no extra setup required.
211
+
175
212
  ### `createAuditEventsRoutes({ audit_adapter, getAuth })` → `{ GET, reveal: { POST } }`
176
213
 
177
214
  Next.js route factory.
@@ -204,10 +241,29 @@ createAuditEventsRoutes({
204
241
  Renders a clock icon that opens a popover with the field's audit trail.
205
242
  Self-positioning, no Radix dep.
206
243
 
244
+ | Prop | Type | Default | Description |
245
+ |---|---|---|---|
246
+ | `subjectKind` | `string` | — | Required. Table-level subject kind (e.g. `"client_folder"`). |
247
+ | `subjectId` | `string` | — | Required. Record ID. |
248
+ | `fieldPath` | `string` | — | Field to scope the trail to. |
249
+ | `api_base` | `string` | `"/api/audit"` | Route prefix. |
250
+ | `opLabels` | `OpLabels` | `DEFAULT_OP_LABELS` | Override op badge text for individual ops. |
251
+ | `intentLabels` | `Record<string, string>` | — | Map of intent event names → display labels. Adds a "(via …)" annotation to events fired inside a named intent. |
252
+
207
253
  ### `<FieldAuditTrail subjectKind subjectId fieldPath? />`
208
254
 
209
255
  Renders the trail directly (use in a sidebar, modal, etc.).
210
256
 
257
+ | Prop | Type | Default | Description |
258
+ |---|---|---|---|
259
+ | `subjectKind` | `string` | — | Required. |
260
+ | `subjectId` | `string` | — | Required. |
261
+ | `fieldPath` | `string` | — | Filter to one field. Omit for the full record trail. |
262
+ | `api_base` | `string` | `"/api/audit"` | Route prefix. |
263
+ | `opLabels` | `OpLabels` | `DEFAULT_OP_LABELS` | Override op badge text. See `OpLabels` + `DEFAULT_OP_LABELS`. |
264
+ | `intentLabels` | `Record<string, string>` | — | Annotate changes with their originating intent. Key = bare event name (`.completed`/`.failed` stripped). |
265
+ | `limit` | `number` | `50` | Max events to fetch. |
266
+
211
267
  ## Schema
212
268
 
213
269
  Three tables (see `migrations/001_init.sql` for both Postgres + SQLite):
@@ -259,6 +315,87 @@ Sidebar walks through:
259
315
 
260
316
  Backed by SQLite (sql.js); the demo DB lives at `test-app/data/demo.db`.
261
317
 
318
+ ## What's new in v2.0.0
319
+
320
+ ### `auditIntent(adapter, name, callback)` — group multi-write transactions
321
+
322
+ ```ts
323
+ import { auditIntent, runWithAuditContext } from 'hazo_audit/server';
324
+
325
+ await runWithAuditContext({ actor_kind: 'user', actor_user_id: 'u1' }, () =>
326
+ auditIntent(adapter, 'person.merge', async () => {
327
+ await crud.update(personA.id, { ...mergedFields });
328
+ await crud.delete(personB.id);
329
+ }, { metadata: { reason: 'manual merge by admin' } }),
330
+ );
331
+ ```
332
+
333
+ All captured writes inside the callback share a `correlation_id`. An opening
334
+ `hazo_audit_intent` row is written when the callback starts; a closing row
335
+ (`person.merge.completed` or `person.merge.failed`) lands on completion or
336
+ throw. Nested calls reuse the outer `correlation_id`.
337
+
338
+ ### `snapshot(adapter, { table, recordId, asOf })`
339
+
340
+ ```ts
341
+ import { snapshot } from 'hazo_audit/server';
342
+
343
+ const snap = await snapshot(adapter, {
344
+ table: 'app_persons',
345
+ recordId: 'p1',
346
+ asOf: new Date('2026-05-01T10:00:00Z'),
347
+ });
348
+ // → { state: { name: 'Alice', email: 'a@x.com' }, deleted: false, exists: true }
349
+ ```
350
+
351
+ Replays `hazo_audit_field` events for the subject up to `asOf` and returns the
352
+ computed field state.
353
+
354
+ ### `revert(app_adapter, { table, recordId, toTimestamp, reason })`
355
+
356
+ ```ts
357
+ import { revert, RecordNotFoundError } from 'hazo_audit/server';
358
+
359
+ try {
360
+ const result = await revert(wrapped, {
361
+ audit_adapter: base, // optional; falls back to app_adapter when omitted
362
+ table: 'app_persons',
363
+ recordId: 'p1',
364
+ toTimestamp: new Date('2026-05-01T10:00:00Z'),
365
+ actorUserId: 'admin1',
366
+ reason: 'user-requested rollback',
367
+ });
368
+ // result.applied = 'insert' | 'update' | 'delete' | 'noop'
369
+ } catch (e) {
370
+ if (e instanceof RecordNotFoundError) { /* no audit history exists */ }
371
+ }
372
+ ```
373
+
374
+ Computes the target snapshot, diffs against the current row, and applies the
375
+ necessary PATCH/INSERT/DELETE — all wrapped in an `audit.revert` intent.
376
+
377
+ ### `<AuditViewer />` (R3) — cross-record admin viewer
378
+
379
+ ```tsx
380
+ import { AuditViewer } from 'hazo_audit/client';
381
+
382
+ <AuditViewer
383
+ api_base="/api/audit"
384
+ initialFilters={{ subject_kind: 'person' }}
385
+ />
386
+ ```
387
+
388
+ Filterable, grouped-by-`correlation_id` list of all audit events with CSV export.
389
+
390
+ ### `<RevertConfirmDialog />`
391
+
392
+ Modal helper for confirming a revert with a typed reason.
393
+
394
+ ### Capture default exclusions widened (R2)
395
+
396
+ The sample INI now ships with `hazo_logs, hazo_notifications` in `exclude_tables`
397
+ by default. The capture matrix is documented inline in `config/hazo_audit_config.ini.sample`.
398
+
262
399
  ## Related
263
400
 
264
401
  - `hazo_connect` — provides the adapter interface and `claimRows()` primitive.
@@ -184,3 +184,12 @@ wasn't set).
184
184
  | `[retention]` | Default 30d for drained outbox, 90d for dead-lettered. Bump if you need longer auditability. |
185
185
  | `[worker]` | Bump `poll_ms` down for snappier history (CPU cost: minimal at single-pod scale). |
186
186
  | `[overrides.<table>]` | `sensitive_columns`, `jsonb_columns`, `jsonb_path_exclude`, `resolver`, `fanout_bulk_writes`. |
187
+
188
+ ## Running the test suite
189
+
190
+ ```bash
191
+ npm test
192
+ ```
193
+
194
+ The suite uses jest 30 + ts-jest with an in-memory SQLite adapter per test.
195
+ No external services or fixtures required. Total runtime under 30 seconds.
@@ -13,11 +13,21 @@ include_tables =
13
13
 
14
14
  ; Blacklist by prefix or exact name. Always wins over include rules.
15
15
  exclude_table_prefixes = _
16
- exclude_tables = hazo_chat_typing_indicators, hazo_worker_heartbeats
16
+ exclude_tables = hazo_chat_typing_indicators, hazo_worker_heartbeats, hazo_logs, hazo_notifications
17
17
 
18
- ; Note: the audit pipeline tables themselves
19
- ; (hazo_audit_outbox, hazo_audit_field, hazo_audit_intent)
20
- ; are hardcoded as never-capture regardless of this config.
18
+ ; ─── Capture matrix (R2) ────────────────────────────────────────────────────
19
+ ; The capture decision honors this order (deterministic, exclude wins):
20
+ ; 1. hazo_audit_outbox / hazo_audit_field / hazo_audit_intent → never (hardcoded)
21
+ ; 2. exclude_tables → skip
22
+ ; 3. exclude_table_prefixes → skip
23
+ ; 4. include_tables → capture
24
+ ; 5. include_table_prefixes → capture
25
+ ; 6. otherwise → skip (default deny)
26
+ ;
27
+ ; To opt a single table into auditing without enabling the whole prefix,
28
+ ; clear `include_table_prefixes` and add the table to `include_tables`.
29
+ ; To suppress a single table inside a captured prefix, add it to
30
+ ; `exclude_tables`.
21
31
 
22
32
  [retention]
23
33
  ; Days to keep successfully-drained outbox rows before the reaper deletes them.
@@ -0,0 +1,13 @@
1
+ export interface AuditViewerProps {
2
+ api_base?: string;
3
+ initialFilters?: {
4
+ subject_kind?: string;
5
+ subject_id?: string;
6
+ actor_user_id?: string;
7
+ since?: string;
8
+ until?: string;
9
+ };
10
+ className?: string;
11
+ }
12
+ export declare function AuditViewer({ api_base, initialFilters, className, }: AuditViewerProps): JSX.Element;
13
+ //# sourceMappingURL=AuditViewer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuditViewer.d.ts","sourceRoot":"","sources":["../../src/client/AuditViewer.tsx"],"names":[],"mappings":"AAMA,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE;QACf,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,WAAW,CAAC,EAC1B,QAAuB,EACvB,cAAmB,EACnB,SAAS,GACV,EAAE,gBAAgB,GAAG,GAAG,CAAC,OAAO,CA0HhC"}
@@ -0,0 +1,52 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useState } from 'react';
4
+ import { cn } from './cn.js';
5
+ export function AuditViewer({ api_base = '/api/audit', initialFilters = {}, className, }) {
6
+ const [filters, setFilters] = useState(initialFilters);
7
+ const [events, setEvents] = useState([]);
8
+ const [loading, setLoading] = useState(false);
9
+ const [error, setError] = useState(null);
10
+ async function load() {
11
+ setLoading(true);
12
+ setError(null);
13
+ try {
14
+ const params = new URLSearchParams();
15
+ for (const [k, v] of Object.entries(filters)) {
16
+ if (v)
17
+ params.set(k, v);
18
+ }
19
+ const res = await fetch(`${api_base}/viewer?${params.toString()}`);
20
+ if (!res.ok) {
21
+ setError(`HTTP ${res.status}`);
22
+ setEvents([]);
23
+ return;
24
+ }
25
+ const body = await res.json();
26
+ setEvents(body.events ?? []);
27
+ }
28
+ catch (e) {
29
+ setError(e instanceof Error ? e.message : 'unknown error');
30
+ }
31
+ finally {
32
+ setLoading(false);
33
+ }
34
+ }
35
+ useEffect(() => { load(); /* eslint-disable-next-line */ }, []);
36
+ function exportCsv() {
37
+ const params = new URLSearchParams();
38
+ for (const [k, v] of Object.entries(filters))
39
+ if (v)
40
+ params.set(k, v);
41
+ params.set('format', 'csv');
42
+ window.open(`${api_base}/viewer?${params.toString()}`, '_blank');
43
+ }
44
+ const groups = new Map();
45
+ for (const e of events) {
46
+ const list = groups.get(e.correlation_id) ?? [];
47
+ list.push(e);
48
+ groups.set(e.correlation_id, list);
49
+ }
50
+ return (_jsxs("div", { className: cn('flex flex-col gap-3 rounded border border-slate-200 p-4', className), children: [_jsxs("div", { className: "flex flex-wrap gap-2 text-sm", children: [_jsx("input", { className: "rounded border px-2 py-1", placeholder: "subject_kind", value: filters.subject_kind ?? '', onChange: (e) => setFilters({ ...filters, subject_kind: e.target.value }) }), _jsx("input", { className: "rounded border px-2 py-1", placeholder: "actor_user_id", value: filters.actor_user_id ?? '', onChange: (e) => setFilters({ ...filters, actor_user_id: e.target.value }) }), _jsx("input", { className: "rounded border px-2 py-1", placeholder: "since (ISO)", value: filters.since ?? '', onChange: (e) => setFilters({ ...filters, since: e.target.value }) }), _jsx("input", { className: "rounded border px-2 py-1", placeholder: "until (ISO)", value: filters.until ?? '', onChange: (e) => setFilters({ ...filters, until: e.target.value }) }), _jsx("button", { onClick: load, className: "rounded bg-amber-500 px-3 py-1 text-white", children: loading ? 'Loading…' : 'Apply' }), _jsx("button", { onClick: exportCsv, className: "rounded border px-3 py-1", children: "Export CSV" })] }), error && _jsx("div", { className: "text-sm text-red-600", children: error }), _jsxs("div", { className: "flex flex-col gap-2", children: [[...groups.entries()].map(([cid, evs]) => (_jsxs("details", { className: "rounded border border-slate-100 bg-slate-50 p-2", children: [_jsxs("summary", { className: "cursor-pointer text-sm", children: [_jsx("span", { className: "font-mono text-xs text-slate-600", children: cid.slice(0, 8) }), ' · ', _jsxs("span", { children: [evs.length, " change", evs.length === 1 ? '' : 's'] }), ' · ', _jsxs("span", { children: [evs[0].subject_kind, " ", evs[0].subject_id] }), ' · ', _jsx("span", { className: "text-xs text-slate-500", children: evs[0].occurred_at })] }), _jsxs("table", { className: "mt-2 w-full text-xs", children: [_jsx("thead", { children: _jsxs("tr", { className: "text-left", children: [_jsx("th", { className: "pr-3", children: "field" }), _jsx("th", { className: "pr-3", children: "op" }), _jsx("th", { className: "pr-3", children: "before" }), _jsx("th", { className: "pr-3", children: "after" }), _jsx("th", { className: "pr-3", children: "actor" })] }) }), _jsx("tbody", { children: evs.map((e) => (_jsxs("tr", { className: "border-t", children: [_jsx("td", { className: "pr-3 font-mono", children: e.field_path }), _jsx("td", { className: "pr-3", children: e.op }), _jsx("td", { className: "pr-3", children: JSON.stringify(e.before_value) }), _jsx("td", { className: "pr-3", children: JSON.stringify(e.after_value) }), _jsx("td", { className: "pr-3", children: e.actor_user_id ?? '—' })] }, e.id))) })] })] }, cid))), events.length === 0 && !loading && (_jsx("div", { className: "text-sm text-slate-500", children: "No events match the current filters." }))] })] }));
51
+ }
52
+ //# sourceMappingURL=AuditViewer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuditViewer.js","sourceRoot":"","sources":["../../src/client/AuditViewer.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"FieldAuditIcon.d.ts","sourceRoot":"","sources":["../../src/client/FieldAuditIcon.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,GAAG,CAAC,OAAO,CAwEtE"}
1
+ {"version":3,"file":"FieldAuditIcon.d.ts","sourceRoot":"","sources":["../../src/client/FieldAuditIcon.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,GAAG,CAAC,OAAO,CAmFtE"}
@@ -12,7 +12,7 @@ import { FieldAuditTrail } from './FieldAuditTrail.js';
12
12
  * permission" hint.
13
13
  */
14
14
  export function FieldAuditIcon(props) {
15
- const { subjectKind, subjectId, fieldPath, api_base, className, label } = props;
15
+ const { subjectKind, subjectId, fieldPath, api_base, intentLabels, opLabels, className, label, } = props;
16
16
  const [open, setOpen] = React.useState(false);
17
17
  const rootRef = React.useRef(null);
18
18
  React.useEffect(() => {
@@ -35,7 +35,7 @@ export function FieldAuditIcon(props) {
35
35
  document.removeEventListener('keydown', onKey);
36
36
  };
37
37
  }, [open]);
38
- return (_jsxs("div", { ref: rootRef, className: "relative inline-block", children: [_jsx("button", { type: "button", "aria-label": label ?? `View audit history for ${fieldPath}`, title: label ?? 'View audit history', onClick: () => setOpen((v) => !v), className: cn('inline-flex h-6 w-6 items-center justify-center rounded-full', 'text-slate-400 transition-colors hover:bg-slate-100 hover:text-slate-700', 'focus:outline-none focus:ring-2 focus:ring-slate-400', 'dark:hover:bg-slate-800 dark:hover:text-slate-200', className), children: _jsx(ClockIcon, { className: "h-3.5 w-3.5" }) }), open && (_jsxs("div", { role: "dialog", "aria-label": "Audit history", className: cn('absolute right-0 z-50 mt-2 w-96 max-w-[calc(100vw-2rem)]', 'rounded-md border border-slate-200 bg-white p-3 shadow-lg', 'dark:border-slate-700 dark:bg-slate-900'), children: [_jsxs("div", { className: "mb-2 flex items-center justify-between", children: [_jsxs("h3", { className: "text-sm font-semibold text-slate-900 dark:text-slate-100", children: ["History \u00B7 ", fieldPath] }), _jsx("button", { type: "button", "aria-label": "Close", onClick: () => setOpen(false), className: "text-slate-400 hover:text-slate-700 dark:hover:text-slate-200", children: _jsx(CloseIcon, { className: "h-4 w-4" }) })] }), _jsx(FieldAuditTrail, { subjectKind: subjectKind, subjectId: subjectId, fieldPath: fieldPath, api_base: api_base })] }))] }));
38
+ return (_jsxs("div", { ref: rootRef, className: "relative inline-block", children: [_jsx("button", { type: "button", "aria-label": label ?? `View audit history for ${fieldPath}`, title: label ?? 'View audit history', onClick: () => setOpen((v) => !v), className: cn('inline-flex h-6 w-6 items-center justify-center rounded-full', 'text-slate-400 transition-colors hover:bg-slate-100 hover:text-slate-700', 'focus:outline-none focus:ring-2 focus:ring-slate-400', 'dark:hover:bg-slate-800 dark:hover:text-slate-200', className), children: _jsx(ClockIcon, { className: "h-3.5 w-3.5" }) }), open && (_jsxs("div", { role: "dialog", "aria-label": "Audit history", className: cn('absolute right-0 z-50 mt-2 w-96 max-w-[calc(100vw-2rem)]', 'rounded-md border border-slate-200 bg-white p-3 shadow-lg', 'dark:border-slate-700 dark:bg-slate-900'), children: [_jsxs("div", { className: "mb-2 flex items-center justify-between", children: [_jsxs("h3", { className: "text-sm font-semibold text-slate-900 dark:text-slate-100", children: ["History \u00B7 ", fieldPath] }), _jsx("button", { type: "button", "aria-label": "Close", onClick: () => setOpen(false), className: "text-slate-400 hover:text-slate-700 dark:hover:text-slate-200", children: _jsx(CloseIcon, { className: "h-4 w-4" }) })] }), _jsx(FieldAuditTrail, { subjectKind: subjectKind, subjectId: subjectId, fieldPath: fieldPath, api_base: api_base, intentLabels: intentLabels, opLabels: opLabels })] }))] }));
39
39
  }
40
40
  function ClockIcon({ className }) {
41
41
  return (_jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: className, "aria-hidden": true, children: [_jsx("circle", { cx: "12", cy: "12", r: "10" }), _jsx("polyline", { points: "12 6 12 12 16 14" })] }));
@@ -1 +1 @@
1
- {"version":3,"file":"FieldAuditIcon.js","sourceRoot":"","sources":["../../src/client/FieldAuditIcon.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FieldAuditIcon.js","sourceRoot":"","sources":["../../src/client/FieldAuditIcon.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"FieldAuditTrail.d.ts","sourceRoot":"","sources":["../../src/client/FieldAuditTrail.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,GAAG,CAAC,OAAO,CA+JxE"}
1
+ {"version":3,"file":"FieldAuditTrail.d.ts","sourceRoot":"","sources":["../../src/client/FieldAuditTrail.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,GAAG,CAAC,OAAO,CAiNxE"}
@@ -2,14 +2,21 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import * as React from 'react';
4
4
  import { cn } from './cn.js';
5
+ import { DEFAULT_OP_LABELS } from '../index.js';
5
6
  /**
6
7
  * Renders an ordered list of field audit events for a subject (optionally
7
8
  * filtered to a single field_path). Sensitive rows show "[redacted]" with a
8
9
  * "Reveal" button that calls /audit/events/[id]/reveal.
9
10
  */
10
11
  export function FieldAuditTrail(props) {
11
- const { subjectKind, subjectId, fieldPath, api_base = '/api/audit', limit = 50, className, onRevealed, } = props;
12
- const [state, setState] = React.useState({ loading: true, events: [], revealed: {} });
12
+ const { subjectKind, subjectId, fieldPath, api_base = '/api/audit', intentLabels, opLabels, limit = 50, className, onRevealed, } = props;
13
+ const wantIntent = !!intentLabels && Object.keys(intentLabels).length > 0;
14
+ const [state, setState] = React.useState({
15
+ loading: true,
16
+ events: [],
17
+ intentByCorrelation: new Map(),
18
+ revealed: {},
19
+ });
13
20
  React.useEffect(() => {
14
21
  let cancelled = false;
15
22
  setState((s) => ({ ...s, loading: true, error: undefined }));
@@ -20,6 +27,8 @@ export function FieldAuditTrail(props) {
20
27
  });
21
28
  if (fieldPath)
22
29
  params.set('field_path', fieldPath);
30
+ if (wantIntent)
31
+ params.set('include', 'intent');
23
32
  fetch(`${api_base}/events?${params.toString()}`, { credentials: 'include' })
24
33
  .then(async (r) => {
25
34
  if (r.status === 403) {
@@ -37,14 +46,35 @@ export function FieldAuditTrail(props) {
37
46
  setState({
38
47
  loading: false,
39
48
  events: [],
49
+ intentByCorrelation: new Map(),
40
50
  revealed: {},
41
51
  error: 'You do not have permission to view audit history.',
42
52
  });
43
53
  return;
44
54
  }
55
+ // Build correlation_id → intent map. When multiple events share a
56
+ // correlation_id (e.g. `name` + `name.completed`), prefer the bare
57
+ // started event since `.completed`/`.failed` carry lifecycle status
58
+ // rather than the user-meaningful source label.
59
+ const intentMap = new Map();
60
+ for (const ie of data.intent_events ?? []) {
61
+ const existing = intentMap.get(ie.correlation_id);
62
+ if (!existing) {
63
+ intentMap.set(ie.correlation_id, ie);
64
+ continue;
65
+ }
66
+ const existingIsLifecycle = existing.event_name.endsWith('.completed') ||
67
+ existing.event_name.endsWith('.failed');
68
+ const candidateIsLifecycle = ie.event_name.endsWith('.completed') ||
69
+ ie.event_name.endsWith('.failed');
70
+ if (existingIsLifecycle && !candidateIsLifecycle) {
71
+ intentMap.set(ie.correlation_id, ie);
72
+ }
73
+ }
45
74
  setState({
46
75
  loading: false,
47
76
  events: data.field_events ?? [],
77
+ intentByCorrelation: intentMap,
48
78
  revealed: {},
49
79
  });
50
80
  })
@@ -54,6 +84,7 @@ export function FieldAuditTrail(props) {
54
84
  setState({
55
85
  loading: false,
56
86
  events: [],
87
+ intentByCorrelation: new Map(),
57
88
  revealed: {},
58
89
  error: err.message,
59
90
  });
@@ -61,7 +92,7 @@ export function FieldAuditTrail(props) {
61
92
  return () => {
62
93
  cancelled = true;
63
94
  };
64
- }, [subjectKind, subjectId, fieldPath, api_base, limit]);
95
+ }, [subjectKind, subjectId, fieldPath, api_base, limit, wantIntent]);
65
96
  async function handleReveal(id) {
66
97
  try {
67
98
  const r = await fetch(`${api_base}/events/${id}/reveal`, {
@@ -96,11 +127,43 @@ export function FieldAuditTrail(props) {
96
127
  if (state.events.length === 0) {
97
128
  return (_jsx("div", { className: cn('py-3 text-center text-xs text-slate-400', className), children: "No history yet." }));
98
129
  }
99
- return (_jsx("ol", { className: cn('space-y-2 text-sm', className), children: state.events.map((ev) => (_jsxs("li", { className: "rounded border border-slate-200 p-2 dark:border-slate-700", children: [_jsxs("div", { className: "mb-1 flex items-center justify-between gap-2 text-xs text-slate-500", children: [_jsxs("span", { children: [_jsx("span", { className: cn('mr-2 inline-block rounded px-1.5 py-0.5 text-[10px] font-medium uppercase', ev.op === 'insert'
100
- ? 'bg-emerald-100 text-emerald-700'
101
- : ev.op === 'delete'
102
- ? 'bg-rose-100 text-rose-700'
103
- : 'bg-sky-100 text-sky-700'), children: ev.op }), ev.actor_label || ev.actor_user_id || ev.actor_kind] }), _jsx("time", { dateTime: ev.occurred_at, title: ev.occurred_at, className: "text-[11px] text-slate-400", children: formatDate(ev.occurred_at) })] }), !fieldPath && (_jsx("div", { className: "mb-1 font-mono text-xs text-slate-600 dark:text-slate-300", children: ev.field_path })), _jsx(ValueDiff, { event: ev, revealed: state.revealed[ev.id], onReveal: () => handleReveal(ev.id) })] }, ev.id))) }));
130
+ return (_jsx("ol", { className: cn('space-y-2 text-sm', className), children: state.events.map((ev) => {
131
+ const sourceLabel = resolveIntentLabel(ev.correlation_id, state.intentByCorrelation, intentLabels);
132
+ const actor = ev.actor_label || ev.actor_user_id || ev.actor_kind;
133
+ return (_jsxs("li", { className: "rounded border border-slate-200 p-2 dark:border-slate-700", children: [_jsxs("div", { className: "mb-1 flex items-center justify-between gap-2 text-xs text-slate-500", children: [_jsxs("span", { children: [_jsx("span", { className: cn('mr-2 inline-block rounded px-1.5 py-0.5 text-[10px] font-semibold tracking-wide', ev.op === 'insert'
134
+ ? 'bg-emerald-600 text-white dark:bg-emerald-500'
135
+ : ev.op === 'delete'
136
+ ? 'bg-rose-600 text-white dark:bg-rose-500'
137
+ : 'bg-sky-600 text-white dark:bg-sky-500'), children: resolveOpLabel(ev.op, opLabels) }), actor, sourceLabel && (_jsxs("span", { className: "ml-1 text-slate-500 dark:text-slate-400", children: ["(via ", sourceLabel, ")"] }))] }), _jsx("time", { dateTime: ev.occurred_at, title: ev.occurred_at, className: "text-[11px] text-slate-400", children: formatDate(ev.occurred_at) })] }), !fieldPath && (_jsx("div", { className: "mb-1 font-mono text-xs text-slate-600 dark:text-slate-300", children: ev.field_path })), _jsx(ValueDiff, { event: ev, revealed: state.revealed[ev.id], onReveal: () => handleReveal(ev.id) })] }, ev.id));
138
+ }) }));
139
+ }
140
+ /**
141
+ * Resolve the friendly badge label for a field event op. Consumer-supplied
142
+ * overrides win; otherwise the package defaults (Added / Changed / Removed)
143
+ * apply. An explicit empty-string override falls back to the raw DB op so
144
+ * apps can opt into the legacy uppercase rendering per-op.
145
+ */
146
+ function resolveOpLabel(op, overrides) {
147
+ const override = overrides?.[op];
148
+ if (override !== undefined)
149
+ return override === '' ? op : override;
150
+ return DEFAULT_OP_LABELS[op];
151
+ }
152
+ /**
153
+ * Look up an intent label for a field event by correlation_id. `.completed`
154
+ * and `.failed` suffixes are stripped so the app's `intentLabels` map only
155
+ * needs the bare event names.
156
+ */
157
+ function resolveIntentLabel(correlation_id, intentByCorrelation, labels) {
158
+ if (!labels)
159
+ return undefined;
160
+ const intent = intentByCorrelation.get(correlation_id);
161
+ if (!intent)
162
+ return undefined;
163
+ const name = intent.event_name
164
+ .replace(/\.completed$/, '')
165
+ .replace(/\.failed$/, '');
166
+ return labels[name];
104
167
  }
105
168
  function ValueDiff({ event, revealed, onReveal, }) {
106
169
  if (event.is_sensitive && !revealed) {
@@ -1 +1 @@
1
- {"version":3,"file":"FieldAuditTrail.js","sourceRoot":"","sources":["../../src/client/FieldAuditTrail.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FieldAuditTrail.js","sourceRoot":"","sources":["../../src/client/FieldAuditTrail.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export interface RevertConfirmDialogProps {
2
+ open: boolean;
3
+ table: string;
4
+ recordId: string;
5
+ toTimestamp: string;
6
+ onConfirm: (reason: string) => Promise<void>;
7
+ onClose: () => void;
8
+ className?: string;
9
+ }
10
+ export declare function RevertConfirmDialog({ open, table, recordId, toTimestamp, onConfirm, onClose, className, }: RevertConfirmDialogProps): JSX.Element | null;
11
+ //# sourceMappingURL=RevertConfirmDialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RevertConfirmDialog.d.ts","sourceRoot":"","sources":["../../src/client/RevertConfirmDialog.tsx"],"names":[],"mappings":"AAKA,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,mBAAmB,CAAC,EAClC,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,WAAW,EACX,SAAS,EACT,OAAO,EACP,SAAS,GACV,EAAE,wBAAwB,GAAG,GAAG,CAAC,OAAO,GAAG,IAAI,CA4D/C"}