Implement ScenarioRuleRepository data layer
epic-scenario-based-follow-up-prompts-foundation-task-005 — Implement the ScenarioRuleRepository Dart class that performs CRUD operations against the scenario_rules Supabase table. Expose methods: fetchRulesForChapter(chapterId), fetchRuleById(ruleId), upsertRule(ScenarioRule), and deleteRule(ruleId). Use the existing Supabase client provider. Include typed model classes (ScenarioRule, TriggerCondition) with fromJson/toJson serialization.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 2 - 518 tasks
Can start after Tier 1 completes
Implementation Notes
Follow the existing repository pattern in the codebase — examine other repository classes (e.g. activity repository or contact repository) for consistent structure before implementing. Place model classes in `lib/features/scenario_rules/data/models/` and the repository in `lib/features/scenario_rules/data/repositories/`. Use `freezed` and `json_serializable` if the codebase already uses them for model generation — do not introduce a new serialization pattern.
Define a `ScenarioRuleRepositoryProvider` using Riverpod's `Provider` or `StateNotifierProvider` following the established pattern. For error handling, wrap all Supabase calls in try/catch and rethrow as domain-specific exceptions. The TriggerCondition class likely needs to handle multiple trigger types (e.g. inactivity duration, event type) — design it as a sealed class or use a type discriminator field in JSON.
Ensure toJson produces snake_case keys matching the database column names.
Testing Requirements
Unit tests using flutter_test and a mocked SupabaseClient: (1) fetchRulesForChapter returns a List
Supabase RLS policies for chapter-scoped rule access may interact unexpectedly with service-role keys used by the Edge Function, potentially blocking backend reads or leaking cross-chapter data.
Mitigation & Contingency
Mitigation: Write and review RLS policies in isolation with automated policy tests before merging; define a dedicated service-role bypass policy scoped to the edge function's Postgres role.
Contingency: If RLS blocks the edge function, temporarily use a bypass policy with audit logging while a permanent fix is implemented; escalate to a Supabase security review.
FCM device tokens become invalid when users reinstall the app or revoke permissions; stale tokens cause silent delivery failures that are hard to detect without explicit error handling.
Mitigation & Contingency
Mitigation: Implement token invalidation handling in PushNotificationDispatcher that removes stale tokens from the database on FCM 404/410 responses; log all delivery failures with structured output.
Contingency: If token hygiene proves unreliable, add a periodic token refresh job that re-registers all active users' tokens via the FCM registration endpoint.