Integration test: data layer end-to-end
epic-assignment-follow-up-reminders-foundation-task-012 — Write an integration test that exercises all four repository/service components against a local Supabase instance or staging environment. Scenario: configure reminder thresholds for an org, create an assignment with a past last_contact_date, fetch overdue assignments, insert a notification record, mark it read, and dispatch a push notification. Verify RLS prevents cross-org data leakage throughout the flow.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 3 - 413 tasks
Can start after Tier 2 completes
Implementation Notes
Structure the test using a TestFixtureManager helper class that creates and tracks all inserted rows, then deletes them in reverse insertion order during teardown. This prevents orphaned records from accumulating across failed test runs. For RLS validation, create two SupabaseClient instances authenticated as user-A and user-B respectively, then run cross-org queries and assert empty results. Do not rely on Supabase throwing errors for RLS rejection — it returns empty sets silently.
The integration test is the authoritative proof that RLS policies are correctly configured; if unit tests pass but integration tests fail on RLS assertions, the database migration is incorrect. Coordinate with the database migration task to ensure the test database schema matches production. Run this test suite as a mandatory gate in the CI/CD pipeline before merging to main.
Testing Requirements
Integration test using real Supabase connection (local docker-based instance preferred; staging acceptable). Use Supabase's service role client exclusively for fixture setup/teardown (bypasses RLS intentionally for test data management). Use org-scoped user clients for the actual test scenario assertions to exercise RLS. Tag the test file with @Tags(['integration']) so it is excluded from CI unit test runs and only executed in a dedicated integration test step.
Document the required environment variables (SUPABASE_TEST_URL, SUPABASE_TEST_ANON_KEY, SUPABASE_TEST_SERVICE_ROLE_KEY) in the test file header. The PushNotificationService must use its mock implementation in this test (real FCM dispatch is not needed for data layer validation).
Adding last_contact_date to the assignments table may conflict with existing RLS policies or trigger-based logic that monitors the assignments table. If the migration is not carefully reviewed, existing assignment management features could break in production.
Mitigation & Contingency
Mitigation: Review all existing triggers, policies, and foreign key constraints on the assignments table before writing the migration. Run the migration against a staging Supabase instance with production-like data and execute the full existing test suite before merging.
Contingency: Roll back the migration using Supabase's versioned migration history. Apply the schema change as an additive-only migration (nullable column with default) to ensure zero downtime and reversibility.
The PushNotificationService wraps an existing FCM integration whose internal API contract may have changed or may not expose the payload formatting required for deep-link CTAs. Misalignment discovered late delays the dispatch service epic.
Mitigation & Contingency
Mitigation: Before implementing the wrapper, read the existing push notification integration code and confirm the method signatures, payload structure, and token management model. Agree on a stable interface contract in a shared Dart abstract class.
Contingency: If the existing service is incompatible, implement a thin adapter layer that translates reminder payloads to the existing service's format, isolating the reminder feature from upstream changes.
Incorrect RLS policies on notification_log could allow coordinators to read reminder records belonging to peer mentors in other chapters, exposing sensitive assignment information across organisational boundaries.
Mitigation & Contingency
Mitigation: Write explicit RLS policies with integration tests that assert cross-chapter queries return zero rows. Use Supabase's built-in auth.uid() and join through the org membership tables to scope all queries.
Contingency: If a policy gap is discovered post-merge, immediately disable the affected table's SELECT policy, deploy a corrected policy, and audit recent queries in Supabase logs for any cross-boundary reads.