critical priority medium complexity backend pending backend specialist Tier 2

Acceptance Criteria

loadRulesForChapter(chapterId) returns an ordered List<ScenarioRule> for a valid chapter ID, returning an empty list (not null) when no rules exist
loadRulesForChapter() triggers seedDefaultTemplates() automatically when the returned list is empty and the chapter is recognized as valid
saveRule(rule) persists a new rule when validateRuleJson(rule.toJson()) returns true, and returns the saved rule with a server-assigned ID
saveRule(rule) throws a ScenarioValidationException with a descriptive message when validateRuleJson returns false
deleteRule(ruleId) removes the rule from the repository and returns true; returns false (does not throw) when the ruleId does not exist
validateRuleJson(json) returns true for all JSON structures conforming to the schema defined in task-001 and false for any violation
validateRuleJson(json) populates a ValidationResult.errors list with field-level error messages for each schema violation
seedDefaultTemplates(chapterId) inserts the canonical default rule set exactly once even if called multiple times concurrently (idempotent)
seedDefaultTemplates(chapterId) does not overwrite existing rules if any rules already exist for the chapter
All public methods handle Supabase connectivity errors gracefully and surface a typed ScenarioRepositoryException rather than a raw exception
ScenarioConfigurationManager is injectable via Riverpod and its dependencies are resolved through the DI graph, not constructed manually

Technical Requirements

frameworks
Flutter
Riverpod
flutter_test
apis
Supabase REST API
Supabase Realtime (optional for live config sync)
data models
ScenarioRule
ScenarioRuleTemplate
ValidationResult
ScenarioRepositoryException
ScenarioValidationException
performance requirements
loadRulesForChapter() must complete within 500ms under normal network conditions
saveRule() must complete within 800ms including round-trip to Supabase
validateRuleJson() must complete synchronously in under 5ms (pure in-memory schema check)
security requirements
Chapter IDs must be validated against the current user's accessible chapters using Supabase Row Level Security (RLS) — do not perform manual authorization checks in Dart
Rule JSON stored in Supabase must not contain executable code fields; strip any keys not present in the schema before persistence
Supabase service role key must never be used on the client; use only the anon key with RLS policies

Execution Context

Execution Tier
Tier 2

Tier 2 - 518 tasks

Can start after Tier 1 completes

Implementation Notes

ScenarioConfigurationManager should be a plain Dart class (not a Flutter widget or BLoC) registered as a Riverpod Provider. Delegate all Supabase I/O to ScenarioRuleRepository (injected via constructor); the manager must contain zero direct Supabase calls. validateRuleJson should use the JSON schema model built in task-001 — do not re-implement schema logic here. For seedDefaultTemplates idempotency, use a Supabase upsert with an ON CONFLICT DO NOTHING strategy keyed on (chapter_id, template_name) rather than a read-then-write pattern, which is prone to race conditions.

Default templates should be defined as a Dart const list in a separate ScenarioDefaultTemplates constants file so they can be updated without modifying business logic. Keep all error types in a dedicated exceptions.dart file inside the scenario feature module.

Testing Requirements

Write unit tests using flutter_test and a mocked ScenarioRuleRepository (using Mockito or manual test doubles). Test cases must cover: (1) loadRulesForChapter returns empty list and triggers seeding, (2) loadRulesForChapter returns existing rules without re-seeding, (3) saveRule succeeds with valid JSON, (4) saveRule throws ScenarioValidationException for invalid JSON, (5) deleteRule returns true for existing ID and false for missing ID, (6) validateRuleJson passes all valid schema permutations from task-001 fixture set, (7) validateRuleJson fails with specific error messages for missing required fields, wrong types, and out-of-range values, (8) seedDefaultTemplates is idempotent under concurrent calls. Aim for 90%+ line coverage on the manager class. Integration tests against a Supabase test project should cover the RLS enforcement path.

Component
Scenario Configuration Manager
service medium
Epic Risks (2)
high impact medium prob scope

The Rule Engine must support a flexible JSON rule schema that can express compound conditions (e.g., contact_type AND wellbeing_flag AND delay_days). Underestimating schema expressiveness may require breaking changes to the rule format after coordinators have already configured rules.

Mitigation & Contingency

Mitigation: Define and freeze the rule JSON schema (trigger_type enum, metadata_conditions structure, delay logic) before any implementation begins; validate schema against all known HLF scenarios documented in the feature spec.

Contingency: If schema changes are needed after deployment, implement a schema version field and a migration utility that upgrades stored rules to the new format without coordinator intervention.

medium impact medium prob technical

Deep-link navigation to the activity wizard with pre-filled arguments may fail if the user's session has expired or if the wizard route is not yet mounted in the navigator stack, causing unhandled navigation exceptions.

Mitigation & Contingency

Mitigation: Implement session state check before navigation; if session is expired, redirect to biometric/login screen and store the pending deep-link URI for post-auth redirect using go_router's redirect mechanism.

Contingency: If post-auth redirect proves unreliable, fall back to navigating to the home screen with a visible action banner that re-triggers the wizard with pre-filled arguments.