Implement RoleRepository with session caching
epic-role-based-access-control-data-infrastructure-task-005 — Build the RoleRepository class on top of SupabaseRoleProvider. The repository must cache resolved role assignments per session using an in-memory map keyed by session ID, map raw Supabase records to typed Role domain models, and expose a clean getRolesForCurrentUser() interface to the service layer. Implement cache invalidation on session change.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 3 - 413 tasks
Can start after Tier 2 completes
Implementation Notes
Use a Map
Register as a Riverpod Provider
Testing Requirements
Write flutter_test unit tests with a mock SupabaseRoleProvider. Test cases: (1) first call fetches from provider and caches — verify provider called once; (2) second call hits cache — verify provider still called only once total; (3) emit a session change event on the auth stream — verify cache is cleared and next call fetches from provider again (provider now called twice total); (4) provider returns empty list — verify getRolesForCurrentUser() returns empty list without throwing; (5) provider throws RoleProviderException — verify exception propagates to caller. Use a StreamController
The get_my_roles RPC call adds a network round-trip immediately after login, potentially increasing the time before the home screen renders. If Supabase RPC is slow or the roles table lacks proper indexing, users with multiple org affiliations could experience noticeable delays.
Mitigation & Contingency
Mitigation: Index user_roles on user_id and org_unit_id. Use JWT claim extraction as the primary fast path; fall back to the RPC only when claims are absent or stale. Set a 3-second timeout with a fallback to cached roles.
Contingency: If RPC latency exceeds acceptable thresholds in production, pre-fetch and embed roles into the session JWT at login time via a Supabase Auth hook, eliminating the post-login RPC entirely.
Users who belong to multiple organizations (e.g., a coordinator in one NHF chapter who is also a peer mentor in another) may have conflicting role assignments. The repository layer must correctly scope roles to the active organization context set during the organization selection step, or it could return roles from the wrong org.
Mitigation & Contingency
Mitigation: Always filter role queries by the active org_unit_id stored in the tenant session. Write integration tests that simulate multi-org users and verify only the correct org's roles are returned.
Contingency: If org-scoping logic is found to be incorrect during QA, add an explicit org_unit_id parameter to get_my_roles RPC and require the client to always pass the active org context, making the scoping explicit rather than inferred.