high priority medium complexity frontend pending frontend specialist Tier 1

Acceptance Criteria

A Riverpod StreamProvider named scenarioTemplatesProvider is defined, scoped by chapter ID, and streams scenario templates from the Scenario Configuration Manager
Templates are grouped by category and displayed under SectionHeader widgets in the correct order (e.g., alphabetical by category name)
Each template shows its current enabled/disabled state for the coordinator's chapter — state is chapter-scoped, not global
Screen shows a loading skeleton while the StreamProvider is in loading state on first emission
Screen updates in real-time when template configuration changes in the backend (Supabase Realtime stream)
On stream error, an error state widget is shown with a retry option that re-subscribes the StreamProvider
Provider is auto-disposed when the screen is removed from the navigation stack — stream subscription cancelled
If a new template category is added to the backend, it appears in the correct sorted position without a full reload
Chapter ID used to scope the provider is read from the authenticated user's session claims — not from a hardcoded value or URL parameter
Templates within each category are sorted alphabetically by name
Loading state shows at least 3 skeleton list items under a skeleton section header to indicate the expected content shape

Technical Requirements

frameworks
Flutter
Riverpod
apis
Supabase PostgreSQL 15
Supabase Realtime
data models
activity_type
performance requirements
Initial stream emission must render within 2 seconds on 4G
Real-time update must reflect in UI within 1 second of backend change
Stream must not cause full widget rebuild of the entire list on partial updates — use keyed list items
security requirements
Supabase Realtime subscription must enforce RLS — coordinator can only receive events for their own chapter's template configurations
JWT validated on every channel subscription renewal
Chapter ID from JWT claims is authoritative — do not use chapter ID from local state as the RLS scope
ui components
Skeleton loading widgets for section header and list items
SectionHeader with category name and item count badge
ScenarioTemplateListItem (from task-011) with live isEnabled state
ErrorStateWidget with retry button
SliverList with SliverStickyHeader (or grouped ListView) for category sections

Execution Context

Execution Tier
Tier 1

Tier 1 - 540 tasks

Can start after Tier 0 completes

Implementation Notes

Use StreamProvider.autoDispose.family, String>(chapterId) to scope by chapter. The Scenario Configuration Manager service should expose a Stream> watchTemplatesByChapter(String chapterId) method backed by Supabase's .stream() or .select().eq('chapter_id', chapterId) with Realtime enabled on the relevant table. For grouping, compute the grouped map in the provider's map operator, not in the widget's build method. Use a SliverList with a custom delegate or a package like grouped_list to render category sections efficiently.

For sticky section headers, evaluate if the existing codebase already uses a sticky header package — prefer consistency over introducing a new dependency. Anticipate that task-013 will need to call a toggle handler — define the onToggleChanged callback signature in ScenarioTemplateListItem now (bool newValue, String templateId) -> void.

Testing Requirements

Write widget and unit tests using flutter_test. Unit test 1: scenarioTemplatesProvider emits correctly grouped and sorted ScenarioTemplateViewModel list from mock repository stream. Unit test 2: Provider correctly filters templates by the chapter ID from the auth session. Unit test 3: When stream emits a new value, the grouped list updates to reflect the change.

Widget test 1: Loading skeleton renders on first empty stream emission. Widget test 2: Correct number of SectionHeaders and list items rendered per category group. Widget test 3: Error widget shown on stream error, retry re-subscribes. Widget test 4: Provider auto-disposes (stream cancelled) when screen popped.

Mock the Scenario Configuration Manager using Mockito or manual stubs — use StreamController to simulate real-time updates in tests.

Component
Scenario Configuration Screen
ui medium
Epic Risks (2)
high impact medium prob technical

If the scheduler runs concurrently (e.g., two overlapping cron invocations due to edge function retry), duplicate prompts could be dispatched before the first run's history records are committed, breaking the deduplication guarantee.

Mitigation & Contingency

Mitigation: Use a Postgres advisory lock or unique constraint on (user_id, scenario_id, activity_ref) in the prompt history table to make concurrent writes idempotent; design the scheduler to check history inside a transaction.

Contingency: If concurrency issues persist in production, add a distributed lock via Supabase Edge Function concurrency limit (max_instances=1) for the evaluation function as a hard guard.

medium impact medium prob scope

Coordinators may find scenario configuration unclear if trigger conditions are expressed as raw JSON or technical terminology, leading to misconfiguration and irrelevant prompts being sent to peer mentors.

Mitigation & Contingency

Mitigation: Design the ScenarioConfigurationScreen to display human-readable descriptions of each template's trigger condition (e.g., 'Send 3 days after first contact if wellbeing concern was flagged') rather than raw rule properties; validate with an HLF coordinator in a design review before implementation.

Contingency: If coordinators still misconfigure rules after launch, add a preview mode that shows a simulated prompt based on a test activity before the rule is enabled.