medium priority low complexity infrastructure pending infrastructure specialist Tier 0

Acceptance Criteria

ProxyAuditLogger class is implemented as a singleton-accessible service injectable via Riverpod provider
All four event types are logged: entry_created, submission_success, submission_partial_failure, submission_full_failure
Each log record contains: event_type, coordinator_id, mentor_ids (array), activity_date, timestamp (UTC), error_details (nullable JSON), and batch_size
Audit writes use unawaited async calls so they never delay the main submission flow
Supabase insert errors in the audit logger are caught silently and reported to an error monitoring sink without re-throwing
Audit table 'proxy_audit_log' exists in Supabase with appropriate RLS policies (insert-only for app service role, select for admin role)
Log entries are retained for a minimum of 12 months per GDPR audit trail requirements
Logger exposes a typed Dart API: logEntryCreated(), logSuccess(), logPartialFailure(), logFullFailure()
Unit tests confirm that a Supabase failure in the logger does not throw or propagate to the caller

Technical Requirements

frameworks
Flutter
Riverpod
apis
Supabase REST API (insert to proxy_audit_log table)
data models
ProxyAuditLogEntry
ProxyRegistrationEvent
performance requirements
Audit write must be fire-and-forget — zero added latency to submission path
Insert must complete within 2 seconds under normal network conditions (not on critical path)
security requirements
RLS: insert-only for authenticated app users, select restricted to admin service role
coordinator_id and mentor_ids must be validated UUIDs before insert to prevent injection
error_details field must strip any PII before persisting — log error codes/types only
Audit log rows must be immutable — no update or delete RLS policies

Execution Context

Execution Tier
Tier 0

Tier 0 - 440 tasks

Implementation Notes

Use `unawaited()` from `dart:async` explicitly rather than omitting `await` silently — this makes the fire-and-forget intent clear and avoids linter warnings. Define a sealed `ProxyAuditEvent` class hierarchy so each event type carries only the fields it needs. Keep the logger completely stateless: it receives all context as parameters. Supabase RLS policies should be defined in a migration file, not applied manually.

Avoid logging full mentor profile data — only IDs. Consider a local in-memory queue with a background flush if offline resilience becomes a requirement in a later phase.

Testing Requirements

Unit tests using flutter_test with a mocked Supabase client. Test all four log method signatures produce correct payload shapes. Test that a thrown exception in the Supabase client is swallowed and does not propagate. Test that unawaited calls do not block the calling function.

Integration test (TestFlight build) verifying rows appear in proxy_audit_log after a real submission flow.

Component
Proxy Audit Logger
infrastructure low
Epic Risks (3)
high impact high prob scope

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.

medium impact medium prob technical

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.

medium impact medium prob technical

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.