Register route guard in GoRouter configuration
epic-no-access-screen-access-control-task-007 — Register the NoAccessRouteGuard redirect callback in the app's GoRouter configuration, ensuring it runs after authentication guards but before role-based home routing. Validate that the guard integrates correctly with the existing role-route-guard (048) in the redirect chain without conflicts.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 6 - 158 tasks
Can start after Tier 5 completes
Implementation Notes
In the GoRouter configuration (typically in app_router.dart or router_provider.dart): chain the redirect callbacks using a composed function rather than a single monolithic redirect. Pattern: redirect: (context, state) { final authRedirect = authGuard.redirect(context, state); if (authRedirect != null) return authRedirect; final noAccessRedirect = noAccessGuard.redirect(context, state); if (noAccessRedirect != null) return noAccessRedirect; final roleRedirect = roleRouteGuard.redirect(context, state); return roleRedirect; }. This explicit chaining makes the order clear and maintainable. For refreshListenable, use Listenable.merge([authChangeNotifier, noAccessRouterNotifier]) — do not replace the existing auth notifier, extend it.
Verify that role-route-guard (048) has /no-access in its passthrough paths so it does not try to redirect a global_admin away from the no-access screen. Add a comment above the guard chain explaining the execution order and the reason for each guard's position.
Testing Requirements
Integration tests using flutter_test with full ProviderScope + GoRouter setup matching the production app configuration. Test scenarios: (1) unauthenticated user → lands on /auth/login (auth guard fires, NoAccessRouteGuard skipped), (2) global_admin authenticated → lands on /no-access (NoAccessRouteGuard fires, role guard does not redirect away), (3) coordinator authenticated → lands on /coordinator-home (NoAccessRouteGuard passes, role guard routes correctly), (4) peer_mentor authenticated → lands on /mentor-home, (5) role changes from coordinator to global_admin during session → router refresh → next navigation goes to /no-access. Run existing guard integration tests to confirm no regressions. Use pumpAndSettle and verify router.location after each navigation.
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.