Implement NoAccessRouteGuard GoRouter redirect callback
epic-no-access-screen-access-control-task-005 — Implement the NoAccessRouteGuard as a GoRouter redirect callback. The guard must intercept every navigation attempt for authenticated users, check whether the current role is in the blocked set via AccessDenialService, and redirect to the no-access terminal route (/no-access) when blocked. Logout navigation (/logout and /auth routes) must be explicitly allowed even when the role is blocked.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 4 - 323 tasks
Can start after Tier 3 completes
Implementation Notes
Use the RouterNotifier pattern from Riverpod + GoRouter: create a NoAccessRouterNotifier extends Notifier
true default ensures fail-secure behavior during loading. Keep the redirect callback a pure function — extract the allowlist check into a separate static method for testability.
Testing Requirements
Integration tests using flutter_test with a ProviderScope wrapping a GoRouter test harness. Test scenarios: (1) global_admin role → initial route redirects to /no-access, (2) global_admin navigates to /logout → allowed, (3) global_admin navigates to /auth/login → allowed, (4) coordinator role → no redirect applied, (5) role changes from coordinator to global_admin mid-session → router.refresh() triggers and next navigation goes to /no-access, (6) already on /no-access with global_admin → no redirect loop (returns null). Use pumpWidget with MaterialApp.router and verify tester.routeInformationProvider.value.location.
If the GoRouter redirect callback evaluates the no-access route itself as a blocked destination, it will trigger an infinite redirect loop, crashing the navigator.
Mitigation & Contingency
Mitigation: Add an explicit guard condition in the redirect callback: return null (no redirect) when the current location is already the no-access route or the logout route. Write a dedicated unit test covering this exact scenario.
Contingency: If the redirect loop is detected in production, deploy a hotfix that adds the null-return guard; the feature can be toggled off via the existing feature-flag infrastructure while the fix is prepared.
The access-denial-service may read role state before authentication completes (e.g. during app resume), causing a temporary false-positive block that redirects valid peer-mentor users to the no-access screen.
Mitigation & Contingency
Mitigation: Subscribe to the role-state-manager's loading/ready lifecycle and only evaluate role-based access once the RBAC state is confirmed as loaded. Return a 'pending' state that causes the guard to defer rather than redirect.
Contingency: Add a retry mechanism: if a user lands on the no-access screen but their role subsequently resolves as non-blocked, automatically navigate them to the role-based home screen.