Skip to main content

Entry point

POST /api/v1/search or GET /api/v1/searchSearchControllerSearchService::findTutors() File: app/Models/Services/v1/SearchService.php

Search parameters

The Search model (app/Models/v1/Search.php) defines the search criteria:

Filter keys

How search works

1

Resolve coordinates

If no lat/lng provided, PostcodeService looks up coordinates from the postcode. Results are cached for 3 months via postcodes.io API.
2

Build base query

Starts with Tutor::query() (already scoped to role_id=1) and chains multiple scopes:
3

Filter by availability

Uses isAvailableOnDay() or isAvailableOnDate() scopes. Checks:
  • Tutor has availability on the requested day/date
  • Tutor is not on holiday (unavailable_from/unavailable_until)
  • No clashing existing lessons
  • Available time slots match requested times
4

Filter by location

For in-person lessons:
  • withDistance($lat, $lng) — adds a calculated distance column using the Haversine formula
  • withinDistance() — filters by tutor’s max_travel_distance
For online lessons: location filtering is skipped.
5

Apply additional filters

Gender, language, lesson type filters applied via withFilters() scope.
6

Check advance booking window

getAllUnavailableTutorIds() checks a 14-day advance booking window. Tutors unavailable across the entire window are excluded.
7

Sort and paginate

Results sorted via sortResultsBy() scope and returned with pagination via ServicePaginatorResponse.

Response format

Transformed via SearchTransformer:

BlackBox distance service

For travel time calculations between tutor and student locations, the API calls the BlackBox microservice (runs as a Docker sidecar on port 3000). File: app/BlackBox/Models/Distance.php
  • Calculates transit distance/duration between two UK postcodes
  • Results cached for 2 days
  • Returns DistanceResponse with getDuration() (seconds) and getMilesAway() (converted from meters)
  • Uses Google Maps Distance Matrix API under the hood

PostcodeService

File: app/Models/Services/PostcodeService/PostcodeService.php
  • Fetches postcode coordinates from postcodes.io public API
  • Results cached for 3 months
  • Returns PostcodeResponse with getLat() and getLng()