high priority high complexity testing pending testing specialist Tier 6

Acceptance Criteria

Integration tests run against a dedicated Supabase test project (separate from production) and clean up all created records in tearDown()
Test: full happy path — registerProxyActivity succeeds → query the activities table directly and assert recorded_by_user_id == coordinatorA_id AND peer_mentor_id == mentorX_id
Test: coordinator audit query (RLS-filtered SELECT by coordinator) returns only records where recorded_by_user_id == coordinatorA_id, not records recorded by coordinatorB for the same mentor
Test: peer mentor statistics query aggregates all activities for peer_mentor_id == mentorX_id regardless of which coordinator recorded them — verifies that aggregate counts are by mentee, not by recorder
Test: duplicate detection with real database — insert a seed activity record for (mentorX, activity_type_A, date_1), then call registerProxyActivity with the same triple-key → receives DuplicateWarning before any new record is inserted
Test: NHF multi-coordinator duplicate scenario — coordinatorA records activity for mentorX, coordinatorB (same chapter) attempts the same activity → duplicate warning includes originalRecordedByCoordinatorId == coordinatorA_id
Test: permission denied scenario — coordinatorA attempts to register for mentorY who is NOT in coordinatorA's scope → returns PermissionDenied and no record is inserted (verified by direct DB count query)
Test: persistence error handling — simulate by attempting to insert a record that violates a NOT NULL constraint → ProxyRegistrationResult.persistenceError is returned
All tests use isolated seed data with unique UUIDs to avoid cross-test pollution
tearDown() deletes all records created during the test using the test Supabase service role key
Tests are tagged with @Tags(['integration']) and excluded from standard unit test runs via test configuration

Technical Requirements

frameworks
Flutter
Dart
flutter_test
supabase_flutter (test project credentials via .env or test config)
apis
Supabase REST API (test project)
Supabase Auth (test user sessions for coordinatorA and coordinatorB)
Supabase service role API (for tearDown cleanup bypassing RLS)
data models
ActivityRecord
CoordinatorScopeRecord
PeerMentorStats
ProxyRegistrationResult
MentorDuplicateWarning
performance requirements
Each integration test completes within 10 seconds including Supabase round-trips
Tests must not leave orphaned records — tearDown must succeed even if the test assertion fails (use addTearDown() in flutter_test)
security requirements
Test project credentials stored in environment variables or a .env.test file — never hardcoded in test source files
.env.test must be in .gitignore
Use the Supabase service role key only in tearDown cleanup — test assertions must use regular user sessions to validate RLS behaviour
Test coordinator sessions must be created with limited-scope JWTs matching real role assignments, not service role tokens

Execution Context

Execution Tier
Tier 6

Tier 6 - 158 tasks

Can start after Tier 5 completes

Implementation Notes

Integration test setup is the hardest part of this task. Plan for: (1) a test fixtures file (test/integration/fixtures.dart) with factory functions for creating test users and scope assignments in Supabase; (2) a TestSupabaseClient wrapper that automatically uses the test project URL/key from environment; (3) a cleanup utility that uses the service role key to hard-delete all test data by a test run ID tag. For the NHF multi-coordinator scenario, create two coordinator users in the test project assigned to the same chapter, create a scope entry linking coordinatorB to mentorX, then have coordinatorA create an activity — then have coordinatorB attempt the same. The key assertion is that warning.originalRecordedByCoordinatorId returns coordinatorA's UUID.

For the statistics aggregation test, use a raw Supabase RPC call or a SELECT with GROUP BY peer_mentor_id to simulate how the app's stats screen would query — verifying the data model supports this query pattern is the core value of this test.

Testing Requirements

Use flutter_test with the real supabase_flutter client pointed at a dedicated test Supabase project. Integration test file should be in test/integration/ directory separate from unit tests. Use setUpAll() to create test users (coordinatorA, coordinatorB, mentorX, mentorY) and their scope assignments. Use addTearDown(cleanupFn) for each test to ensure cleanup runs even on failure.

For the RLS audit query test, sign in as coordinatorA and verify that a Supabase SELECT on the activities table with no additional filters only returns records where recorded_by_user_id == coordinatorA_id (RLS enforces this). For the peer mentor statistics test, insert two records for mentorX with different coordinators and verify the aggregate count is 2. Run integration tests in CI with a dedicated test Supabase project credential set.

Component
Proxy Registration Service
service medium
Epic Risks (2)
high impact low prob security

The Proxy Registration Service must verify that the coordinator has a legitimate assignment relationship with the target peer mentor before creating a record. If this check is implemented only in application code and not enforced at the DB/RLS level, a compromised or buggy client could bypass it by calling the Supabase endpoint directly, creating fraudulent proxy records for arbitrary peer mentors.

Mitigation & Contingency

Mitigation: Implement permission validation at two levels: (1) application-layer check in Proxy Registration Service that queries the assignments table before constructing the payload, and (2) RLS policy on the activities table that restricts INSERT to rows where recorded_by_user_id matches the authenticated user AND peer_mentor_id is in the set of peer mentors assigned to that coordinator. The RLS policy is the authoritative guard; the service-layer check provides early user-facing feedback.

Contingency: If RLS policy implementation is blocked by Supabase plan constraints, implement a Supabase Edge Function as a proxy endpoint that enforces the permission check server-side before forwarding to the DB. Disable direct client inserts entirely for proxy activities.

medium impact medium prob technical

For a bulk session with 30 selected peer mentors, the Proxy Duplicate Detector must query existing activities for each mentor. If implemented as 30 sequential Supabase queries, round-trip latency could make the bulk confirmation screen feel slow (>3s), degrading coordinator experience and potentially causing timeouts.

Mitigation & Contingency

Mitigation: Implement the duplicate check as a single Supabase query using an IN clause on peer_mentor_id combined with the activity_type and date filters, returning all potential duplicates for the entire batch in one network round-trip. Group results client-side by mentor ID to produce the per-mentor warning structure.

Contingency: If the single-query approach returns too much data for very large chapters, add a database index on (peer_mentor_id, activity_type, date) and profile query time. If still insufficient, accept a short loading state on the confirmation screen with a progress indicator rather than pre-loading duplicates before navigation.