high priority medium complexity testing pending backend specialist Tier 3

Acceptance Criteria

Tests connect to a dedicated Supabase test project (credentials sourced from environment variables, never hard-coded)
Peer mentor JWT: insert own claim succeeds (HTTP 201)
Peer mentor JWT: read own claim by ID succeeds and returns correct data
Peer mentor JWT: read another user's claim returns empty list or throws PermissionDeniedException (RLS enforced)
Coordinator JWT (same chapter): read all claims in chapter returns multiple rows including other users' claims
Coordinator JWT (different chapter): read claims from another chapter returns empty list (chapter-scoped RLS)
Any authenticated user JWT: read org_configuration row succeeds
Peer mentor JWT: write to org_configuration returns error (RLS write restriction enforced)
Admin JWT: write to org_configuration succeeds
All tests clean up inserted rows in tearDown to maintain test isolation
Tests are tagged @Tags(['integration']) and skipped in unit-test CI runs
Each test documents which RLS policy it exercises in its description string

Technical Requirements

frameworks
Flutter
flutter_test
Dart
Supabase
apis
Supabase REST API
Supabase Auth API
data models
MileageClaim
OrgConfiguration
performance requirements
Each individual test completes within 5 seconds
Full integration suite completes within 60 seconds
security requirements
Test credentials (service role key, test user JWTs) loaded exclusively from environment variables or a .env.test file excluded from version control
Test project must be isolated from production — separate Supabase project URL
Service role key used only in tearDown cleanup, never in role-specific test assertions
No real user PII in test fixtures

Execution Context

Execution Tier
Tier 3

Tier 3 - 413 tasks

Can start after Tier 2 completes

Implementation Notes

Create three Supabase clients in the test file: serviceRoleClient (for setup/teardown only), peerMentorClient (authenticated as test peer mentor), coordinatorClient (authenticated as test coordinator). Use supabase_flutter's SupabaseClient directly — do not use SupabaseMileageAdapter for setup to avoid circular dependency. Seed test data in setUpAll or individual setUp methods with unique IDs (use Uuid.v4()) to prevent cross-test contamination. The integration test file should live at integration_test/features/mileage/supabase_mileage_adapter_test.dart.

Add a README note in the test directory explaining how to configure environment variables for the test Supabase project. Ensure CI pipeline has a separate job for integration tests with the required env vars injected as secrets.

Testing Requirements

Integration tests using flutter_test with @Tags(['integration']) annotation. Each test signs in as a specific role using Supabase Auth signInWithPassword() with dedicated test accounts created in the test Supabase project. Use setUpAll() to sign in and tearDownAll() to sign out. Use setUp/tearDown for row-level cleanup via service-role client.

Tests must NOT rely on pre-existing data — all required rows are inserted as part of the test. RLS rejection assertions check for either an empty result set (select) or a caught PostgrestException with code '42501' (write). Document each test with a comment citing the specific RLS policy name it validates.

Component
Supabase Mileage Adapter
infrastructure low
Epic Risks (3)
high impact medium prob security

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.

medium impact low prob scope

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.

low impact low prob technical

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.