critical priority low complexity backend pending backend specialist Tier 2

Acceptance Criteria

updateMentorStatus(String mentorId, MentorStatus status, {DateTime? expectedReturnDate}) is an async method returning Future<PeerMentorProfile>
Method issues a Supabase UPDATE on peer_mentors filtering by id, setting status and (if provided) expected_return_date
When status is MentorStatus.active, expected_return_date is explicitly set to null in the update payload to clear any previously set return date
When status is MentorStatus.paused and expectedReturnDate is non-null, expected_return_date is written as an ISO-8601 string
When status is MentorStatus.paused and expectedReturnDate is null, the update proceeds without setting expected_return_date (field left unchanged)
Method returns the updated PeerMentorProfile by chaining .select().single() on the UPDATE query — no second SELECT call required
Throws MentorNotFoundException if the update affects 0 rows (mentorId does not exist or RLS blocked the update)
Throws RepositoryException for unexpected Supabase errors
Method does NOT perform coordinator notification — that responsibility belongs to a higher-level service or BLoC
Unit tests pass for: pause with return date, pause without return date, activate (clears return date), not-found error, and generic error

Technical Requirements

frameworks
Flutter
Riverpod
Dart
apis
Supabase PostgREST — peer_mentors table UPDATE by id with .select().single()
data models
PeerMentorProfile
MentorStatus (enum)
performance requirements
Single UPDATE + SELECT in one round-trip using Supabase's update().select().single() chain
Do not issue a separate fetchPeerMentorProfile after the update — use the returned row directly
security requirements
Only coordinators and org admins should be able to update mentor status — enforce this via Supabase RLS, not client-side role checks
Log the status transition (mentorId, old status not known client-side, new status) at debug level for audit trail support without logging PII

Execution Context

Execution Tier
Tier 2

Tier 2 - 518 tasks

Can start after Tier 1 completes

Implementation Notes

Build the update payload map dynamically: start with {'status': status.name}, then conditionally add expected_return_date. When activating, always include 'expected_return_date': null explicitly so the field is cleared — omitting it would leave the old value in place. The Supabase Dart client's .update(payload).eq('id', mentorId).select().single() pattern returns the updated row. If the project's Supabase client version does not support chaining .select() on update, issue a follow-up .from('peer_mentors').select().eq('id', mentorId).single() call but document this as a two-round-trip workaround.

Optimistic update support means the BLoC layer can update local state immediately; the repository method is the confirmation/rollback source — do not implement optimistic logic inside the repository itself.

Testing Requirements

Unit tests using flutter_test with mocked SupabaseClient. Test file: test/features/peer_mentor/data/repositories/peer_mentor_repository_status_test.dart (or append to existing repository test file). Required cases: (1) pause with expectedReturnDate sets both status and expected_return_date in payload, (2) pause without expectedReturnDate sets only status, (3) activate sets status=active and expected_return_date=null in payload, (4) throws MentorNotFoundException when update returns empty list, (5) throws RepositoryException for PostgrestException. Verify the exact update payload map passed to Supabase using argument captors.

Component
Peer Mentor 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.