Apply and verify RLS policies for mileage adapter
epic-mileage-reimbursement-entry-infrastructure-task-003 — Configure and verify Supabase Row Level Security policies on mileage_claims and org_configuration tables. Ensure peer mentors can only access their own claims, coordinators can access claims within their chapter scope, and all policies are enforced at the database level.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 2 - 518 tasks
Can start after Tier 1 completes
Implementation Notes
The coordinator chapter-scope policy is the most complex. The recommended pattern is: EXISTS (SELECT 1 FROM organization_members WHERE user_id = auth.uid() AND organization_id = mileage_claims.organization_id AND role IN ('coordinator', 'admin')). Ensure organization_members is also RLS-protected to prevent policy bypass via a subquery. Use Supabase's auth.jwt() → 'app_metadata' → 'role' claim as an alternative if org membership is embedded in the JWT at login time — this avoids the subquery entirely and is faster.
Test both approaches and choose based on how roles are currently issued in the project's auth flow. Avoid using SECURITY DEFINER functions in RLS policies unless absolutely necessary — they are harder to audit.
Testing Requirements
Write verification tests using the Supabase JS client or psql with explicit role switching (SET LOCAL ROLE). Cover all policy scenarios listed in acceptance criteria. For Flutter integration tests, use ProviderContainer with a real Supabase test instance and two separate test user accounts (one peer_mentor, one coordinator in the same org, one coordinator in a different org). Assert that cross-org and cross-user queries return empty lists, not exceptions.
Document the test matrix in a Markdown table committed alongside the migration file.
Supabase Row Level Security policies for mileage_claims may require complex join conditions to distinguish peer mentor (own claims only) from coordinator (chapter-scoped claims) access. If the RLS policy is misconfigured, coordinators could see claims outside their chapter scope or peer mentors could read other users' data, causing a data privacy incident.
Mitigation & Contingency
Mitigation: Write RLS policy SQL as part of this epic with explicit test cases for each role. Use Supabase's built-in policy testing tools and add integration tests that assert cross-user data isolation before merging.
Contingency: If RLS configuration proves too complex to test reliably within the epic, add an application-layer guard in the adapter that filters query results by authenticated user ID as a defence-in-depth measure while the policy is corrected.
Norwegian tax authority reimbursement rounding rules may change or may not be publicly documented in machine-readable form. Using the wrong rounding convention could cause systematic over- or under-payment, leading to compliance issues for the organisation.
Mitigation & Contingency
Mitigation: Source the exact rounding specification from HLF's finance team before implementing MileageCalculationService. Document the rule as a comment in the source code and link to the authoritative reference.
Contingency: If the rule is ambiguous, implement both truncation and half-up rounding behind a configuration flag so the organisation can switch without a code release.
SharedPreferences reads and writes are asynchronous. If the distance prefill service (built in the next epic) calls LocalDistanceCache concurrently with a post-submission write, a race condition could result in the cache returning a stale or partially written value, causing the next form load to show an incorrect default.
Mitigation & Contingency
Mitigation: Wrap all SharedPreferences access in LocalDistanceCache with sequential async operations and document the non-concurrent usage contract in the class API.
Contingency: If race conditions are observed in testing, introduce a simple mutex pattern using a Completer to serialise cache operations.