05 — Screen Inventory (Audit Module)
- Legend
- 1. Audit Log List (
/settings/audit) - 2. Audit Filter Bar (part of list screen)
- 3. Audit Entry Detail (
/settings/audit/:id) - 4. Export Sheet (
/settings/audit/export)(planned) - 5. Entry Timeline
(proposed)— optional richer view - Shared components used
- Keyboard, landscape, tablet, desktop
Every screen of the Audit module, its intent, route, composition, states, permissions, platform behaviour and events. Authoritative components in 00-shared/03; module-specific components in 07_Component_Library.md. Data fields are exact from
audit-log.schema.ts:13-56.
Legend
States = idle / loading / success / empty / error(offline, rate, invalid) / disabled / permission.
Analytics events follow {module}.{screen}.{action} (proposed; SDK open — 00-shared/10 §8).
1. Audit Log List (/settings/audit)
| Field | Detail |
|---|---|
| Purpose | Browse + filter the tenant's immutable action trail |
| Entry | Settings → Audit log; RBAC "Access audit"; deep link |
| Exit | row → detail; back → Settings; export (planned) |
| Source | GET /api/v1/audit-logs?page&limit&action&entityType&actorId (audit.controller.ts:19-25) |
| Composition | AppBar "Audit log" (+ count total); AuditFilterBar; result list: desktop/tablet = AuditTable (Time, Action, Actor, Resource, Context), phone = AuditEntryRow cards; footer "N of M" + Load more |
| States | loading (AppSkeleton rows), success, empty (AppEmptyState "No activity recorded" — also when total===0), error (AppErrorState by code), permission (route hidden w/o audit.read), offline (AppOfflineBanner + cached list) |
| Realtime | WS appends (journey 5) → prepend + banner "1 new entry" |
| Pull-to-refresh | RefreshIndicator → load(page=1) bypassing cache |
| Analytics | audit.list.view, audit.list.filter, audit.list.clear, audit.list.load_more, audit.list.refresh, audit.list.realtime_append (proposed) |
Data per row (exact schema): _id, action, actorId, actorType, entityType?,
entityId?, occurredAt, ipAddress?, device?, browser?, userAgent?, before?,
after?, correlationId?, metadata? (audit-log.schema.ts:15-55) plus inherited
tenantId, version, isDeleted, createdBy/updatedBy/deletedBy (base.schema.ts:8-34)
— inherited markers are not displayed.
2. Audit Filter Bar (part of list screen)
| Field | Detail |
|---|---|
| Purpose | AND-combined narrowing: action / entity type / actor (audit.controller.ts:26-29) |
| Controls | AppDropdown Action (free list from data), AppDropdown Entity type, AppDropdown/AppTextField Actor (id or name→id), Clear button, (planned) date range + search |
| Behaviour | any change → page=1 + reload; clear → unfiltered reload |
| States | default (all empty), active (chips with values + clear), empty-result hint when entityType chosen (see OQ-1) |
| Analytics | audit.list.filter with values |
3. Audit Entry Detail (/settings/audit/:id)
| Field | Detail |
|---|---|
| Purpose | Inspect one entry: who/what/when + before/after snapshot |
| Entry | row tap; deep link (in-memory lookup, OQ-4) |
| Exit | back → list (state preserved) |
| Composition | Header: AuditActionChip (action), actor line (actorId mono + name if resolved), occurredAt local-time + UTC tooltip, correlationId (copy), meta actorType; body: AuditDiffView (before/after) or JsonTreeView (after = payload, audit.handler.ts:43) or empty state; footer: immutability note |
| States | entry found / not found (deep link with no match → empty state + "back to list"), loading n/a (in-memory) |
| Actions | Copy ID, Copy JSON, Expand nested values, Export (planned) |
| Analytics | audit.detail.view, audit.detail.copy_json, audit.detail.expand (proposed) |
4. Export Sheet (/settings/audit/export) (planned)
| Field | Detail |
|---|---|
| Purpose | CSV/PDF export of current filter scope (blueprint: streamed, itself an audited action — AUDITING.md:87) |
| Entry | list overflow menu |
| Composition | Format radio (CSV/PDF), scope summary (filters + pages), timezone selector, CTA "Export" |
| States | disabled with note — no backend endpoint (gated until backend lands) |
| Analytics | audit.export.request (proposed) |
5. Entry Timeline (proposed) — optional richer view
Grouped-by-resource timeline (all entries for one entityId/correlationId in reverse
chronology). Requires backend ?entityId= filter support (OQ-1) or client-side grouping of
the loaded set only. (proposed) — not in code.
Shared components used
AppSkeleton, AppEmptyState, AppErrorState, AppOfflineBanner, AppSnackbar,
AppDropdown, AppSearchBar, AppChips, AppCard, AppListTile, AppMenu,
AppBottomSheet, AppRefreshIndicator, AppBadge, AppButton. Module-specific:
AuditTable, AuditEntryRow, AuditActionChip, AuditFilterBar, AuditDiffView,
JsonTreeView, EntryTimeline (proposed) — defined in 07_Component_Library.md.
Keyboard, landscape, tablet, desktop
- Desktop: full-width table with sticky header;
/focuses filter; arrows + Enter navigate rows. - Tablet ≥ 840 px: master-detail (list left, detail right).
- Phone: cards, single pane; landscape scrolls.