high priority high complexity testing pending testing specialist Tier 6

Acceptance Criteria

All integration tests run against a Supabase local emulator or a dedicated test schema — never against the production database
Seed data includes: (a) 3 active mentors with expired certifications, (b) 1 active mentor with a valid certification, (c) 1 already-paused mentor with an expired certification, (d) 2 coordinators each responsible for a subset of mentors
Test asserts that after job execution exactly 3 mentors transition to 'paused' status and the valid-cert mentor remains 'active'
Test asserts that peer_mentor_status_history contains exactly 3 new rows with correct fields: reason='certification_expired', job_run_id present, certification_expiry_date correct
Test asserts that the already-paused mentor has no new history row and no duplicate notification
Test asserts that exactly 2 coordinator notifications are dispatched (one per coordinator) with correct mentor groupings
Test simulates an RPC failure for one mentor (mock or trigger a constraint violation) and asserts: the other 2 mentors are still paused, error_count === 1, and the failed mentor_id appears in mentor_ids_errored in the job log
Test validates the final job log JSON against the schema: { job_run_id: string, processed_count: number, paused_count: number, skipped_count: number, error_count: number, notifications_dispatched_count: number, mentor_ids_paused: string[], mentor_ids_errored: string[] }
Tests are deterministic and do not depend on system clock — use a fixed reference date passed to the job as a parameter
Test suite completes in under 60 seconds including database seeding and teardown

Technical Requirements

frameworks
Supabase PostgreSQL 15
Supabase Edge Functions (Deno)
apis
Supabase local emulator CLI
update_mentor_status PostgreSQL RPC
data models
certification
assignment
activity
performance requirements
Test database must be reset to a clean state between test cases using transactions or truncate scripts
Seed scripts must run in under 5 seconds to keep the full suite under 60 seconds
security requirements
Test credentials (service-role key for local emulator) must be stored in .env.test and excluded from version control
Test data must not include real personnummer or real mentor PII — use synthetic data only

Execution Context

Execution Tier
Tier 6

Tier 6 - 158 tasks

Can start after Tier 5 completes

Implementation Notes

Structure the test file as a single Deno test suite with named sub-tests for each scenario. Extract the seed data setup into a shared helper (seedHlfMentors(db, overrides)) so each test can vary only the fields relevant to that scenario. For the RPC failure simulation, create a trigger or a wrapper function in the test schema that raises an exception when the mentor_id matches a sentinel UUID — this avoids needing to mock at the Deno layer and tests the real RPC path. Use a fixed reference date (e.g.

'2026-03-29') as the job's 'today' parameter in all tests to eliminate date-dependency flakiness. Capture stdout from the job run and parse the final JSON log line to assert schema compliance — do not rely on database state alone for the log assertions.

Testing Requirements

Integration tests using Deno test runner against supabase local (supabase start). Each test case seeds its own data in a beforeEach hook and tears down in afterEach using DELETE or ROLLBACK. Test coverage must reach 100% of the job's branching paths: happy path, skip-already-paused, per-record RPC failure, zero-eligible-mentors (no-op). Notification dispatch is tested by injecting a spy/stub for CoordinatorNotificationService that records calls without making real FCM requests.

Final job log schema is validated using a JSON schema validator (e.g. ajv or zod) to catch structural regressions. All tests must be runnable with `deno test --allow-env --allow-net` against the local emulator.

Component
Certification Expiry Auto-Pause Job
infrastructure medium
Epic Risks (3)
medium impact low prob technical

The status state machine must handle race conditions where two concurrent callers (e.g., a mentor self-pausing and a coordinator force-pausing simultaneously) attempt to update the same mentor's status. Without a concurrency guard, both writes could succeed, leaving the audit log in an inconsistent state.

Mitigation & Contingency

Mitigation: Use a Supabase RPC with a row-level lock (SELECT FOR UPDATE) inside a transaction so only one transition wins. Return a clear error to the losing caller. Test with concurrent requests in the integration test suite.

Contingency: If row-level locking proves unreliable in the Supabase environment, add an optimistic-locking version field to peer_mentors and have the service retry up to three times on version conflict before surfacing an error to the caller.

high impact medium prob technical

If the CertificationExpiryJob Edge Function fails silently (network timeout, Supabase cold start), HLF mentors with expired certifications could remain in active status and continue appearing on the chapter website, creating a compliance breach.

Mitigation & Contingency

Mitigation: Implement structured error logging inside the Edge Function, write a monitoring query that checks for mentors with expired certifications still in active status, and set up an alert if any are detected 30 minutes after the scheduled nightly run.

Contingency: Provide a coordinator-accessible manual trigger for the expiry check that can be invoked via the admin interface if the scheduled job is known to have failed. Document the manual recovery procedure for HLF coordinators.

medium impact medium prob dependency

pg_cron registration in Supabase requires superuser-level access that may not be available in all environments (local dev, staging, CI). If the cron job cannot be registered automatically, the Edge Function will never execute on schedule, breaking the HLF certification expiry workflow.

Mitigation & Contingency

Mitigation: Use Supabase's recommended pg_cron setup via the SQL editor migration script and document the exact commands. Validate cron registration in the staging environment as part of the epic's deployment checklist.

Contingency: If pg_cron is unavailable, switch to a Supabase scheduled Edge Function invocation via an external cron service (e.g., a GitHub Actions scheduled workflow calling the Edge Function endpoint with a service-role key) until the pg_cron approach is resolved.