Implement MentorActivityLogRepository mentor-scoped raw log queries
epic-peer-mentor-detail-screen-data-layer-task-007 — Implement fetchActivityLogs(String mentorId, {DateRange? range, int? limit}) in MentorActivityLogRepository for retrieving paginated raw activity log entries scoped to a specific mentor. This supports detail drill-down in the UI beyond summary statistics. Results must be ordered by activity date descending, support cursor-based pagination, and map to a typed list of activity log model objects.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 2 - 518 tasks
Can start after Tier 1 completes
Implementation Notes
Build on top of the abstract interface defined in task-006 — do not duplicate the interface declaration. Use Dart's named optional parameters with defaults (limit defaults to 20, range defaults to null meaning no date filter). For cursor pagination, use keyset pagination on activity_date combined with the row id as a tiebreaker to avoid skipping rows with identical timestamps. Return a value object (e.g., ActivityLogPage) that bundles List
nextCursor rather than returning a bare list, so the UI layer can detect end-of-data. Keep fromJson factory constructors on ActivityLogEntry; do not put mapping logic inside the repository method itself.
Testing Requirements
Unit tests using flutter_test and mockito (or mocktail). Mock the Supabase client at the PostgREST builder level. Test cases: (1) successful fetch returns correctly typed list in descending date order; (2) DateRange filter passes correct gte/lte parameters; (3) limit parameter is forwarded; (4) empty result set returns empty list, not null; (5) cursor value matches last entry's activity_date; (6) PostgrestException is rethrown as ActivityLogFetchException; (7) null/empty mentorId throws ArgumentError before any network call. Aim for 100% branch coverage on the repository method.
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.