high priority medium complexity testing pending testing specialist Tier 4

Acceptance Criteria

Test: inserting a ProxyActivityRecord with both coordinator_id and attributed_mentor_id persists both fields correctly and independently (values do not overwrite each other)
Test: attempting to insert a record with null coordinator_id throws a validation error or is rejected by the database constraint before reaching Supabase
Test: attempting to insert a record with null attributed_mentor_id throws a validation error or is rejected
Test: RLS — a coordinator from org A cannot read, update, or delete proxy_activity records belonging to org B (simulated via two different authenticated JWT sessions)
Test: bulk insert of N mentors results in exactly N rows in proxy_activity with distinct attributed_mentor_id values and the same coordinator_id
Test: after each successful single insert, ProxyAuditLogger.logCreated is called exactly once (verified via mock/spy)
Test: after a successful bulk insert of N mentors, ProxyAuditLogger.logBulkCreated is called once with a list of N records
Test: failed insert (e.g., DB constraint violation) does NOT produce an audit log entry
All tests pass with flutter_test runner (`flutter test`) without requiring a live Supabase project
Test file is organized with descriptive group() and test() labels following flutter_test conventions

Technical Requirements

frameworks
Flutter
Dart
flutter_test
apis
Supabase PostgREST (mocked)
ProxyAuditLogger (mocked via interface)
data models
ProxyActivityRecord
ProxyAuditLogEntry
proxy_activity (Supabase table schema)
performance requirements
Full test suite must complete in under 30 seconds
No tests should make real network calls — all Supabase interactions must be mocked
security requirements
RLS tests must simulate different org JWTs — use separate mock Supabase client instances with different auth contexts
Do not embed real Supabase credentials or API keys in test files

Execution Context

Execution Tier
Tier 4

Tier 4 - 323 tasks

Can start after Tier 3 completes

Implementation Notes

Define an abstract IProxyAuditLogger interface so ProxyActivityRepository depends on the interface, not the concrete class — this enables clean mocking via mocktail's Mock. For RLS tests, the cleanest approach without a live DB is to mock the Supabase client to return a 403/RLS-violation error when the org filter doesn't match, then assert the repository throws the expected exception. Alternatively, use a Supabase local dev instance (via Docker) if the team has this set up. Document in a comment which tests require a live Supabase project vs.

which are fully mocked. Prioritize fully mocked tests for CI reliability. The audit-log-not-written-on-failure test is the most important edge case: wrap the Supabase insert in a try/catch in ProxyActivityRepository and only call the logger in the success path.

Testing Requirements

Use flutter_test. Mock the Supabase client using a mock class implementing the SupabaseClient interface (or use a package like mocktail). Mock ProxyAuditLogger via an interface so call counts can be asserted. Group tests into: (1) single insert - attribution fields, (2) single insert - validation rejections, (3) bulk insert - correctness, (4) RLS cross-org isolation, (5) audit log integration (verifying logger is called correctly).

Use setUp/tearDown to reset mock state between tests. Add a test for the case where Supabase throws a network error mid-insert to confirm no audit entry is written.

Component
Proxy Activity Repository
data medium
Epic Risks (3)
high impact medium prob security

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.

medium impact low prob technical

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.

high impact medium prob security

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.