Implement auto-approval edge function client
epic-travel-expense-registration-foundation-task-008 — Build the AutoApprovalEdgeFunctionClient Dart class that invokes the Supabase Edge Function responsible for evaluating whether a submitted expense claim meets the organisation's auto-approval criteria. Handle authentication headers, parse the approval/rejection response envelope, and expose a typed result object. Implement retry logic with exponential back-off for transient network failures.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 1 - 540 tasks
Can start after Tier 0 completes
Implementation Notes
Use supabase_flutter's `supabase.functions.invoke('auto-approve-expense', body: {'claim_id': claimId})` — this automatically attaches the JWT and targets the correct project URL. Model the request as a simple JSON envelope: `{claim_id: String}` — keep the mobile client's contract minimal to reduce coupling to edge function internals. For exponential backoff, use a helper `RetryPolicy` class with configurable maxAttempts, baseDelayMs, and multiplier rather than hardcoding delays inline — this makes the policy testable and reusable for other edge function clients. Define the AutoApprovalResult sealed class using Dart 3 sealed classes (not package:freezed) to keep the dependency count low.
The edge function response envelope should follow the convention: `{status: 'auto_approved' | 'manual_review' | 'rejected', approved_at?: ISO8601, reason?: string}` — agree this contract with the backend developer implementing the edge function. Document the expected response schema in a shared `contracts/` folder in the repo.
Testing Requirements
Unit tests (flutter_test + mocktail): mock the Supabase functions client, test AutoApproved response parsing, test RequiresManualReview response parsing, test HTTP 500 retry sequence (verify exactly 3 retries with correct delays using a fake async clock), test HTTP 400 no-retry behaviour, test timeout after 30 seconds, test cancellation mid-retry. Contract test: define the expected edge function request/response JSON schema and validate the client against it — this protects against edge function API changes breaking the mobile client silently. Integration test (optional, against local Supabase with deno serve): submit a real claim that meets auto-approval criteria and verify AutoApproved result is returned. Minimum 85% line coverage on client class.
Row-level security policies for expense claims must correctly scope data to organisation, role (peer mentor sees own claims only, coordinator sees org-wide queue), and claim status. Incorrect RLS can expose claims cross-organisation or prevent coordinators from accessing the attestation queue.
Mitigation & Contingency
Mitigation: Define RLS policies in code-reviewed migration files. Write integration tests that attempt cross-org reads with different JWT roles and assert access denial. Review with a second engineer before merging migrations.
Contingency: If RLS is misconfigured post-deployment, disable the affected policy temporarily and apply a hotfix migration within the same release window. No claim data is exposed publicly due to Supabase project-level auth requirement.
The auto-approval Edge Function is triggered server-side on expense insert. Cold-start latency or Edge Function failures can block the submission response and degrade UX, especially on mobile networks.
Mitigation & Contingency
Mitigation: Implement the auto-approval Edge Function client with a timeout and graceful fallback: if no result is received within 5 seconds, treat the claim as 'pending' and poll for the status update via Supabase Realtime. Keep the Edge Function warm with a periodic ping.
Contingency: If Edge Function reliability is unacceptable, move auto-approval evaluation to a database trigger or Postgres function as an interim measure, accepting that threshold configuration changes require a migration rather than a settings update.
The expense type catalogue and threshold configuration are cached locally for offline use. If an organisation updates their catalogue exclusion rules or thresholds while a peer mentor is offline, the local cache may allow submissions that violate the new policy.
Mitigation & Contingency
Mitigation: Cache entries include a TTL (24 hours). On connectivity restore, refresh cache before allowing new submissions. Server-side validation in the Edge Function and save functions provides a second enforcement layer.
Contingency: If a stale-cache submission passes client validation but fails server validation, surface a clear error message explaining that the expense type rules have been updated and prompt the user to review their selection with the refreshed catalogue.