Implement ProxyAuditLogger service in Dart
epic-coordinator-proxy-registration-foundation-task-006 — Implement the ProxyAuditLogger class as an infrastructure service that writes immutable audit records to the proxy_audit_log table after every proxy registration event. Expose methods: logCreated(), logBulkCreated(), logUpdated(). Called internally by ProxyActivityRepository after successful inserts. Include payload snapshot serialization of the activity data at time of registration for dispute resolution and NHF/HLF audit trail requirements.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 3 - 413 tasks
Can start after Tier 2 completes
Implementation Notes
Define a ProxyAuditLogEntry model with fields: id (uuid), proxy_activity_id (uuid), event_type (enum: created | bulk_created | updated), coordinator_id (uuid), attributed_mentor_id (uuid), timestamp (DateTime), payload_snapshot (Map
Register it via Riverpod provider so ProxyActivityRepository can receive it via constructor injection. The RLS policy is the authoritative immutability guarantee; the service layer simply never calls update/delete — do not add application-level guards that could create a false sense of security.
Testing Requirements
Unit tests (task-010) must verify: (1) logCreated produces exactly one audit row with event_type='created', (2) logBulkCreated produces one row per mentor with event_type='bulk_created', (3) logUpdated produces one row with event_type='updated', (4) payload_snapshot equals the full serialized activity at call time, (5) RLS blocks UPDATE and DELETE on audit table. Use flutter_test with a Supabase mock client for unit isolation. Integration tests against a real Supabase test project should confirm immutability at the database level.
Supabase RLS policies for org-scoped proxy access may be difficult to express correctly, especially for coordinators with multi-chapter access. An overly permissive policy could allow cross-org proxy registrations, corrupting Bufdir reporting; an overly restrictive policy could block legitimate coordinators from registering.
Mitigation & Contingency
Mitigation: Write integration tests covering all access boundary cases (same org, cross-org, multi-chapter coordinator) before merging any RLS migration. Use parameterised RLS test helpers already established by the auth feature.
Contingency: If RLS proves insufficient, add a server-side Edge Function validation layer that re-checks org membership before persisting any proxy record, providing defence in depth.
Adding new tables and foreign key constraints to an existing production Supabase database risks migration failures or locking issues if the database already contains active sessions during deployment.
Mitigation & Contingency
Mitigation: Use additive-only migrations (no DROP or ALTER on existing tables). Test full migration sequence in a staging Supabase project before production deployment. Schedule during low-traffic window.
Contingency: Maintain a rollback migration script. If the migration fails, the feature remains unreachable behind a feature flag while the schema issue is resolved.
Audit log entries must be immutable for compliance, but Supabase RLS by default allows row owners to update their own rows. If audit records are accidentally mutable, dispute resolution and accountability guarantees are invalidated.
Mitigation & Contingency
Mitigation: Configure the proxy_audit_log table with an RLS policy that allows INSERT for coordinators but denies UPDATE and DELETE for all roles including service_role, enforced at the database level.
Contingency: If RLS cannot fully prevent updates, create a database trigger that reverts any UPDATE to the audit table and logs the attempt as a security event.