Katkat

Build a Paginated Provider Search Backend and React Filter UI

VersemedicalSoftware Engineer · Onsite

Last updated

This problem tests full-stack proficiency, focusing on efficient database querying with optional filters, secure backend API design, and responsive frontend state management.

Problem Statement

You are tasked with building a provider search system for a medical portal. The system must support searching for doctors by name (prefix match) and filtering by specialization, while maintaining stable pagination.

Database Schema

Assume a PostgreSQL table providers with columns: id (UUID), name (TEXT), specialization (TEXT), and rating (FLOAT).

Task Requirements

  1. Backend API: Create an endpoint GET /api/providers that accepts query (string), specialization (string), page (integer, 1-indexed), and limit (integer). The API must return a paginated list of providers and the total count.
  2. Database Query: Write an efficient SQL query that handles optional filters. Ensure that the query is indexed for prefix-matching on the name.
  3. Frontend Component: Implement a React component that fetches this data, displays the providers in a list, and provides controls for the search input, specialization dropdown, and pagination. Include handling for loading states and error boundaries.

Worked Example

Input Request: GET /api/providers?query=Dr&specialization=Cardiology&page=1&limit=10 Expected Response:

{
  "data": [{"id": "1", "name": "Dr. Smith", "specialization": "Cardiology", "rating": 4.5}],
  "total": 1,
  "page": 1,
  "limit": 10
}

Edge Cases

  • Empty search results.
  • page number exceeding the total number of pages.
  • SQL injection prevention for the name prefix search.
  • Handling rapid user typing (debounce requirements).

Hints

Hint 1

Use parameterized queries to safely handle the LIKE operator for prefix matching, e.g., 'name ILIKE $1 || %'.

Hint 2

Ensure your SQL query uses an ORDER BY clause with a tie-breaker (like ID) to guarantee stable sorting across pages.

Hint 3

On the frontend, use the useEffect hook with a debounce utility to avoid excessive API calls while the user is typing.

Follow-up questions

  • How would you optimize the database performance if the providers table grew to contain 10 million rows?
  • How would you handle race conditions where a user updates filters while a previous fetch request is still pending?
  • How would you implement server-side caching for the total count to avoid a slow count(*) query on every page change?