Wire Role Resolution into Auth Session Post-Login
epic-role-based-access-control-state-and-services-task-007 — Integrate RoleResolutionService into the post-login auth flow so that after successful BankID/Vipps/email authentication, the service is automatically invoked to resolve and set the active role before navigation to the home screen. Ensure the role state is cleared (resetOnLogout) when the auth session ends. Register all providers in the Riverpod ProviderScope.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 4 - 323 tasks
Can start after Tier 3 completes
Implementation Notes
Listen to Supabase.instance.auth.onAuthStateChange in a top-level Riverpod Provider (authStateProvider). On AuthChangeEvent.signedIn, call ref.read(roleResolutionServiceProvider).resolveRoles(userId). Use a GoRouter redirect that checks RoleStateManager state — if role is not yet resolved, redirect to a /loading route. Once RoleStateManager emits a resolved state, GoRouter's refreshListenable triggers re-evaluation of the redirect, allowing navigation to proceed.
This avoids imperative navigation calls and keeps routing declarative. The no-access screen for globalAdmin is a hard requirement per all three workshop organisations — it must be unreachable by any other navigation path.
Testing Requirements
Widget tests with flutter_test: mock Supabase Auth stream to emit AuthChangeEvent.signedIn with various user types, assert correct navigation outcome (home, no-access, role-pending). Test logout flow: emit signedOut event, assert RoleStateManager state is cleared. Test that navigation does not fire before resolution completes (use a delayed mock). Integration test: full BankID/Vipps PKCE callback simulation using local deep link trigger, assert role resolved and home screen rendered.
Test token refresh event does not clear or re-resolve role.
A coordinator's permissions could be revoked by an admin while they are actively using the app. If the permission checker relies solely on the cached role state from login, the coordinator could continue performing actions they are no longer authorized for until the next login.
Mitigation & Contingency
Mitigation: The Permission Checker Service must re-validate against the Role Repository (not just in-memory state) before high-impact actions. Implement a configurable staleness window (e.g., 15 minutes) after which role data is refreshed from Supabase in the background.
Contingency: If a revoked permission is detected during a pre-action check, immediately clear the cached role state, force a re-resolution from Supabase, and display an inline error explaining the permission change rather than crashing or silently failing.
Using both BLoC and Riverpod in the same state management layer for roles risks state synchronization bugs where one system updates before the other, causing widgets to render with stale role data during the switch transition.
Mitigation & Contingency
Mitigation: Choose a single primary state management approach (Riverpod StateNotifier is recommended) for role state and wrap the BLoC pattern within it if legacy code requires BLoC interfaces. Establish a single source-of-truth provider that all consumers read from.
Contingency: If synchronization bugs appear during integration testing, introduce a RoleStateReady gate widget that delays rendering of role-dependent UI until the state notifier emits a confirmed resolved state, preventing partial renders.
Hardcoded permission constants per role can become a maintenance burden as new features are added across 61 total features, leading to permission definitions that are scattered, stale, or inconsistent.
Mitigation & Contingency
Mitigation: Centralize all role-permission mappings in a single RolePermissions constants file with named action keys. Enforce that no widget or service directly checks role type strings; all checks must go through the Permission Checker Service.
Contingency: If permission definitions drift out of sync, introduce a validation test suite that cross-references all registered permission constants against their usage sites and fails the CI build if an undefined permission key is referenced.