Implement Proxy Activity Repository
epic-coordinator-proxy-registration-bulk-orchestration-task-002 — Build the ProxyActivityRepository that handles all database operations for proxy activity records in Supabase. Implement insert, batch-insert, query-by-coordinator, query-by-mentor, and status-update operations. Define the ProxyActivity data model including attributed_to (mentor), registered_by (coordinator), activity details, and submission status fields. Ensure RLS policies enforce coordinator-only write access.
Acceptance Criteria
Technical Requirements
Implementation Notes
Define `abstract class ProxyActivityRepository` and `SupabaseProxyActivityRepository implements ProxyActivityRepository`. For batchInsertActivities, use Supabase's `.upsert(List
Map `ProxyActivityStatus` to/from Supabase string using a static `fromString()` factory. Use `eq('registered_by', coordinatorId)` and `order('activity_date', ascending: false)` in the query builder for getActivitiesByCoordinator. Define the Supabase table name as a constant: `static const _tableName = 'proxy_activities'`. This repository is a foundational dependency for the bulk registration orchestration layer — keep it thin and focused on data access only, with no business logic.
Testing Requirements
Unit tests mocking Supabase client for all operations. Test: (1) single insert maps response to ProxyActivity with correct field mapping, (2) batch insert of 3 items sends single upsert call with all 3 records, (3) batch insert of 51 items throws ArgumentError before Supabase call, (4) getActivitiesByCoordinator returns only records where registered_by matches, (5) getActivitiesByMentor returns only records where attributed_to matches, (6) updateStatus sends PATCH with only status field changed (verify payload), (7) Supabase PostgrestException mapped to RepositoryException with correct code, (8) role check blocks peer mentor from calling insert (throws UnauthorizedException). Minimum 10 test cases. Use flutter_test with Mockito-generated or manual mocks for the Supabase client.
Partial failures in bulk registration — where some mentors succeed and others fail — create a complex UX state that is easy to mishandle. If the UI does not clearly communicate which records succeeded and which failed, coordinators may re-submit already-saved records (creating duplicates) or miss failed records entirely (creating underreporting).
Mitigation & Contingency
Mitigation: Design the per-mentor result screen as a primary deliverable of this epic, not an afterthought. Use a clear list view with success/failure indicators per mentor name, and offer a 'Retry failed' action that pre-selects only the failed mentors for resubmission.
Contingency: If partial failure UX proves too complex to deliver within scope, implement a simpler all-or-nothing submission mode for the initial release with a clear error message listing which mentors failed, and defer the partial-retry UI to a follow-up sprint.
Submitting proxy records for a large group (e.g., 30+ mentors) as individual Supabase inserts may cause latency issues or hit rate limits, degrading the coordinator experience and potentially causing timeout failures that leave data in an inconsistent state.
Mitigation & Contingency
Mitigation: Implement the BulkRegistrationOrchestrator to batch inserts using a Supabase RPC call that accepts an array of proxy records, reducing round-trips to a single network call. Add progress indication using a stream of per-record results if the RPC supports it.
Contingency: If the RPC approach is blocked by Supabase limitations, fall back to chunked parallel inserts (5 records per batch) with retry logic, capping total submission time and surface a progress bar to manage coordinator expectations.
Unifying state management for both single and bulk proxy flows in a single BLoC risks state leakage between flows — for example, a previously selected mentor list persisting when a coordinator switches from bulk to single mode — causing confusing UI states or incorrect submissions.
Mitigation & Contingency
Mitigation: Define separate, named state subtrees within the BLoC for single-proxy state and bulk-proxy state, with explicit reset events triggered on flow entry. Write unit tests for state isolation scenarios using the bloc_test package.
Contingency: If unified BLoC state becomes unmanageable, split into two separate BLoCs (ProxySingleRegistrationBLoC and ProxyBulkRegistrationBLoC) sharing only common events via a parent coordinator Cubit.