Entry point
POST /api/v1/search or GET /api/v1/search → SearchController → SearchService::findTutors()
File: app/Models/Services/v1/SearchService.php
Search parameters
TheSearch model (app/Models/v1/Search.php) defines the search criteria:
| Parameter | Type | Description |
|---|---|---|
path | string | Subject slug/path |
date | date | Requested lesson date |
dayOfTheWeek | string | Day of week for availability |
duration | int | Lesson duration in minutes |
availabilityTimes | array | Requested time slots |
subjectId | int | Subject filter |
subjectLevelIds | array | Subject level filters |
examBoards | array | Exam board filters |
lat / lng | float | Search location coordinates |
sort | string | Sort order |
filters | array | Additional filters (see below) |
Filter keys
| Key | Values |
|---|---|
FILTER_LESSON_TYPE | online, tutors_home, students_home |
FILTER_GENDER | male, female |
FILTER_LANGUAGE | language ID |
How search works
Resolve coordinates
If no lat/lng provided,
PostcodeService looks up coordinates from the postcode. Results are cached for 3 months via postcodes.io API.Build base query
Starts with
Tutor::query() (already scoped to role_id=1) and chains multiple scopes: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
Filter by location
For in-person lessons:
withDistance($lat, $lng)— adds a calculated distance column using the Haversine formulawithinDistance()— filters by tutor’smax_travel_distance
Check advance booking window
getAllUnavailableTutorIds() checks a 14-day advance booking window. Tutors unavailable across the entire window are excluded.Response format
Transformed viaSearchTransformer:
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
DistanceResponsewithgetDuration()(seconds) andgetMilesAway()(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.iopublic API - Results cached for 3 months
- Returns
PostcodeResponsewithgetLat()andgetLng()