Interaction, state and motion details for the Health surfaces. Shared
interaction/motion language in 00-shared/08 . Screens (proposed); the
endpoint interaction contract is implemented and quoted.
Aspect Spec Source
Request GET /api/v1/health - no params, no body, no headers beyond standardhealth.controller.ts:27-37
Auth none - @Public() skips JWT/RBAC guards health.controller.ts:15, app.module.ts:129-131
Rate limit 30 req/min sliding window, Redis-backed health.controller.ts:16, rate-limit.constants.ts:4
Success 200, envelope-wrapped Terminus result response-envelope.interceptor.ts:47-60
Failure 503, error envelope; 429 when rate-capped http-exception.filter.ts:56-58, 73-81
Latency as fast as the slowest dependency probe; no timeout inside the check itself (non-goal, 01 §5) health.controller.ts:31-36
# Interaction Spec
I1 Enter screen immediate fetch(); skeletons for 5 cards
I2 Poll tick (30 s) silent refetch; animate only changed cards (m-fast flash)
I3 Tap down-card open S2 sheet from cached payload (zero network)
I4 Tap up-card nothing (not a button; avoids dead-affordance taps)
I5 Retry tap immediate fetch; resets poll timer on success; disabled while in-flight; countdown during 429
I6 Pull-to-refresh optional at grid top; same as Retry (skip when I5 timer active)
I7 App resume from background immediate refetch (stale rule, 07 §4)
I8 Offline AppOfflineBanner; cards show last state + "stale"; Retry stays enabled
stateDiagram-v2
[*] --> Loading
Loading --> AllUp: 200 status ok
Loading --> PartialDown: 503 error has N<5 down keys
Loading --> AllDown: 503 error has 5 down keys
Loading --> Offline: network/timeout
AllUp --> AllUp: poll tick (no change)
AllUp --> PartialDown: poll tick
PartialDown --> AllUp: retry/poll recovers
PartialDown --> Offline: retry fails w/ network error
AllUp/PartialDown/AllDown --> RateLimited: 429
RateLimited --> AllUp/PartialDown/AllDown: countdown ends → retry
Offline --> Loading: retry (connectivity restored)
Down-key counting: API card counts as down when the request itself is 503;
dependency keys come from data.error (health.controller.spec.ts:29-35).
Motion Token Use Source
Card state flash m-fast (150 ms)status change on poll 00-shared/08
Banner swap m-base (250 ms)overall verdict change 00-shared/08
Sheet bottom sheet curve S2 open/close 00-shared/03
Skeleton shimmer loop loading cards 00-shared/08
Retry, cards, banner: full focus traversal; cards announce button when
down (06 S1 a11y).
Live region on banner for state changes (00-shared/09).
No gestures required for any core action (no swipe-to-refresh dependency -
Retry button is the canonical path, 00-shared/09).