Module-specific interactions layered on shared 00-shared/08 . Covers every input modality
on phone/tablet/desktop for a read-only, high-density log surface .
Gesture Behaviour Where
Tap open detail, open filter sheet, clear filters, copy id/json, expand JSON node rows, filter bar, detail
Long-press AppMenu (View entry, Copy ID, Export (planned))list rows
Swipe left none destructive (read-only; no delete exists) — no swipe actions —
Pull down refresh → reset page 1 (RefreshIndicator, bypasses cache) list
Pinch/drag none (no media) —
Hardware back detail → list (filters/scroll kept); list → Settings all
Input Behaviour
/focus filter bar (global pattern: Ctrl+K is shell search; / is in-screen filter)
Tab filter controls → table → footer; visible primary focus ring (00-shared/09 §6 )
Arrow up/down move table row selection
Enter open selected entry detail
Escclear filters / close filter sheet / collapse JSON
Ctrl/Cmd+C copy JSON on detail (with SelectableText)
Ctrl/Cmd+F focus filter bar (alias of /); browser-find disabled on web via semantics where possible
Right-click context menu (same as long-press) on rows
Hover row tint m-fast; tooltip 500 ms (UTC timestamp, truncated values, full action)
Event Haptic Ref
Realtime entry appended selectionClick (subtle; not disruptive)—
Copy ID/JSON selectionClick—
Filter applied none —
Rule disabled when system haptics off; none on desktop 08 §3
Transition Duration/curve Used by
Route push (list→detail) m-base slide (phone); master-detail pane swap m-fast (≥ 840 px)detail
Realtime append slide-in m-base + primaryContainer flash list
First-load rows m-entrance stagger 40 mslist
Filter change cross-fade m-slow (content swap, no pop) list
JSON expand/collapse AnimatedSize m-fastdetail
Table hover m-fast tintdesktop table
Reduced-motion: fades only, no stagger, no flash.
Interaction Detail
Row tap (table) ripple m-fast; detail pane opens m-fast (master-detail)
Load more bottom spinner fade-in m-instant; button label "Loading…"
Realtime banner slide-in AppBanner info; auto-dismiss 6 s; tap → scroll to top + flash row
Copy ID/JSON Snackbar "Copied" + lightImpact-less (selectionClick)
Clear filters chips remove one-by-one m-fast; "Clear" resets all
Diff expand AnimatedSize; badge colors never sole signal (text + icon)
All presses respond < 100 ms (m-fast ripple).
Every network action shows pending state (skeleton, load-more spinner) — never silent.
Load-more disabled while in flight (anti-duplicate pages).
429 → countdown, no auto-retry.
Errors persist until dismissed/retried (never flash).
WS lifecycle: on connect, join tenant:{tenantId} (automatic, ws.gateway.ts:50);
on reconnect → resubscribe + background refetch (page 1 merge).
Clipboard: detail JSON copy (entire entry), correlationId copy, entry _id copy.
Deep link to entry: studylyon://settings/audit/:id → in-memory lookup; miss → load
next pages (cap (proposed), OQ-4) → miss → empty state.
No gesture implies edit/delete (server has no such paths — audit-log.repository.ts:6).
Filters map 1:1 to query params (audit.controller.ts:22-24); client never sends params
the controller ignores (sort, q, dates are (planned)).
Realtime append derives from the same event stream as persisted entries
(ws-bridge.service.ts:16-22 vs audit.handler.ts:18-25) — dedupe by _id.
Timestamps always from occurredAt (schema timestamps: false — createdAt never used
for display, audit-log.schema.ts:13, 42-43).