Role-Based Access Control
Feature Detail
Description
This feature implements a multi-role authorization system that controls what each authenticated user can see and do within the app. Roles include global admin, organization admin, coordinator, and peer mentor, with the possibility of a user holding multiple roles across different organizations or local associations. After login, users with multiple roles or memberships are presented with an organization and role selection screen. Users whose role grants no access to a given context see a dedicated no-access screen. A role switch widget allows eligible users to toggle between roles without re-authenticating. Role assignments are stored in the User Role Repository and enforced by the Permission Guard service on every protected route.
Analysis
Role-based access control is architecturally foundational — without it, no other feature can safely be delivered to the right users. NHF explicitly requires handling members in up to five local associations simultaneously with no double-reporting, which demands precise role and membership scoping. Coordinators need elevated permissions for proxy registration and bulk operations, while peer mentors must be restricted to their own data. The no-access screen and role switch widget reduce support burden by giving users clear feedback and self-service options rather than silent failures or confusing blank states. This feature directly enables the multi-organization structure required by all participating organizations.
Implemented using Flutter BLoC for role state management with Riverpod for dependency injection of the Role Authorization Service. Route protection is handled via a Permission Guard integrated into the GoRouter redirect mechanism — every route declares its required role, and the guard redirects unauthenticated or unauthorized users to the appropriate screen. The User Role Repository queries Supabase for the user's roles and organization memberships, caching results in the Role Config Store for offline resilience. The organization selection screen appears post-login when multiple memberships exist, persisting the selection to local state. Role switching re-evaluates permissions and triggers a navigation reset to prevent stale UI state from prior role context.
Dependencies
Definition of Done
Components (7)
User Stories (25)
As a As a Global Administrator
I want I want the no-access screen to provide me with a clear path to the admin portal when I access standard app flows not intended for my role
So that So that I am not confused by peer mentor or coordinator screens I should not interact with, and I can quickly navigate to the elevated tooling designed for platform administration
- Given a user authenticated as a Global Administrator, when they attempt to access standard peer mentor routes such as activity registration or contacts, then the Permission Guard redirects them to the No-Access Screen
- Given the No-Access Screen is displayed to a Global Administrator, when they view it, then the screen includes an action to navigate to the admin portal
- Given a Global Administrator is on the No-Access Screen, when they view the explanation, then it clearly states that their role requires the admin portal rather than the standard app
- +2 more
As a As a user
I want I want the app to remember my role and organizational context when I am offline
So that So that I can continue using the app in field conditions with limited connectivity without being locked out or losing my session context
- Given a user has previously authenticated and their role data has been cached, when the device goes offline, then the app continues to function with the cached role and organization context
- Given the device is offline and the user navigates to a protected route, when the Permission Guard evaluates access, then it uses the cached role data from the Role Config Store
- Given the device reconnects to the network, when the session is active, then the Role Config Store is refreshed with the latest role data from Supabase
- +2 more
As a As a user
I want I want the app to remember my role and organizational context when I am offline
So that So that I can continue using the app in field conditions with limited connectivity without being locked out or losing my session context
- Given a user has previously authenticated and their role data has been cached, when the device goes offline, then the app continues to function with the cached role and organization context
- Given the device is offline and the user navigates to a protected route, when the Permission Guard evaluates access, then it uses the cached role data from the Role Config Store
- Given the device reconnects to the network, when the session is active, then the Role Config Store is refreshed with the latest role data from Supabase
- +2 more
As a As a user
I want I want to switch my active role using the role switch widget without logging out and back in
So that So that I can efficiently move between my different role contexts without the friction of a full re-authentication cycle
- Given a user holds more than one role, when they view any screen, then the Role Switch Widget is visible
- Given a user with a single role, when they view any screen, then the Role Switch Widget is not displayed
- Given the Role Switch Widget is visible, when the user selects a different role, then the active role changes without requiring re-authentication
- +3 more
As a As a user
I want I want the app to fully reset its navigation stack when I switch roles
So that So that I do not see data or UI state from my previous role context after switching, preventing confusing mixed-role experiences or accidental actions taken in the wrong role
- Given a user switches roles via the Role Switch Widget, when the role switch completes, then the navigation stack is fully cleared and the user lands on the home screen for the new role
- Given a user was viewing a restricted screen under their previous role, when they switch to a different role, then the previous screen is not visible and back navigation does not return to it
- Given a user was mid-way through a multi-step workflow such as an activity wizard when they initiated a role switch, when the switch completes, then the workflow is abandoned and the user is on the new role's home screen
- +2 more
As a As a user
I want I want the app to remember my role and organizational context when I am offline
So that So that I can continue using the app in field conditions with limited connectivity without being locked out or losing my session context
- Given a user has previously authenticated and their role data has been cached, when the device goes offline, then the app continues to function with the cached role and organization context
- Given the device is offline and the user navigates to a protected route, when the Permission Guard evaluates access, then it uses the cached role data from the Role Config Store
- Given the device reconnects to the network, when the session is active, then the Role Config Store is refreshed with the latest role data from Supabase
- +2 more
As a As a user
I want I want to switch my active role using the role switch widget without logging out and back in
So that So that I can efficiently move between my different role contexts without the friction of a full re-authentication cycle
- Given a user holds more than one role, when they view any screen, then the Role Switch Widget is visible
- Given a user with a single role, when they view any screen, then the Role Switch Widget is not displayed
- Given the Role Switch Widget is visible, when the user selects a different role, then the active role changes without requiring re-authentication
- +3 more
As a As a user
I want I want the app to fully reset its navigation stack when I switch roles
So that So that I do not see data or UI state from my previous role context after switching, preventing confusing mixed-role experiences or accidental actions taken in the wrong role
- Given a user switches roles via the Role Switch Widget, when the role switch completes, then the navigation stack is fully cleared and the user lands on the home screen for the new role
- Given a user was viewing a restricted screen under their previous role, when they switch to a different role, then the previous screen is not visible and back navigation does not return to it
- Given a user was mid-way through a multi-step workflow such as an activity wizard when they initiated a role switch, when the switch completes, then the workflow is abandoned and the user is on the new role's home screen
- +2 more
As a As a Organization Administrator
I want I want to assign, modify, and revoke roles for users within my organization
So that So that I can control who has access to which features and maintain accurate access control as staff and volunteer roles change over time, without depending on platform-level support
- Given a user authenticated as an Organization Administrator, when they navigate to user management, then they see all users within their organization with their current role assignments
- Given an Organization Administrator assigns a role to a user, when the assignment is saved, then the User Role Repository is updated and the affected user's next session reflects the new role
- Given an Organization Administrator assigns a role, when the change is persisted, then the affected user's cached role data is invalidated so stale permissions are not used
- +3 more
As a As a user
I want I want the app to remember my role and organizational context when I am offline
So that So that I can continue using the app in field conditions with limited connectivity without being locked out or losing my session context
- Given a user has previously authenticated and their role data has been cached, when the device goes offline, then the app continues to function with the cached role and organization context
- Given the device is offline and the user navigates to a protected route, when the Permission Guard evaluates access, then it uses the cached role data from the Role Config Store
- Given the device reconnects to the network, when the session is active, then the Role Config Store is refreshed with the latest role data from Supabase
- +2 more
As a As a user
I want I want to switch my active role using the role switch widget without logging out and back in
So that So that I can efficiently move between my different role contexts without the friction of a full re-authentication cycle
- Given a user holds more than one role, when they view any screen, then the Role Switch Widget is visible
- Given a user with a single role, when they view any screen, then the Role Switch Widget is not displayed
- Given the Role Switch Widget is visible, when the user selects a different role, then the active role changes without requiring re-authentication
- +3 more
As a As a user
I want I want to see a dedicated no-access screen with a clear explanation and actionable navigation options when I attempt to access a restricted area
So that So that I understand why I cannot access the content and can take appropriate next steps such as switching roles or contacting support, rather than experiencing a silent failure or blank screen
- Given a user with an insufficient role attempts to access a restricted route, when the Permission Guard evaluates the request, then the user is redirected to the No-Access Screen
- Given the No-Access Screen is displayed, when the user views it, then it shows a clear human-readable explanation of why access was denied
- Given the user has multiple roles and is on the No-Access Screen, when they view the screen, then a role switch option is visible and functional
- +3 more
As a As a user
I want I want to select which organization and local association context to work in after logging in
So that So that my activities, reports, and data are scoped to the correct organization and I avoid contributing to double-reporting across local associations
- Given a user with memberships in multiple organizations, when authentication succeeds, then the Organization Selection Screen is displayed before the home screen
- Given the Organization Selection Screen is displayed, when the user selects an organization, then the session context is set to that organization and the user is navigated to the home screen
- Given a user with only one organization membership, when authentication succeeds, then the Organization Selection Screen is skipped and the user proceeds directly to the home screen
- +2 more
As a As a Peer Mentor (Likeperson)
I want I want the app to restrict my view to only my own activities, contacts, assignments, and expense claims
So that So that I cannot accidentally view or modify another peer mentor's data, and sensitive data about other users is protected in compliance with GDPR and organizational privacy requirements
- Given a user authenticated as a Peer Mentor, when they attempt to navigate to a coordinator-only route such as bulk registration or approval queue, then the Permission Guard redirects them to the No-Access Screen
- Given a user authenticated as a Peer Mentor, when they view their activity list, then only activities registered by or assigned to them are displayed
- Given a user authenticated as a Peer Mentor, when they view their contacts, then only their own assigned contacts are shown
- +2 more
As a As a user
I want I want every protected route in the app to automatically verify my current role before allowing navigation to complete
So that So that I cannot access restricted features through deep links, programmatic navigation, or back-button gestures that might otherwise bypass role-based access checks
- Given any protected route in the app, when a user navigates to it via any method including tap, back, or deep link, then the Permission Guard evaluates the user's current role before allowing navigation
- Given a user attempts to access a route via a deep link that exceeds their current role's permissions, when the Permission Guard evaluates the link, then the user is redirected to the No-Access Screen rather than the requested route
- Given a user is not authenticated, when they attempt to access any protected route, then the Permission Guard redirects them to the login screen
- +2 more
As a As a user
I want I want to see a dedicated no-access screen with a clear explanation and actionable navigation options when I attempt to access a restricted area
So that So that I understand why I cannot access the content and can take appropriate next steps such as switching roles or contacting support, rather than experiencing a silent failure or blank screen
- Given a user with an insufficient role attempts to access a restricted route, when the Permission Guard evaluates the request, then the user is redirected to the No-Access Screen
- Given the No-Access Screen is displayed, when the user views it, then it shows a clear human-readable explanation of why access was denied
- Given the user has multiple roles and is on the No-Access Screen, when they view the screen, then a role switch option is visible and functional
- +3 more
As a As a user
I want I want to select which organization and local association context to work in after logging in
So that So that my activities, reports, and data are scoped to the correct organization and I avoid contributing to double-reporting across local associations
- Given a user with memberships in multiple organizations, when authentication succeeds, then the Organization Selection Screen is displayed before the home screen
- Given the Organization Selection Screen is displayed, when the user selects an organization, then the session context is set to that organization and the user is navigated to the home screen
- Given a user with only one organization membership, when authentication succeeds, then the Organization Selection Screen is skipped and the user proceeds directly to the home screen
- +2 more
As a As a Coordinator
I want I want my coordinator role to automatically grant me access to proxy registration, bulk activity registration, the approval queue, and member overview features
So that So that I can efficiently manage multiple peer mentors' activities and approve expense claims without needing to request elevated access separately for each feature
- Given a user authenticated as a Coordinator, when they navigate to proxy registration, then they are granted access and the screen loads with the peer mentor selection widget
- Given a user authenticated as a Coordinator, when they navigate to bulk registration, then they can access the screen and select peer mentors from their organizational scope
- Given a user authenticated as a Coordinator, when they navigate to the reimbursement approval queue, then they see all pending claims for their organizational scope
- +3 more
As a As a user
I want I want every protected route in the app to automatically verify my current role before allowing navigation to complete
So that So that I cannot access restricted features through deep links, programmatic navigation, or back-button gestures that might otherwise bypass role-based access checks
- Given any protected route in the app, when a user navigates to it via any method including tap, back, or deep link, then the Permission Guard evaluates the user's current role before allowing navigation
- Given a user attempts to access a route via a deep link that exceeds their current role's permissions, when the Permission Guard evaluates the link, then the user is redirected to the No-Access Screen rather than the requested route
- Given a user is not authenticated, when they attempt to access any protected route, then the Permission Guard redirects them to the login screen
- +2 more
As a As a user
I want I want to see a dedicated no-access screen with a clear explanation and actionable navigation options when I attempt to access a restricted area
So that So that I understand why I cannot access the content and can take appropriate next steps such as switching roles or contacting support, rather than experiencing a silent failure or blank screen
- Given a user with an insufficient role attempts to access a restricted route, when the Permission Guard evaluates the request, then the user is redirected to the No-Access Screen
- Given the No-Access Screen is displayed, when the user views it, then it shows a clear human-readable explanation of why access was denied
- Given the user has multiple roles and is on the No-Access Screen, when they view the screen, then a role switch option is visible and functional
- +3 more
As a As a user
I want I want to select which organization and local association context to work in after logging in
So that So that my activities, reports, and data are scoped to the correct organization and I avoid contributing to double-reporting across local associations
- Given a user with memberships in multiple organizations, when authentication succeeds, then the Organization Selection Screen is displayed before the home screen
- Given the Organization Selection Screen is displayed, when the user selects an organization, then the session context is set to that organization and the user is navigated to the home screen
- Given a user with only one organization membership, when authentication succeeds, then the Organization Selection Screen is skipped and the user proceeds directly to the home screen
- +2 more
As a As a user
I want I want every protected route in the app to automatically verify my current role before allowing navigation to complete
So that So that I cannot access restricted features through deep links, programmatic navigation, or back-button gestures that might otherwise bypass role-based access checks
- Given any protected route in the app, when a user navigates to it via any method including tap, back, or deep link, then the Permission Guard evaluates the user's current role before allowing navigation
- Given a user attempts to access a route via a deep link that exceeds their current role's permissions, when the Permission Guard evaluates the link, then the user is redirected to the No-Access Screen rather than the requested route
- Given a user is not authenticated, when they attempt to access any protected route, then the Permission Guard redirects them to the login screen
- +2 more
As a As a user
I want I want to see a dedicated no-access screen with a clear explanation and actionable navigation options when I attempt to access a restricted area
So that So that I understand why I cannot access the content and can take appropriate next steps such as switching roles or contacting support, rather than experiencing a silent failure or blank screen
- Given a user with an insufficient role attempts to access a restricted route, when the Permission Guard evaluates the request, then the user is redirected to the No-Access Screen
- Given the No-Access Screen is displayed, when the user views it, then it shows a clear human-readable explanation of why access was denied
- Given the user has multiple roles and is on the No-Access Screen, when they view the screen, then a role switch option is visible and functional
- +3 more
As a As a user
I want I want to select which organization and local association context to work in after logging in
So that So that my activities, reports, and data are scoped to the correct organization and I avoid contributing to double-reporting across local associations
- Given a user with memberships in multiple organizations, when authentication succeeds, then the Organization Selection Screen is displayed before the home screen
- Given the Organization Selection Screen is displayed, when the user selects an organization, then the session context is set to that organization and the user is navigated to the home screen
- Given a user with only one organization membership, when authentication succeeds, then the Organization Selection Screen is skipped and the user proceeds directly to the home screen
- +2 more
As a As a user
I want I want every protected route in the app to automatically verify my current role before allowing navigation to complete
So that So that I cannot access restricted features through deep links, programmatic navigation, or back-button gestures that might otherwise bypass role-based access checks
- Given any protected route in the app, when a user navigates to it via any method including tap, back, or deep link, then the Permission Guard evaluates the user's current role before allowing navigation
- Given a user attempts to access a route via a deep link that exceeds their current role's permissions, when the Permission Guard evaluates the link, then the user is redirected to the No-Access Screen rather than the requested route
- Given a user is not authenticated, when they attempt to access any protected route, then the Permission Guard redirects them to the login screen
- +2 more