medium priority low complexity documentation pending documentor Tier 6

Acceptance Criteria

Documentation covers the complete FCM token lifecycle: registration on first login, refresh on token rotation, revocation on logout or device change, and re-registration after app reinstall
Trigger service section documents all Supabase database event subscriptions (INSERT/UPDATE triggers per table), the dispatch decision tree (preference check → token lookup → FCM send), and retry/failure behaviour
Payload schema table lists every field (notification_id, type, title, body, category, deep_link, metadata, sent_at) with type, constraints, and example values
Deep link route resolution map covers all notification categories (activity_reminder, certification_expiry, pause_status, scenario_prompt, system) and maps each to the correct Flutter route path
Sequence diagrams exist for all three message states: foreground (FirebaseMessaging.onMessage), background (onBackgroundMessage isolate), and terminated (getInitialMessage cold-start)
Preference filtering logic is documented showing the exact filter chain applied before dispatch (user enabled flag per category + org-level overrides)
Document is stored in the repository under /docs/notifications/ and is referenced from the top-level ARCHITECTURE.md
All diagrams use a consistent notation (Mermaid or PlantUML) so they render in GitHub/GitLab markdown previews

Technical Requirements

frameworks
Flutter
Riverpod
firebase_messaging
apis
FCM HTTP v1 API
Supabase Realtime
Supabase Database Triggers
data models
fcm_tokens
notification_preferences
notifications
performance requirements
Documentation must accurately reflect real dispatch latency targets (< 2 s p95 from trigger to FCM send)
Token lookup query plan documented with index usage confirmed
security requirements
Document must note that FCM server key is stored only in Supabase Edge Function secrets, never in client code
Payload must not include PII fields; document approved fields list explicitly
RLS policy summary included showing which roles can read notification_preferences

Execution Context

Execution Tier
Tier 6

Tier 6 - 158 tasks

Can start after Tier 5 completes

Implementation Notes

Write documentation after tasks 014 and 015 are merged so the implementation is final. Use Mermaid sequence diagrams embedded in Markdown for maximum portability — avoid external diagram tools that require login. Structure the doc in four sections: (1) Token Lifecycle, (2) Trigger & Dispatch Pipeline, (3) Payload Schema Reference, (4) Client-Side Handling (foreground/background/terminated). For the deep link map, use a Markdown table with columns: category | route | screen | params.

Highlight the foreground vs terminated difference clearly — terminated state requires getInitialMessage() called in main() before runApp(), which is a common gotcha. Cross-reference the RLS policy doc from task-003 for the preference filtering section.

Testing Requirements

No automated tests for documentation itself. Peer review required: at least one backend developer and one Flutter developer must sign off that the sequence diagrams match the actual implementation. A documentation smoke-test checklist should be attached to the PR: (1) open each deep link route on a physical device to confirm navigation, (2) trigger each notification category and verify the payload fields match the schema table.

Component
Notification Trigger Service
service high
Epic Risks (4)
high impact high prob technical

Flutter's background message handler for FCM must run in a separate Dart isolate. Incorrect dependency initialization in the isolate (e.g., attempting to access Riverpod providers or Supabase before initialization) will cause silent crashes on Android when the app is terminated, resulting in missed notifications that are invisible in crash reporting.

Mitigation & Contingency

Mitigation: Use a minimal top-level background handler function annotated with @pragma('vm:entry-point') that only stores the raw RemoteMessage payload to a platform channel or shared preferences. Process the payload in the main isolate on next app launch. Write an explicit test for terminated-state message handling on Android.

Contingency: If isolate crashes are observed, implement a native Android FirebaseMessagingService subclass that handles background messages without Flutter isolate complexity, falling back to a database-insert-only approach for terminated-state notifications.

medium impact medium prob technical

Supabase Edge Functions can experience cold-start latency of 1–3 seconds after periods of inactivity. For high-frequency events like assignment creation, cumulative cold starts could cause dispatch delays exceeding the 30-second SLA, reducing the perceived reliability of the notification system.

Mitigation & Contingency

Mitigation: Configure the Edge Function with a keep-warm ping mechanism or use Supabase database webhooks that invoke the function directly on row insert to minimize cold-start frequency. Batch preference lookups within the function to reduce per-invocation Supabase round-trips.

Contingency: If latency SLA is consistently breached, move to a polling or Realtime-subscription architecture within the Edge Function, or pre-compute dispatch targets at preference-save time to eliminate per-dispatch preference queries.

high impact low prob security

If the deep link handler does not perform server-side role validation before rendering the target screen, a peer mentor who receives a mis-configured notification payload containing a coordinator-only route could access restricted data, violating the role-based access control invariants.

Mitigation & Contingency

Mitigation: The deep link handler must check the user's current role from the RoleStateManager before constructing the navigation route. Coordinator-only routes must be listed in a deny-list checked against the current role. The go_router route guard is a second line of defence.

Contingency: If a role bypass is discovered in testing, immediately add the affected route to the deep link handler deny-list and add a regression test. Audit all notification payload types for route targets that could expose cross-role data.

medium impact low prob dependency

FCM v1 HTTP API enforces per-project send quotas. For large organisations with many active peer mentors receiving simultaneous assignment notifications, batch dispatch events (e.g., bulk coordinator assignments) could approach quota limits and result in dropped notifications with 429 errors logged silently.

Mitigation & Contingency

Mitigation: Implement exponential backoff retry logic in the Edge Function for 429 responses. Design bulk assignment flows to dispatch notifications in batches with a configurable delay between batches. Monitor FCM console quotas during load testing.

Contingency: If quota limits are hit, implement a notification queue table in Supabase and a separate Edge Function that processes the queue with rate limiting, ensuring eventual delivery without exceeding FCM quotas.