medium priority low complexity backend pending backend specialist Tier 5

Acceptance Criteria

A top-level `mentorLocationServiceProvider` is defined using Riverpod `Provider` or `StateNotifierProvider` and is importable from a single barrel file in the map feature
A top-level `mentorFilterServiceProvider` is defined using Riverpod `Provider` and is importable from the same barrel file
Both providers are scoped within the map feature module and do not leak into global provider scope
MentorMapBloc is wired as a `BlocProvider` that consumes `ref.read(mentorLocationServiceProvider)` and `ref.read(mentorFilterServiceProvider)` from Riverpod
Both providers expose `overrideWithValue` or `overrideWith` hooks so tests can inject mocks without modifying production code
No circular dependencies exist between the two providers
A `ProviderScope` override example is included in a test helper file demonstrating how to override providers in widget and unit tests
Build succeeds with zero Riverpod lint warnings (`riverpod_lint` clean)

Technical Requirements

frameworks
Flutter
Riverpod
BLoC
data models
MentorLocationService
MentorFilterService
MentorMapBloc
performance requirements
Providers must be lazy-initialized (not eagerly constructed at startup)
Provider disposal must release all subscriptions when the map feature is popped from the navigation stack
security requirements
No auth tokens or PII stored in provider state — services must retrieve tokens from the auth provider at call time
Provider scope must not expose location data outside the map feature module

Execution Context

Execution Tier
Tier 5

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` definitions for consistency with the existing codebase. Wire `MentorMapBloc` inside a `BlocProvider` that calls `ref.read()` inside the `create` callback so Riverpod manages the service lifecycle. To avoid a hard coupling between BLoC and Riverpod, pass services as constructor parameters to the BLoC rather than letting the BLoC call `ref` directly.

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.

Component
Mentor Location Service
service high
Epic Risks (2)
medium impact medium prob technical

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.

low impact medium prob scope

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.