Implement AssignmentHistoryRepository with Blindeforbundet org branching
epic-peer-mentor-detail-screen-data-layer-task-008 — Implement fetchAssignmentHistory(String mentorId, String organizationId) in AssignmentHistoryRepository. The method MUST return an empty list (not null) for NHF and HLF organizations since assignment tracking is specific to Blindeforbundet. For Blindeforbundet, query the assignment_records table and map results to List<AssignedContact> including open/closed status, assignment date, and deadline metadata. The empty-list return for non-Blindeforbundet orgs is a deliberate multi-tenant data isolation decision.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 1 - 540 tasks
Can start after Tier 0 completes
Implementation Notes
The org-branching is architecturally significant: it represents a deliberate multi-tenant data isolation contract. Document this with a /// doc comment on the method explaining why NHF/HLF return empty. Use a centralized OrgIds constant class (e.g., in constants.dart) so the branching condition is maintainable — if a new org is added, the constant class is the single change point. Compute days_remaining and the overdue flag inside the AssignedContact.fromJson factory or a dedicated mapper function, not inside the repository method, to keep the repository thin.
The AssignedContact model should be immutable (all final fields, const constructor where possible).
Testing Requirements
Unit tests with flutter_test and mockito. Test cases: (1) NHF organizationId → returns empty list, Supabase client never called; (2) HLF organizationId → returns empty list, Supabase client never called; (3) Blindeforbundet organizationId → Supabase is queried and results mapped to List
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.
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.
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.