high priority low complexity frontend pending frontend specialist Tier 3

Acceptance Criteria

Tapping the 'Single proxy' mode card navigates the user to the Peer Mentor Single Selector screen; back navigation returns them to this screen without state loss
Tapping the 'Bulk' mode card navigates the user to the Peer Mentor Multi-Select List screen; back navigation returns them to this screen without state loss
A user with the 'peer_mentor' role is redirected away from this screen (to a no-access or home screen) before any content is rendered
A user with the 'coordinator' role can access the screen and both navigation paths function correctly
A user with the 'admin' role can access the screen and both navigation paths function correctly
The role guard reads from the active Riverpod auth/session provider and does not make a Supabase network call on every route evaluation
Route guard unit tests cover: coordinator allowed, admin allowed, peer_mentor denied, unauthenticated user denied
Navigation uses the project's existing GoRouter or Navigator setup — no new routing library is introduced

Technical Requirements

frameworks
Flutter
Riverpod
flutter_test
data models
UserRole (coordinator, admin, peer_mentor)
AuthSession / UserProfile
performance requirements
Role check must be synchronous from cached provider state — no async await on navigation tap
Navigation push completes within one frame (~16 ms)
security requirements
Role guard must run on the Flutter client AND be enforced server-side on any Supabase RLS policies — client guard is UX only
Do not expose role enum values in URL query parameters
ui components
GoRouter redirect or Navigator route guard callback
Riverpod Provider/StateNotifier for current user role
No-access or redirect screen (reuse existing project component)

Execution Context

Execution Tier
Tier 3

Tier 3 - 413 tasks

Can start after Tier 2 completes

Implementation Notes

Use Riverpod's ref.read() inside the tap callbacks to retrieve the current user role synchronously from a cached provider — avoid FutureProvider here since the user is already authenticated by the time they reach this screen. For the route guard, implement a GoRouter redirect that checks the role; if GoRouter is not used, wrap the screen's initState or build method with a post-frame callback that pops/replaces if the role is insufficient. Keep the navigation calls as named routes (string constants) matching the existing routing file — do not hardcode path strings inline. Add the two new target routes (single selector, multi-select) to the router definition in this task so downstream tasks can depend on them.

Testing Requirements

Write unit tests using flutter_test and Riverpod's ProviderContainer overrides to test the route guard logic in isolation: override the auth provider with a mock that returns each role variant and assert the correct redirect behaviour. Write widget tests that pump the ProxyModeSelectorScreen with each role, tap each mode card, and verify the correct route was pushed using a NavigatorObserver mock. Aim for 100% branch coverage on the guard function. No integration test against Supabase is required for this task.

Component
Proxy Mode Selector Screen
ui low
Epic Risks (2)
medium impact medium prob technical

NHF coordinators may manage dozens of peer mentors across multiple chapters. If the multi-select list renders all contacts in a single unsorted ListView, performance degrades with 50+ items, and coordinators cannot efficiently locate a specific mentor, increasing the probability of selection errors and wrong-person proxy registrations.

Mitigation & Contingency

Mitigation: Use a SliverList with itemExtent for fixed-height rows to enable O(1) scroll position calculation. Implement the search filter using a debounce utility operating on an in-memory list (no extra API calls). Sort the contact list alphabetically by default. Add chapter-filter chips above the list for NHF's multi-chapter coordinators.

Contingency: If performance issues arise in testing with real data sets, introduce pagination with a 'load more' trigger at the bottom of the list and cache rendered rows using Flutter's AutomaticKeepAliveClientMixin.

high impact medium prob security

NHF has a complex 12-national-association / 9-region / 1,400-chapter hierarchy. It is ambiguous whether a coordinator can proxy-register for peer mentors outside their immediately assigned chapter. If the contact list is not correctly scoped by RLS, coordinators might see — and register on behalf of — peer mentors they do not manage, creating fraudulent activity records that skew Bufdir statistics.

Mitigation & Contingency

Mitigation: The Proxy Contact List Provider must query only peer mentors linked to the coordinator's own chapter scope via RLS. Add an explicit Supabase query test asserting that a coordinator from chapter A cannot retrieve peer mentors from chapter B. Display each mentor's chapter affiliation in the list row so coordinators can visually verify scope.

Contingency: If RLS scope is found to be too permissive in testing, apply a server-side coordinator_id filter as a secondary guard on the query. Block the feature release until the scope test passes consistently.