high priority medium complexity integration pending frontend specialist Tier 2

Acceptance Criteria

ReminderNotificationCard reads reminder state from the shared notification provider and re-renders automatically when state changes
CoordinatorEscalationNotificationCard reads escalation state from the shared provider and re-renders on state changes
Both cards display a skeleton/shimmer loading state while the initial data load is in progress
Both cards display a non-destructive error state (message + retry button) when the provider emits an error
New reminders arriving via Supabase Realtime cause the card list to update without a full page reload
Resolving an escalation removes the corresponding card from the escalation list in real time
All stream subscriptions and Riverpod listeners are cancelled/disposed when the widget is removed from the tree
No memory leaks are detectable in Flutter DevTools memory profiler after repeated mount/unmount cycles
Cards do not re-render unnecessarily when unrelated state changes occur (use select() or specific providers)
The integration does not introduce circular provider dependencies

Technical Requirements

frameworks
Flutter
BLoC
Riverpod
Supabase Realtime
apis
Supabase Realtime (websocket)
Supabase PostgreSQL 15
data models
assignment
performance requirements
Cards must reflect real-time state updates within 500ms of the Realtime event being received
Widget rebuild scope must be minimised — only the affected card should rebuild on state change
No more than one active Realtime subscription per notification type per screen instance
security requirements
Supabase Realtime subscription must enforce RLS — users only receive events for their own organisation's rows
JWT must be validated on every channel subscription; handle token expiry by re-subscribing
Realtime payloads must contain only row IDs and status — full data fetched from API, not from payload
ui components
Shimmer/skeleton placeholder matching card dimensions
Inline error widget with retry button
AnimatedList or similar for smooth card addition/removal

Execution Context

Execution Tier
Tier 2

Tier 2 - 518 tasks

Can start after Tier 1 completes

Implementation Notes

Use ConsumerWidget (Riverpod) or BlocBuilder (BLoC) — whichever matches the foundation epic's established pattern — to connect cards to state. If using Riverpod, prefer ref.watch(reminderNotificationsProvider) with select() to narrow rebuilds. If using BLoC, use BlocSelector. For Supabase Realtime, the subscription should be established in the provider/BLoC, not in the widget layer — this ensures proper lifecycle management.

The widget should only react to emitted states, never manage subscriptions directly. Use AutoDispose providers (Riverpod) or close() in BLoC's close() override to handle cleanup. For AnimatedList, maintain a local list in the widget's state synced to the provider's list, using AnimatedList.of(context).removeItem() for removal animations. Avoid calling setState after dispose by checking mounted before any async callback.

Testing Requirements

Write flutter_test widget tests covering: (1) cards render correctly when provider emits loaded state, (2) skeleton shown when provider is in loading state, (3) error widget shown when provider emits error, (4) card list updates when a new reminder is emitted, (5) escalation card is removed when escalation is resolved in state. Use Riverpod ProviderScope overrides or BLoC's MockBloc to inject controlled state sequences. Verify no lingering subscriptions by asserting provider dispose callbacks are called. Integration test (using flutter_test's integration_test package): subscribe a test Supabase Realtime channel, emit a test event, assert the card list updates.

Component
Reminder Notification Card
ui low
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.