high priority low complexity infrastructure pending backend specialist Tier 4

Acceptance Criteria

A `supabaseRoleProviderProvider` (or equivalently named provider) exposes a SupabaseRoleProvider instance, injecting the Supabase client via the existing supabase-client-provider pattern
A `roleRepositoryProvider` exposes a RoleRepository instance, injecting SupabaseRoleProvider via ref.watch
Both providers are defined in a dedicated file (e.g., `role_providers.dart`) in the role data layer, not scattered across feature files
Any widget or BLoC in the app can read roleRepositoryProvider via ref.read/ref.watch without importing Supabase directly
Provider registration does not break existing Riverpod provider graph — no circular dependencies
Providers are overridable in tests via ProviderScope overrides without modifying production code
The Supabase client provider reference matches the existing pattern used in other repositories in the project (no new pattern introduced)

Technical Requirements

frameworks
Flutter
Riverpod
apis
Supabase Flutter SDK
performance requirements
Providers are lazily initialized — no Supabase calls at registration time, only when first read
security requirements
Supabase client must be sourced from the existing secure provider, never instantiated directly in role providers

Execution Context

Execution Tier
Tier 4

Tier 4 - 323 tasks

Can start after Tier 3 completes

Implementation Notes

Follow the exact provider naming and file placement convention already used in the project for other data layer providers (e.g., document_providers.dart, activity_providers.dart). Use `Provider` (not ChangeNotifierProvider) unless RoleRepository extends ChangeNotifier — prefer the simpler Provider unless reactivity is required. Use `ref.onDispose` to cancel the auth subscription when the provider is disposed. Export both providers from the role data layer's barrel file so consumers have a single import.

Do not use `keepAlive: true` unless the repository must survive all widget tree rebuilds — check existing patterns first.

Testing Requirements

Unit tests: use ProviderContainer with overrides to inject a mock SupabaseRoleProvider and verify RoleRepository receives it correctly. Verify that reading roleRepositoryProvider twice from the same ProviderContainer returns the same instance (singleton behavior). Integration test: boot a ProviderScope with real providers against a local Supabase instance and confirm RoleRepository.fetchRolesForUser() resolves without error. Verify that overriding supabaseRoleProviderProvider in a ProviderScope correctly replaces the implementation in RoleRepository (essential for test isolation).

Component
Role Repository
data medium
Epic Risks (2)
medium impact medium prob technical

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.

high impact medium prob integration

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.