Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

10 — Interaction Specification (Reports Module)

Interaction contracts: polling engine, transitions, error handling, motion. Motion tokens m-fast / m-base from 00-shared/08; shared interaction baseline 00-shared/08.


1. The polling engine (core interaction)

Server contract: GET /reports/:jobId returns the full job doc (reports.controller.ts:20-24, reports.service.ts:46-50); statuses queued | processing | completed | failed (report-job.schema.ts:13-18).

Algorithm

start(jobId):
  poll() every 2s while status in {queued, processing}
  on completed → stop; render result (S5)
  on failed    → stop; render error + Retry
  on 404       → stop; not-found state
  on network/5xx → pause cycle; show banner + "Retry check";
                   manual retry resumes cycle
terminal status is sticky; a fresh screen open with terminal doc does not poll

Parameters

AspectValueRationale
Interval2 sfast enough for UX; harmless load (1 doc query, indexed {tenantId,status}, report-job.schema.ts:47)
Max consecutive failures2then pause; exponential backoff for manual retry (1 s → 2 s → 4 s)
Timeout per request10 sglobal client HTTP timeout (00-shared/07)
Max overall waitnoneserver has no job TTL; user can leave and return (B2)

Jitter & life

  • Poll times: 2 s ± 400 ms jitter (thundering-herd avoidance at term end when a school generates N cards).
  • Poll cycle lifecycle: starts on S4 initState; cancelled on dispose; a Timer (not a loop) so cancellation is clean.

2. Status transitions (UI)

FromToTriggerTransition
queuedprocessingpollbadge swap (C2), progress row gains elapsed timer — m-fast crossfade
processingcompletedpollsuccess reveal; result card slides in m-base; haptic light (mobile)
processingfailedpollerror card + error text; m-fast fade
any non-terminalofflinenetwork failbanner slide-in; cycle pauses
offlineresumedmanual retrybanner clears; cycle resumes

No transition animation for the badge itself beyond color change — keep perceptual noise low at 2 s cadence.

3. Screen-level interactions

S2 Generate form

  • Submit → button loading; on success: navigate pushReplacement to S4 (form is dead after submission; back returns to catalog).
  • Failure: inline errors, form intact.
  • report_card without required ids: inline error BEFORE network (08 §3.1).

S3 Job list

  • Pull-to-refresh: re-poll visible rows (only non-terminal ones).
  • Row tap → S4. Failed row menu: Retry (re-POST params → new jobId, reports.service.ts:31-43).
  • Filter chips (All/Running/Completed/Failed) filter locally — no query API.

S4 Job detail

  • Auto-poll (1). Elapsed timer ticks 1 s while processing.
  • Retry (failed): confirm dialog → new POST → pushReplacement to new job detail.
  • "New report from these params": prefill S2 from params (:33).

S5 Result

  • Scrollable content; export CTAs disabled w/ tooltip "coming soon" (planned).
  • Share sheet (forward-looking) once PDF exists.

4. Error taxonomy (client)

ErrorDetectionUX
404poll GETnot-found state; back to list
401interceptorsilent refresh, resume poll
429interceptorpause poll 30 s; countdown snackbar; no auto-retry (00-shared/10)
networktimeout/connectionbanner + pause (1)
job failedpoll GET statusterminal UI (2)

5. Motion & haptics

  • Status badge changes: m-fast (150 ms) color/opacity crossfade.
  • Result reveal: m-base (250 ms) slide-up + fade.
  • Screen push: shared push transition (00-shared/08).
  • Haptics: HapticFeedback.mediumImpact on completed reveal; light on failed.

6. Keyboard / adaptive (S2)

  • resizeToAvoidBottomInset; next-chain; tablet: form left, live job preview right (05 §Keyboard).