high priority high complexity testing pending testing specialist Tier 5

Acceptance Criteria

All integration tests pass against a Supabase local development instance with seeded test data
Test suite covers the happy path: trigger scheduler → aggregation runs → summary persisted → notification dispatched → idempotency check blocks second run
Test: organisation A's summary generation does not read, write, or affect organisation B's data (isolation test with two seeded orgs)
Test: year-over-year delta is computed correctly when prior year's summary exists in the database
Test: year-over-year delta returns null/zero gracefully when no prior year summary exists (first-run scenario)
Test: idempotency — triggering the pipeline twice for the same org+period results in exactly one summary record and one scheduler_run record
Test: partial failure isolation — if notification dispatch fails for one mentor, the summary is still persisted and other mentors' notifications are still sent
Test: outlier detection uses org-specific threshold when configured and falls back to global default when not
Test: peer mentor with zero activities in the period is classified as underactive and receives appropriate summary content
Test: peer mentor with activities exceeding overload threshold is classified as overloaded
Test suite execution time is under 3 minutes for the full suite against a local Supabase instance
All tests are deterministic: no reliance on wall clock time; use injected date parameters

Technical Requirements

frameworks
flutter_test
Supabase local development CLI
Deno test (for Edge Function tests)
apis
Supabase local instance PostgREST API
summary_periods table
scheduler_runs table
activities table (seeded test data)
organisations table (seeded test data)
data models
Organisation
PeerMentor
Activity
SummaryPeriod
SchedulerRun
OutlierThreshold
performance requirements
Full integration test suite completes in under 3 minutes
Each individual test case completes in under 30 seconds
Test data seeding must complete in under 5 seconds
security requirements
Test environment must use a separate Supabase project or local instance — never run integration tests against production
Test data must not include real user PII — use generated names and synthetic data only
Service role key for tests stored in `.env.test` file excluded from version control

Execution Context

Execution Tier
Tier 5

Tier 5 - 253 tasks

Can start after Tier 4 completes

Implementation Notes

Structure the test suite as a `test/integration/summary_pipeline/` directory with one file per concern (e.g. `idempotency_test.dart`, `organisation_isolation_test.dart`, `outlier_classification_test.dart`). Create a shared `SummaryPipelineTestFixture` class with `setUp()` / `tearDown()` methods that seed and clean the local Supabase instance. For date injection, add a `clock` parameter to all date-sensitive functions (see the `clock` package pattern in Dart).

The year-over-year delta test requires seeding two periods of data: seed H1 2024 completed summary, then trigger H1 2025 generation and assert the delta field is populated. For organisation isolation, run two orgs simultaneously using `Future.wait` and verify via direct DB queries that each org's records are correctly separated. Document the `supabase start` and seed commands in a `Makefile` target `make test-integration` for CI reproducibility.

Testing Requirements

Integration tests written in Deno test (for Edge Function pipeline) and flutter_test (for Dart-side service layer). Use a `TestDataSeeder` helper class that inserts deterministic activity records, org configs, and peer mentor profiles before each test and cleans up after. Group tests into describe blocks: `PipelineHappyPath`, `IdempotencyGuard`, `OrganisationIsolation`, `OutlierClassification`, `YearOverYearDelta`, `NotificationDispatch`, `FailureIsolation`. Use dependency injection to pass a mock date into period boundary detection — do not rely on `DateTime.now()`.

Use Supabase local dev (`supabase start`) as the test database — document setup steps in the test README. Assert DB state directly via SQL after each test rather than only asserting return values.

Component
Summary Generation Service
service high
Dependencies (5)
Add idempotency control to the summary generation service so that re-triggered runs for an already-completed period are safely detected and skipped. Must use the summary period repository to check for existing completed run records and return cached results without re-executing the generation pipeline. epic-periodic-summaries-core-logic-task-009 Implement configurable threshold management within the outlier detection service, allowing per-organisation and global default thresholds for underactivity and overload classification. Thresholds must be storable in the database and resolvable at runtime with sensible defaults if no org-specific config exists. epic-periodic-summaries-core-logic-task-010 Extend the push notification dispatcher with summary-specific payload construction logic. Must build personalised notification bodies referencing the peer mentor's name, the period label, key metric highlights, and deep-link URIs routing directly to the periodic summary card within the app. epic-periodic-summaries-core-logic-task-012 Implement the central orchestration service that drives an organisation-scoped summary generation run: fetches aggregated activity data, computes metrics and year-over-year deltas, invokes the outlier detection service, persists results via the summary period and cache repositories, and triggers push notifications upon completion. epic-periodic-summaries-core-logic-task-008 Create the Supabase Edge Function that acts as the cron-triggered scheduler for summary generation. Must detect half-year (June 30, December 31) and quarterly period boundaries, invoke the summary generation service per active organisation, handle multi-organisation fan-out, and log scheduler run metadata including status and duration. epic-periodic-summaries-core-logic-task-011
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.