Expose Riverpod providers for both services
epic-geographic-peer-mentor-map-core-services-task-011 — Create Riverpod StateNotifierProvider or Provider definitions for MentorLocationService and MentorFilterService so they can be injected throughout the widget tree. Ensure providers are scoped to the map feature and are properly overridable in tests. Wire the MentorMapBloc as a BlocProvider that reads both Riverpod providers.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 5 - 253 tasks
Can start after Tier 4 completes
Implementation Notes
Define both providers in a dedicated `providers.dart` file within `lib/features/map/`. Use `riverpod_annotation` with `@riverpod` code generation if the project already uses it — otherwise use manual `Provider
Expose a `mapFeatureProviders` list for use in integration test `ProviderScope` overrides. Do not use `ref.watch` inside BLoC constructors — read once at creation.
Testing Requirements
Unit tests: verify that `mentorLocationServiceProvider` and `mentorFilterServiceProvider` can be overridden via `ProviderContainer` with mock implementations and that `MentorMapBloc` receives the overridden instances. Widget test: render a minimal widget tree with `ProviderScope` overrides and assert the bloc is created without errors. Integration test: confirm providers are properly disposed when the feature scope is removed. Target 90%+ line coverage on the provider definition file.
The dual BLoC state machines (map view state + filter state) may introduce subtle synchronisation bugs where filter changes do not correctly re-trigger viewport queries, causing stale data to appear on the map.
Mitigation & Contingency
Mitigation: Define all BLoC state transitions in a state diagram before implementation. Use flutter_bloc's BlocObserver in development mode to log every state transition. Write explicit unit tests for filter-change → re-query transitions.
Contingency: If state synchronisation bugs appear in integration testing, refactor to a single unified BLoC that owns both map viewport state and filter state, eliminating cross-BLoC dependencies.
Cached mentor location data may become stale (mentors move, pause, or revoke consent) and coordinators in offline mode could be shown incorrect mentor information, leading to wasted outreach.
Mitigation & Contingency
Mitigation: Display a clear timestamp on cached data indicating when it was last synced. Set cache TTL to 24 hours and show an 'offline — data from [date]' banner. Revoked consent removes the mentor from the cache on next successful sync via contact-cache-sync-repository.
Contingency: If cache staleness causes user complaints, reduce TTL to 4 hours and implement background sync on app foreground. Accept that very-recently-revoked mentors may appear briefly in offline mode — document this as a known limitation in the privacy policy.