high priority low complexity frontend pending frontend specialist Tier 5

Acceptance Criteria

A single constant (e.g., NoAccessRouteConstants.allowlistedPaths) of type Set<String> is defined and contains at minimum: /logout, /auth, /no-access
The allowlist uses prefix matching so /auth covers /auth/login, /auth/org-select, and any future /auth/* sub-routes
The allowlist constant is defined in a dedicated file (e.g., no_access_route_constants.dart) — not inlined in the guard class
The route guard references the constant by name — no duplicate string literals for route paths in the guard implementation
Adding a new route to the allowlist requires editing only NoAccessRouteConstants, not the guard redirect logic
A code comment on the constant explains the purpose: 'Routes accessible to blocked roles (e.g. global_admin) to allow logout and re-authentication'
Unit test verifies all required paths (/logout, /auth, /no-access) are present in the set

Technical Requirements

frameworks
Flutter
Dart (const Set<String>)
apis
GoRouter route path constants (should reference existing AppRoutes constants if defined)
performance requirements
Use const Set<String> for O(1) lookup — not a List which requires O(n) iteration
security requirements
Allowlist must be minimal — only routes strictly necessary for logout and re-auth flows
Any new route added to the allowlist must have a documented justification comment explaining why blocked roles need access

Execution Context

Execution Tier
Tier 5

Tier 5 - 253 tasks

Can start after Tier 4 completes

Implementation Notes

Create lib/features/no_access/routing/no_access_route_constants.dart with: abstract class NoAccessRouteConstants { static const Set allowlistedPaths = {'/logout', '/auth', '/no-access'}; }. Use an abstract class with static const rather than a top-level const to keep the namespace organized. The guard then checks: allowlistedPaths.any((prefix) => state.location.startsWith(prefix)). If the project already has a centralized AppRoutes class with route constants, reference those constants here instead of string literals — e.g., {AppRoutes.logout, AppRoutes.auth, AppRoutes.noAccess}.

This prevents route rename regressions. Keep the set small and well-commented — resist the urge to add speculative routes.

Testing Requirements

Unit tests using flutter_test. Test scenarios: (1) NoAccessRouteConstants.allowlistedPaths contains /logout, (2) contains /auth as prefix, (3) contains /no-access, (4) does NOT contain any main app routes (e.g., /home, /contacts). Also verify the guard correctly uses startsWith prefix matching against the set — test that /auth/login is covered by the /auth entry. These are fast, pure constant validation tests with no mocking required.

Component
No-Access Route Guard
service low
Epic Risks (2)
high impact medium prob technical

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.

medium impact low prob integration

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.