Data Layer medium complexity mobile
1
Dependencies
1
Dependents
1
Entities
1
Integrations

Description

Abstracts all Supabase read/write operations for mileage claim records. Handles inserting new claims with their computed status, fetching claims by user or coordinator scope, and updating claim status when a coordinator performs manual attestation.

Feature: Mileage Reimbursement Entry

mileage-claim-repository

Summaries

The Mileage Claim Repository is the data integrity backbone of the entire expense reimbursement system, ensuring that every claim submitted by an employee is durably recorded, correctly scoped to the right user or organisation, and accurately updated when coordinators take action. By centralising all database interactions through a single abstraction, the organisation avoids data inconsistencies that could lead to incorrect payroll processing, compliance failures, or audit discrepancies. The repository also enforces access boundaries — employees see only their own claims, coordinators see their organisation's — reducing the risk of accidental data exposure and the liability that comes with it.

Medium complexity driven by the breadth of operations required: insert, user-scoped fetch, org-scoped fetch with optional status filter, status update, delete, and single-record lookup. Each operation requires distinct Supabase query construction and Row Level Security (RLS) policy alignment, which must be coordinated with the backend/database team before development begins. Testing must cover RLS enforcement (a user cannot fetch another user's claims), status transition validity, and behaviour when Supabase is unreachable. The supabase-mileage-adapter dependency must be stable before integration testing can proceed.

Plan for a dedicated QA pass on the org-scoped coordinator queries, as these carry the highest risk of data leakage if filter logic is incorrect.

MileageClaimRepository wraps a SupabaseMileageAdapter and exposes a clean domain-typed interface, decoupling the rest of the application from Supabase query semantics. createClaim() maps a MileageClaim domain object to a Supabase insert payload and returns the persisted record with server-generated fields (id, created_at). getClaimsForUser() and getClaimsForOrg() rely on Supabase RLS policies for access enforcement — the repository should not re-implement access checks in Dart. updateClaimStatus() should use an optimistic update pattern only if the UI requires it; otherwise a simple await-and-refresh is safer.

deleteClaim() should check the correction window policy before issuing the delete, or delegate that check to the service layer. All methods must propagate typed RepositoryException subclasses rather than raw Supabase errors so the service layer can handle them uniformly.

Responsibilities

  • Insert a new mileage claim row with status, distance, route, and amount into Supabase
  • Fetch claims for the current user ordered by submission date
  • Update claim status from 'pending_review' to 'approved' or 'rejected' on coordinator action
  • Delete or void claims within the allowed correction window

Interfaces

createClaim(MileageClaim claim) → Future<MileageClaim>
getClaimsForUser(String userId) → Future<List<MileageClaim>>
getClaimsForOrg(String orgId, ClaimStatus? filter) → Future<List<MileageClaim>>
updateClaimStatus(String claimId, ClaimStatus status) → Future<void>
deleteClaim(String claimId) → Future<void>
getClaimById(String claimId) → Future<MileageClaim?>

Relationships

Dependencies (1)

Components this component depends on

Dependents (1)

Components that depend on this component

Related Data Entities (1)

Data entities managed by this component

Used Integrations (1)

External integrations and APIs this component relies on

API Contract

View full contract →
REST /api/v1/claims 5 endpoints
GET /api/v1/claims
GET /api/v1/claims/:id
POST /api/v1/claims
PUT /api/v1/claims/:id
DELETE /api/v1/claims/:id