Connect Detail Sheet dismiss action to Prompt History
epic-scenario-based-follow-up-prompts-scheduler-and-ui-task-010 — Implement the dismiss flow in the Detail Bottom Sheet: when a coordinator taps 'Dismiss', call the Prompt History Repository to mark the prompt as dismissed with reason and timestamp, then close the sheet. Dismissed prompts must not reappear in the notification list during the cooldown window.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 8 - 48 tasks
Can start after Tier 7 completes
Implementation Notes
Use a StateNotifier or AsyncNotifier to manage the dismiss flow state (idle, loading, success, error) and expose it to the sheet widget via Riverpod. The reason selection dialog should use an enum DismissReason with values like alreadyHandled, notRelevant, willFollowUpLater — never accept raw strings from the UI. For the optimistic close pattern: pop the sheet immediately on button tap, then await the repository call in the background; if it fails, show a SnackBar from the parent screen (pass a GlobalKey
The cooldown filtering must be in the Supabase query (WHERE dismissed_at IS NULL OR dismissed_at < NOW() - INTERVAL '...'). Coordinate with the backend task that defines the prompt_history table schema to confirm column names before writing the repository method.
Testing Requirements
Write integration tests and widget tests using flutter_test. Integration test 1: Full dismiss flow — tap Dismiss → select reason → confirm → verify markPromptDismissed called with correct promptId, reason, and a UTC timestamp. Integration test 2: After dismissal, prompt notification list provider no longer returns the dismissed prompt. Widget test 1: Dismiss button shows loading indicator while repository call in flight.
Widget test 2: SnackBar error shown when repository returns error, sheet stays open. Widget test 3: Dismiss button absent/disabled for non-coordinator role. Widget test 4: Swiping sheet down without tapping Dismiss does NOT call markPromptDismissed. Mock the PromptHistoryRepository in all tests — do not hit Supabase.
Aim for 85%+ branch coverage on the dismiss flow.
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.
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.