critical priority medium complexity backend pending backend specialist Tier 0

Acceptance Criteria

ScenarioRule Dart class defined as an immutable value object with fields: id (String), chapterId (String), contactTypeFilter (List<String>?), wellbeingFlags (List<String>?), durationThresholdMinutes (int?), delayMinHours (double), delayMaxHours (double), promptTemplateId (String), enabled (bool), createdAt (DateTime), updatedAt (DateTime)
ScenarioRule implements fromJson(Map<String, dynamic>) and toJson() for Supabase serialization
ScenarioRule implements copyWith() for immutable updates
ScenarioRule implements == and hashCode based on id field
JSON schema file authored at lib/features/scenario_prompts/models/scenario_rule_schema.json covering all required and optional fields with type constraints
JSON schema enforces: delayMinHours ≥ 0, delayMaxHours > delayMinHours, promptTemplateId is non-empty string
JSON schema allows null/absent contactTypeFilter and wellbeingFlags (both are optional filters)
Dart unit tests validate that fromJson correctly deserializes a full example payload and a minimal payload (only required fields)
Dart unit tests validate that toJson produces a round-trippable payload (fromJson(toJson(rule)) == rule)
JSON schema is registered in ConfigurationManager's validation map under key 'scenario_rule'

Technical Requirements

frameworks
Flutter
Dart
Riverpod
apis
Supabase (scenario_rules table — column names must match toJson keys)
data models
ScenarioRule
PromptTemplate
performance requirements
fromJson deserialization of a list of 100 rules must complete in under 50ms on a mid-range device
security requirements
ScenarioRule must not store raw user PII — contactTypeFilter contains type codes only, not user identifiers
JSON schema validation must reject any rule payload with unknown extra fields (additionalProperties: false) to prevent injection of unexpected rule behavior

Execution Context

Execution Tier
Tier 0

Tier 0 - 440 tasks

Implementation Notes

Define the Dart model using freezed or a hand-written immutable class — prefer freezed for consistency with the rest of the codebase if it is already in use. The JSON key names must exactly match the Supabase column names in snake_case (e.g., chapter_id, contact_type_filter, delay_min_hours). Do not use camelCase keys in toJson. For the delay window, model delayMinHours and delayMaxHours as double (not int) to support half-hour precision (e.g., 0.5 hours = 30 min).

The enabled flag is critical: the Rule Engine must check this flag before evaluating any rule, so make the default value true but always include it explicitly in serialization. The JSON schema is the contract between the backend configuration UI (future admin portal) and the mobile app — treat it as a published API. Include a $schema, $id, title, and description at the top level for documentation purposes.

Testing Requirements

Write pure Dart unit tests (no Flutter widget test runner needed) in test/features/scenario_prompts/models/scenario_rule_test.dart. Cover: (1) fromJson with full payload, (2) fromJson with minimal payload (only required fields, optional fields null), (3) toJson round-trip, (4) copyWith preserves unchanged fields, (5) equality comparison (two rules with same id are equal), (6) JSON schema validation passes for valid payload, (7) JSON schema validation rejects payload with delayMinHours > delayMaxHours, (8) JSON schema validation rejects payload missing promptTemplateId. Use a JSON schema validation library compatible with Dart (e.g., json_schema) or implement validation inline in ConfigurationManager.

Component
Scenario Rule Engine
service high
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.