medium priority low complexity documentation pending documentor Tier 6

Acceptance Criteria

Documentation is written in English, stored as Markdown in the repository under `docs/summary-pipeline/`
Architecture overview diagram (ASCII or Mermaid) illustrates the full pipeline flow: cron trigger → scheduler → per-org fan-out → aggregation → outlier detection → persistence → notification dispatch
Scheduler cron configuration section documents the pg_cron schedule expression, the trigger times (UTC), and how to modify the schedule
Outlier threshold management section documents the database schema, default values, how to update org-specific thresholds via SQL or RPC, and the resolution priority order (org-specific > global default)
Notification payload section documents the FCM/APNs payload structure, the deep-link URI scheme, and how to test notifications in a development environment
Idempotency design section explains the state machine (null → in_progress → completed/failed), the composite key structure, and the behaviour for each existing state
Operational runbook includes step-by-step instructions for: (1) manually triggering summary generation for one org via HTTP POST, (2) re-running a failed period, (3) checking scheduler run logs, (4) updating outlier thresholds for an org
All code examples in the documentation are tested and working against the implemented system
Documentation references the integration test suite for validation procedures

Technical Requirements

frameworks
Markdown
Mermaid (for diagrams)
apis
Supabase CLI commands (supabase functions invoke)
scheduler_runs table query examples
outlier_thresholds RPC or SQL examples
data models
SchedulerRun
SummaryPeriod
OutlierThreshold
security requirements
Documentation must not include real API keys, service role keys, or production database credentials
All code examples must use placeholder values (e.g. YOUR_SERVICE_ROLE_KEY) with clear labelling

Execution Context

Execution Tier
Tier 6

Tier 6 - 158 tasks

Can start after Tier 5 completes

Implementation Notes

Structure the documentation as an index file (`docs/summary-pipeline/README.md`) linking to sub-documents: `architecture.md`, `scheduler-config.md`, `threshold-management.md`, `notifications.md`, `idempotency.md`, `runbook.md`. Use Mermaid `sequenceDiagram` for the pipeline flow and `stateDiagram-v2` for the idempotency state machine — both render natively in GitHub. In the runbook, include the exact `curl` command for the manual trigger endpoint and the exact `supabase functions invoke` command. Add a Troubleshooting section with the three most common failure modes identified during integration testing: (1) stuck in_progress records, (2) missing push tokens, (3) pg_cron not firing.

Include a table mapping period_type to cron schedule, trigger date, and example period_key strings for developer reference.

Testing Requirements

Documentation review checklist: verify all curl/CLI commands in the runbook execute successfully against the local Supabase dev instance. Have one developer who was not involved in implementation follow the runbook and report any ambiguities. Verify the Mermaid diagram renders correctly in GitHub Markdown preview. Verify all internal links between documentation sections resolve correctly.

Component
Summary Generation Scheduler
infrastructure medium
Epic Risks (4)
high impact medium prob technical

Supabase pg_cron or Edge Function retries could trigger multiple concurrent generation runs for the same period and organisation, producing duplicate summaries and sending multiple push notifications to users — a serious UX regression.

Mitigation & Contingency

Mitigation: Implement a database-level run-lock using an INSERT … ON CONFLICT DO NOTHING pattern keyed on (organisation_id, period_type, period_start). Only the first successful insert proceeds; subsequent attempts read the existing lock and exit early. Test with concurrent invocations in a Deno test suite.

Contingency: If duplicate summaries are detected post-deployment, add a deduplication cleanup job that removes all but the most recent summary per (user_id, period_type, period_start) and sends a corrective push notification.

medium impact low prob integration

FCM and APNs have different payload structures and size limits. An oversized or malformed payload could cause silent notification drops on iOS or delivery failures on Android, meaning mentors never learn their summary is ready.

Mitigation & Contingency

Mitigation: Build the PushNotificationDispatcher with separate FCM and APNs payload constructors, enforce a 256-byte body limit on the preview text, and run integration tests against the Firebase Emulator and a test APNs sandbox.

Contingency: Fall back to a generic 'Your periodic summary is ready' message if personalised preview text construction fails, ensuring delivery even when the personalisation pipeline encounters an error.

medium impact high prob scope

Outlier thresholds that are too tight will flag most mentors as outliers (alert fatigue for coordinators), while thresholds that are too loose will miss genuinely underactive mentors — directly undermining HLF's follow-up goal.

Mitigation & Contingency

Mitigation: Implement thresholds as configurable per-organisation database settings rather than hardcoded constants. Provide sensible defaults (underactive < 2 sessions/period, overloaded > 20 sessions/period) and document the tuning process for coordinators in the admin portal.

Contingency: If coordinators report threshold miscalibration after launch, expose a threshold configuration UI in the coordinator admin screen and allow real-time threshold adjustment without requiring a code deployment.

low impact high prob scope

The app may not have 12 months of historical activity data for all organisations at launch, making year-over-year comparison impossible for most users and rendering the comparison widget empty, which could disappoint users expecting Wrapped-style insights.

Mitigation & Contingency

Mitigation: Design the generation service to gracefully handle missing prior-year data by setting the yoy_delta field to null rather than zero. The UI must treat null as 'no comparison available' with appropriate placeholder copy rather than showing a misleading 0% delta.

Contingency: If historical data import from legacy Excel/Word sources becomes feasible, add a one-time backfill Edge Function that populates prior-year activity records from imported spreadsheets. Until then, explicitly communicate the data-availability limitation in the first summary each user receives.