10 — Interaction Specification (Scheduler Module)
- 1. List → Detail drill-down (S1 → S2)
- 2. Polling loop (S1)
- 3. Create schedule (S3)
- 4. Manual trigger (S5,
(proposed)) - 5. Remove schedule (S1/S2)
- 6. DLQ actions (S6,
(proposed)) - 7. Motion & feedback
- 8. a11y
Interactions of the Scheduled Jobs console, including the polling loop, trigger/remove flows and DLQ actions. Screen refs per 05/06; motion tokens per 00-shared/08.
1. List → Detail drill-down (S1 → S2)
- Row tap →
/admin/scheduler/jobs/:queue/:name(queue+name disambiguate two0 8 * * *jobs:fee-reminder→payment-reminder,admission-reminder-scan→admission-reminder,scheduler.service.ts:92-110). - Detail loads run history
(proposed); header keeps C1/C2/C3 identity. - Back returns to list preserving scroll + filters.
2. Polling loop (S1)
flowchart LR
A[Loaded] --> B[Timer 60s] --> C{cache age < 60s?}
C -->|yes| D[skip request]
C -->|no| E[GET /scheduler]
E --> F[render; update badges]
E -->|error| G[keep last-good + snackbar]
F --> B
- Single-flight: one request in flight; new ticks coalesce.
- Background: timer paused via
WidgetsBindingObserver; on resume → immediate staleness check. - Status enrichments
(proposed)are fetched together with the list, not per row (N+1 avoided).
3. Create schedule (S3)
- FAB "+ New" →
AppBottomSheet(max-width 640 dp); fields per F1. - Preset chips (C8) fill the pattern field; regex re-validates on blur
(
dto:20-24). - Submit →
POST /scheduler(scheduler.controller.ts:30-35); optimistic row insert with rollback on error; duplicate warn per08 §F1.
4. Manual trigger (S5, (proposed))
- Row menu "Run now" → F2 dialog →
(proposed)POST /scheduler/:queue/:name/trigger. - In-flight: confirm button spinner, dialog not re-openable; success →
snackbar + S2 history refresh; the trigger is fire-and-forget server-side
(matches job classes,
jobs/*.job.ts). - Idempotency note displayed in dialog (F2).
5. Remove schedule (S1/S2)
- "Remove" → F3 dialog (name+pattern+queue) →
DELETE /scheduler?queue=&name=&pattern=(scheduler.controller.ts:37-46) →removeRepeatable(jobName, {pattern, tz:'UTC'})(scheduler.service.ts:188-196). Optimistic removal, rollback + snackbar on failure.
6. DLQ actions (S6, (proposed))
- Replay → F4 confirm →
(proposed)POST /scheduler/dlq/:id/retry; must preservecorrelationId/tenantIdfrom the record (dlq.setup.ts:12-21) soIdempotencyServicededup keys stay stable (idempotency.service.ts:12). - Delete → F4 confirm →
(proposed)DELETE /scheduler/dlq/:id. - Status of replay visible in S1/S2 after one poll cycle.
7. Motion & feedback
| Action | Motion (00-shared/08) | Feedback |
|---|---|---|
| Row status change | badge cross-fade m-fast | live region announce |
| Sheet open | m-base slide up | — |
| Trigger/remove | button spinner in place | snackbar (success) / inline error |
| Poll failure | none | keep-last-good + snackbar once per minute |
| Offline | banner slide m-base | AppOfflineBanner |
8. a11y
- Badge: icon + text, never color alone (C1).
- Forms: labels linked, errors in live regions, focus first invalid (F1).
- Cron text:
Semantics(label: "cron pattern, 5 fields")— never spoken as raw five tokens. - Dialog focus trap while open (S3/S5/S6 confirms).