Data Layer medium complexity Shared Component mobile
1
Dependencies
3
Dependents
2
Entities
1
Integrations

Description

Data access layer for contacts and peer mentors backed by Supabase. All queries are scoped by organization ID and rely on Supabase Row Level Security policies to enforce role-based access at the database level, ensuring users never receive records outside their authorization scope.

Feature: Contact List Management

contact-repository

Summaries

The Contact Repository is the data security foundation for the entire contacts experience. By enforcing organization-scoped queries and relying on Supabase Row Level Security policies, it guarantees that no user can ever retrieve contact records outside their authorized scope — even in the event of a bug in the application layer. This database-level enforcement significantly reduces the risk of accidental data breaches, which could expose the organization to regulatory penalties and reputational damage. As a shared component used across multiple features, investment in its correctness and security hardening pays dividends across the entire platform, not just a single feature.

Contact Repository is a medium-complexity, shared data access component that is a foundational dependency for multiple features and services. It must be delivered and validated early in the project timeline since contact-list-service, contact-search-service, and the Riverpod provider all depend on it. Supabase RLS policy configuration is a critical external dependency — the policies governing contact and peer mentor access by role must be authored, reviewed, and deployed to the Supabase project before repository integration tests can run. Plan a dedicated infrastructure spike for RLS policy setup.

As a shared component, any schema changes to the Contact or PeerMentor models require coordinated updates here and across all dependent layers. Data mapping logic should be covered by unit tests using mock Supabase responses.

ContactRepository is the exclusive Supabase client for contact and peer mentor data, scoped strictly by `orgId` on every query. Fetches use the Supabase Flutter SDK's `.from('contacts').select()` builder with `.eq('org_id', orgId)` and ILIKE filters for search variants. All access control enforcement is delegated to Supabase RLS — the repository itself does not implement role filtering logic, which lives in ContactListService. JSON responses from Supabase are mapped to typed `Contact` and `PeerMentor` models using factory constructors (`Contact.fromJson()`).

The repository depends on `contact-list-riverpod-provider` for the current auth session context needed to authenticate Supabase requests. Ensure all public methods are async and propagate `PostgrestException` to the service layer. Consider adding a thin caching layer (e.g., in-memory TTL cache) if repeated fetches on provider invalidation cause noticeable latency.

Responsibilities

  • Fetch contact list filtered by organization and role via Supabase RLS
  • Fetch peer mentor list with role-scoped queries
  • Support name and notes ILIKE search queries against Supabase
  • Map Supabase JSON responses to typed Contact and PeerMentor models

Interfaces

fetchContacts(String orgId)
fetchPeerMentors(String orgId)
fetchContactsBySearch(String query, String orgId)
fetchPeerMentorsBySearch(String query, String orgId)
fetchContactById(String contactId)
fetchPeerMentorById(String mentorId)

Relationships

Dependencies (1)

Components this component depends on

Dependents (3)

Components that depend on this component

Related Data Entities (2)

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/contacts 9 endpoints
GET /api/v1/contacts Fetch all contacts for an org
GET /api/v1/contacts/:id Fetch a single contact by ID
POST /api/v1/contacts Create a contact record
PUT /api/v1/contacts/:id Update a contact record
DELETE /api/v1/contacts/:id Delete a contact record
GET /api/v1/contacts/peer-mentors Fetch all peer mentors for an org
+3 more