critical priority medium complexity frontend pending frontend specialist Tier 4

Acceptance Criteria

Screen is only accessible to users with the coordinator or org_admin role; peer mentors navigating to this route are redirected
All assigned peer mentors for the coordinator's organisation are loaded via PauseManagementService and rendered in a scrollable ListView
Each mentor card displays: full name, PauseStatusIndicator, expected return date (formatted locale-aware, hidden if not set), and certification expiry date
A filter bar with options 'All', 'Active', 'Paused', 'Cert Expired' is rendered above the list and filters the visible mentors client-side
The active filter chip is visually distinguished from inactive chips with sufficient contrast
Empty state is shown with a descriptive message when no mentors match the selected filter
A full-screen loading indicator is shown on initial data fetch; a pull-to-refresh gesture triggers a reload
API errors display an inline error banner with a retry action
Tapping a mentor card navigates to the mentor detail page
The list supports at least 200 mentor entries without jank (use ListView.builder, not ListView with children)
All interactive elements meet WCAG 2.2 AA touch target and contrast requirements
Filter state is preserved on back navigation (not reset when returning from mentor detail)

Technical Requirements

frameworks
Flutter
BLoC
Riverpod
apis
PauseManagementService.getMentorRoster(coordinatorId)
Supabase REST via service layer
data models
assignment
certification
performance requirements
ListView must use ListView.builder for lazy rendering to handle 200+ mentor entries
Client-side filter must apply within 16ms (one frame) for lists up to 200 items
Initial data load must complete within 2 seconds on a standard 4G connection
security requirements
Supabase RLS must ensure coordinators can only see mentors within their own organisation
Role check must be enforced both client-side (route guard) and server-side (RLS policy)
No mentor PII should be logged to console or analytics
ui components
PauseStatusIndicator widget
Filter chip bar (All / Active / Paused / Cert Expired)
Mentor card widget (name, status, dates)
ListView.builder (scrollable list)
Empty state widget
Pull-to-refresh (RefreshIndicator)
Error banner with retry action

Execution Context

Execution Tier
Tier 4

Tier 4 - 323 tasks

Can start after Tier 3 completes

Implementation Notes

Use a dedicated RosterBloc with states: RosterLoading, RosterLoaded(mentors, activeFilter), RosterError. Store the full unfiltered mentor list in the BLoC state and apply filter as a derived getter to avoid unnecessary API calls on filter change. Use ListView.builder with a fixed itemExtent where possible for scroll performance. The mentor card should be a separate stateless widget to simplify testing and reuse on other coordinator screens.

Certification expiry date formatting should use the app's shared date formatting utility — do not inline DateFormat calls. Ensure the filter bar chips use the existing design token colour system for selected/unselected states.

Testing Requirements

Write widget tests using flutter_test covering: (1) list renders correct number of mentor cards from mocked service data, (2) each filter chip correctly filters the visible list, (3) empty state renders when filter returns no results, (4) loading indicator is shown while data is fetching, (5) error banner appears and retry re-calls the service, (6) pull-to-refresh triggers data reload. Write a golden test for the mentor card widget to catch visual regressions. Test role-based access by asserting the screen redirects non-coordinator users.

Component
Coordinator Pause Roster Screen
ui medium
Epic Risks (3)
medium impact medium prob technical

Concurrent status transitions (e.g., coordinator and automated scheduler both attempting to update the same mentor's status simultaneously) may produce race conditions or inconsistent state in the database, leading to audit log gaps or incorrect notifications.

Mitigation & Contingency

Mitigation: Implement all status transitions as atomic Postgres RPC functions with optimistic locking (version column or updated_at check). Use database-level constraints rather than application-level guards as the final enforcement point.

Contingency: Add a compensation job that reconciles status and log table consistency on each nightly scheduler run, surfacing any discrepancies to coordinator dashboards.

medium impact medium prob integration

The coordinator-to-mentor assignment relationship may not always be 1:1 or may be stale (coordinator reassigned after a pause was set), causing notifications to be sent to the wrong coordinator or not sent at all.

Mitigation & Contingency

Mitigation: Query the assignment relationship at notification dispatch time rather than caching it at pause creation time. Add a fallback to notify the chapter administrator if no active coordinator assignment exists.

Contingency: Log all undeliverable notification attempts with the originating mentor ID so administrators can manually follow up, and surface undelivered notification counts on the coordinator dashboard.

medium impact low prob technical

The CoordinatorPauseRosterScreen may load slowly for coordinators managing large rosters with many concurrent certification expiry queries, degrading usability on low-bandwidth mobile connections.

Mitigation & Contingency

Mitigation: Use a single Supabase RPC that joins mentor status, certification expiry, and assignment data in one query rather than N+1 individual calls. Implement pagination with a configurable page size and skeleton loading states.

Contingency: Add an offline cache of the last-fetched roster state using Riverpod with SharedPreferences, ensuring coordinators can at minimum view stale data when connectivity is poor.