high priority low complexity testing pending testing specialist Tier 4

Acceptance Criteria

fetchAssignmentHistory with NHF org ID returns empty list and never calls Supabase
fetchAssignmentHistory with HLF org ID returns empty list and never calls Supabase
fetchAssignmentHistory with Blindeforbundet org ID queries Supabase and returns List<AssignedContact>
fetchAssignmentHistory Blindeforbundet: result includes both open and closed assignments when no status filter is applied
fetchAssignmentsByStatus with AssignmentStatus.open: only open assignments returned; Supabase receives .eq('status', 'open')
fetchAssignmentsByStatus with AssignmentStatus.closed: only closed assignments returned
fetchOpenAssignments: returns same result as fetchAssignmentsByStatus(mentorId, AssignmentStatus.open)
Overdue flag test: assignment with due_date 5 days in the past → overdue_flag is true, days_remaining is negative
Not-overdue test: assignment with due_date 5 days in the future → overdue_flag is false, days_remaining is positive
Null due_date test: assignment with no deadline → overdue_flag is false, days_remaining is null
Integration test: PeerMentorRepository, CertificationRecordRepository, MentorActivityLogRepository, and AssignmentHistoryRepository instantiated with same mock SupabaseClient, called via Future.wait([...]) with non-conflicting queries, all resolve without error
Integration test asserts no cross-contamination: each repository's mock interactions are independent and do not interfere with sibling repository calls
Test files: test/repositories/assignment_history_repository_test.dart and test/repositories/data_layer_integration_test.dart

Technical Requirements

frameworks
Flutter
Dart
flutter_test
mockito (or mocktail)
apis
Mocked Supabase PostgREST builder chain — assignment_records table
Mock SupabaseClient shared across all four repositories for integration test
data models
AssignedContact
AssignmentStatus enum
OrgIds constants
PeerMentorProfile
CertificationRecord
ActivityLogEntry
performance requirements
Integration test using Future.wait must complete within 3 seconds with mocked clients
All unit tests complete in under 5 seconds total
security requirements
Integration test must use mocked clients only — no live Supabase connections
NHF/HLF short-circuit tests confirmed via verifyNever to prevent accidental data access

Execution Context

Execution Tier
Tier 4

Tier 4 - 323 tasks

Can start after Tier 3 completes

Implementation Notes

The integration test is not a true end-to-end test — it is a structural test confirming the repositories can coexist and share a client without stateful collisions (e.g., no global variables, no singleton misuse). The primary risk this test guards against is a developer accidentally using a module-level Supabase singleton instead of injected dependencies. For the overdue flag determinism, create a simple ClockProvider interface with a realNow implementation and a testNow(DateTime fixed) implementation, and inject it into the mapper. The integration test's Future.wait() pattern mirrors how the BLoC or Riverpod provider will actually call these repositories in production — so if the test passes, the production parallel-fetch pattern is validated by design.

Testing Requirements

Unit tests in assignment_history_repository_test.dart using flutter_test and mockito/mocktail. Inject a fixed Clock/DateTime for overdue flag tests so results are deterministic regardless of when CI runs. For the integration test in data_layer_integration_test.dart: create a single shared MockSupabaseClient, instantiate all four repositories with it, define separate when() stubs for each repository's query (using argument matchers that distinguish between table names), call all four via Future.wait(), and assert each resolved to its expected type. Verify that each repository's stub was called exactly once and no other repository's stub was called more than expected.

Group tests using Dart's group() for readability.

Component
Assignment History Repository
data low
Epic Risks (3)
high impact medium prob security

Supabase RLS policies for peer mentor data may block coordinator queries if the RLS rules are written for peer-mentor-self access only, requiring policy updates that affect other features sharing the same tables.

Mitigation & Contingency

Mitigation: Review existing RLS policies on peer_mentors, certification_records, and activity_log tables before writing repository queries. Coordinate with the database team to add coordinator-role predicates without weakening existing mentor-self policies.

Contingency: If policy changes are blocked, implement a Supabase Edge Function as a secure query proxy that enforces authorization server-side, avoiding direct RLS policy modification.

medium impact medium prob technical

The activity log table schema may not have a mentor_id foreign key column or may require a JOIN through an intermediate table, making the aggregation query significantly more complex than anticipated.

Mitigation & Contingency

Mitigation: Inspect the actual Supabase activity_log table schema before starting the MentorActivityLogRepository implementation. Document the exact JOIN path needed and validate it returns correct results for a known mentor.

Contingency: If schema requires complex multi-table aggregation, implement a Supabase database function (RPC) and expose it via the repository's fetchSummary method to keep Dart code clean.

high impact low prob dependency

The Blindeforbundet assignment table may not yet exist in the shared Supabase schema or may have a different structure than assumed, blocking the AssignmentHistoryRepository implementation.

Mitigation & Contingency

Mitigation: Verify the assignments table exists and confirm its column structure with the Contact Detail & Edit Screen team which also depends on assignment data (assignment-repository in that feature).

Contingency: If the assignments table is not yet available, implement the AssignmentHistoryRepository with a stub returning empty list and a TODO marker, unblocking the aggregation service while the schema is finalized.