high priority medium complexity backend pending backend specialist Tier 1

Acceptance Criteria

ScenarioMessageTemplate model is defined with locale-keyed title and body string templates (Map<String, ScenarioLocalizedStrings> keyed by locale code 'nb', 'en')
buildMessage(ScenarioType scenarioType, String locale, Map<String, dynamic> context) returns a ScenarioMessage with non-null, non-empty title and body strings
All defined ScenarioType enum values have corresponding templates for both 'nb' and 'en' locales; missing template throws a descriptive TemplateNotFoundException
Context variable substitution is implemented: {{daysInactive}}, {{sessionCount}}, {{daysToExpiry}}, {{mentorFirstName}} are replaced correctly in both title and body
If an unsupported locale is passed, the builder falls back to 'en' without throwing an exception
If a context variable referenced in the template is missing from the context map, the builder substitutes a safe empty string or documented fallback, not a raw placeholder
Norwegian (nb) templates use correct grammatical forms (e.g. 'dag' vs 'dager' for singular/plural) — tested explicitly
Generated title strings do not exceed 65 characters (FCM/APNs display limit for notifications)
Generated body strings do not exceed 240 characters
ScenarioEvaluationConfig threshold values are accessible from within the builder for dynamic message tuning (e.g. referencing inactivityThresholdDays in message copy)

Technical Requirements

frameworks
Flutter
Dart
Riverpod
performance requirements
buildMessage executes in under 5ms — no I/O, purely in-memory string interpolation
Template definitions loaded once at service initialisation, not re-parsed on each call
security requirements
No PII beyond first name included in push notification payload — full contact details never embedded in push content
mentorFirstName sanitised to strip any HTML or special characters before interpolation to prevent injection in notification display

Execution Context

Execution Tier
Tier 1

Tier 1 - 540 tasks

Can start after Tier 0 completes

Implementation Notes

Define templates as compile-time constants in a dedicated Dart file (e.g. scenario_message_templates.dart) — avoid loading from external files at runtime to eliminate I/O latency and simplify deployment. Use simple string interpolation via a regex-replace utility rather than a heavy templating library. Norwegian plural rules for 'dag/dager' and 'økt/økter' should be handled by a small pluralise(int count, String singular, String plural) helper.

Keep ScenarioMessageTemplate immutable (final fields, const constructors where possible). The builder should be a pure class with no side effects — all state comes from constructor injection (ScenarioEvaluationConfig). This makes it trivially testable without mocking.

Testing Requirements

Write unit tests using flutter_test. Test buildMessage for every ScenarioType and both locales ('nb', 'en'). Test context substitution for all four context variables in isolation and combined. Test singular/plural handling in Norwegian strings.

Test fallback to 'en' when an unknown locale is provided. Test that missing context variables produce safe fallback output (no raw {{placeholder}} strings in output). Test title and body length constraints are not exceeded for the longest plausible input values (e.g. a 20-character mentorFirstName, maximum daysInactive value).

Achieve 95% branch coverage on the builder class.

Component
Scenario Notification Content Builder
service medium
Epic Risks (3)
high impact medium prob dependency

FCM service account key and APNs certificate configuration may be missing or misconfigured in the Supabase Edge Function secrets store, blocking end-to-end push delivery testing until resolved by the infrastructure owner.

Mitigation & Contingency

Mitigation: Raise a credentials-setup task in the project board at epic start; document the exact secret names required in scenario-evaluation-config so the infrastructure owner can provision them independently of development work.

Contingency: Implement a mock push-notification-dispatcher stub that records payloads to the database for local testing, allowing the rest of the feature to proceed while credentials are obtained.

high impact low prob security

Incorrect RLS policies on the scenario_notifications or notification_preferences tables could allow one user to read or modify another user's notification records, constituting a data privacy breach.

Mitigation & Contingency

Mitigation: Write dedicated RLS policy tests using Supabase's built-in test framework before any application code touches the tables; require a peer security review of all policy definitions before merging.

Contingency: If a policy gap is discovered post-merge, immediately disable the affected table's read policy, notify the security lead, and deploy a hotfix with corrected policies before re-enabling access.

medium impact medium prob dependency

Norwegian Bokmål ARB localisation strings for all scenario message templates may not be available at implementation time, causing content-builder tests to fail and delaying integration.

Mitigation & Contingency

Mitigation: Define all required ARB message keys in a tracked document shared with the content owner at epic kickoff; use English placeholder strings that follow the final format so template injection logic can be tested independently.

Contingency: Ship with English-only strings in the first release and gate Norwegian strings behind a feature flag that is enabled once translations are reviewed and approved.