high priority low complexity frontend pending frontend specialist Tier 1

Acceptance Criteria

Submitting with first-reminder threshold < 1 shows an inline error beneath that field: 'Must be at least 1 day'
Submitting with escalation threshold ≤ first-reminder threshold shows an inline error: 'Must be greater than the first reminder threshold'
Submitting with max count < 1 or > 10 shows an inline error: 'Must be between 1 and 10'
Inline error messages disappear as soon as the user corrects the offending field value
All three validations pass before any repository write is attempted
On successful save, a SnackBar appears with a confirmation message and an 'Undo' action button
Tapping 'Undo' in the SnackBar reverts the saved values to the previous values by calling the repository with the old data
The Save button shows a loading indicator during the async repository write
If the repository write fails, the SnackBar is replaced by an error message with a retry option
The form remains in a consistent state if the user navigates away mid-save (no orphaned state)

Technical Requirements

frameworks
Flutter
Riverpod
apis
Reminder config repository (internal)
Supabase PostgreSQL 15 (via repository layer)
data models
assignment
performance requirements
Validation must be synchronous and complete in < 1ms
Repository write should complete within 2 seconds; show loading state if exceeded
security requirements
Validation must be enforced server-side as well — client validation is UX only
No stale threshold values should be persisted if the undo write fails; surface the error clearly
ui components
Inline error text widget (design token error colour, small body text style)
AppButton (primary, with loading state variant)
SnackBar with action (using ScaffoldMessenger)
CircularProgressIndicator embedded in save button

Execution Context

Execution Tier
Tier 1

Tier 1 - 540 tasks

Can start after Tier 0 completes

Implementation Notes

Extend the ReminderThresholdFormState from task-005 with a validationErrors map (Map) and a previousValues snapshot for undo support. The save action in the notifier should: (1) validate synchronously, (2) if invalid populate validationErrors and return early, (3) if valid snapshot current persisted values, (4) call repository.saveThresholds(), (5) on success emit a saved event that triggers the SnackBar via a one-shot stream or AsyncValue. Use ScaffoldMessenger.of(context).showSnackBar() from the widget layer listening to the notifier's save result stream. For undo, store the pre-save snapshot in the notifier and expose a revertToPrevious() method.

Clear validation errors eagerly on field change using the notifier's field update methods.

Testing Requirements

Write flutter_test widget tests covering: (1) each invalid input combination triggers its corresponding inline error, (2) correcting an invalid field clears the error, (3) all-valid input triggers repository save call with correct values, (4) SnackBar with 'Undo' appears after successful save, (5) tapping Undo calls repository with previous values, (6) repository write failure shows error state. Use Riverpod ProviderScope overrides and a mock repository. Verify SnackBar presence using find.byType(SnackBar) and action label matching.

Epic Risks (2)
medium impact medium prob integration

The deep-link from the notification card to the assignment detail screen depends on the assignment detail route being stable and accepting an assignment ID parameter. If the routing contract is undocumented or changes during parallel development, the CTA will silently navigate to a fallback screen.

Mitigation & Contingency

Mitigation: Confirm the assignment detail route path and parameter contract with the team building or maintaining that screen before implementing the CTA. Add an integration test that asserts navigating from a mock notification card with a known assignment ID lands on the correct route.

Contingency: If the route is unstable, implement the deep-link as a late-bound string resolved from a central route registry, allowing the target route to be updated without changing the notification card.

medium impact medium prob technical

Visually distinguishing escalation cards from standard reminder cards using colour alone fails WCAG 1.4.1 (use of colour). Blindeforbundet users relying on screen readers must receive equivalent contextual information through semantics, not just visual styling.

Mitigation & Contingency

Mitigation: Use both colour and an icon/label difference to distinguish card types. Add explicit Semantics widgets with descriptive labels ('Escalation alert: peer mentor has not responded') so screen readers announce the type without visual context.

Contingency: If accessibility review flags the distinction, add a text badge ('Escalation') alongside the visual treatment as a code-change-only fix with no schema or service impact.