Add offline cache for scenario rules
epic-scenario-based-follow-up-prompts-foundation-task-006 — Extend ScenarioRuleRepository with an offline-capable caching layer using flutter_secure_storage or Hive so the mobile client can read rule configuration without a live network connection. Implement a cache-first strategy: return cached rules immediately and refresh from Supabase in the background. Include cache invalidation when chapter context changes and a TTL of 24 hours.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 3 - 413 tasks
Can start after Tier 2 completes
Implementation Notes
Check the existing codebase for any established caching utilities or storage abstractions before introducing a new pattern. If Hive is already a dependency, use a dedicated Hive box named 'scenario_rules_cache'. If only flutter_secure_storage is available, serialize the List
For the cache-first + background refresh pattern, return a Stream> from fetchRulesForChapter — yield cached value immediately, then yield refreshed value when background fetch completes. Alternatively, expose an explicit refreshRules() method and rely on Riverpod state for reactivity. The chapter change invalidation can be triggered by listening to an authentication state change provider. Ensure the 24-hour TTL is calculated server-time-agnostic using DateTime.now() on device.
Testing Requirements
Unit tests with flutter_test: (1) when cache is valid, fetchRulesForChapter returns cached rules without calling Supabase; (2) when cache is empty, Supabase is called and result is cached; (3) when cache is expired (timestamp > 24h), Supabase is called synchronously and cache is refreshed; (4) when chapter changes, old cache is invalidated; (5) background refresh failure does not throw — stale cache is retained; (6) cache key is chapter-scoped (rule set for chapter A not returned for chapter B request); (7) logout clears all cached rules. Use a fake/mock for the underlying storage (Hive or flutter_secure_storage) and a mock for the network repository. Integration test: install app, fetch rules while online, enable airplane mode, restart app, assert rules still available.
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.