Every lawn care operator with more than one truck faces the same problem every morning: who goes where? Which technician takes the north side of town, which takes the south, and in what order do they hit their stops? Get it wrong and you burn fuel, waste daylight, and arrive at the last property when the customer has already given up and gone inside.

The route builder is a three-panel interface. Left panel: unrouted orders, each one a property waiting for assignment. Center: a Leaflet map with colored polylines — one color per technician, grey markers for unassigned stops. Right: route cards with approve buttons, showing the planned sequence for each tech.

Behind the interface, a Google Routes API integration with computeRoutes and optimizeWaypointOrder handles the optimization. The Distance Matrix provides travel times between stops. When API credits aren't available, a Haversine nearest-neighbor fallback ensures the system still works — less optimal routes, but routes nonetheless.

Auto-Build uses geographic clustering by longitude bands. Simple, effective for service areas that spread east-west. Select your technicians, click build, and the algorithm divides the map into vertical strips and assigns each strip to a tech. The result isn't perfect — proper k-means or DBSCAN clustering would handle irregular geographies better — but it's fast and it's right often enough to be useful as a starting point that the operator can adjust.

Four new endpoints. An available-orders query with coordinate and unrouted scoping. An optimize preview that returns the plan without saving it. The auto-build that clusters and assigns. And an approve action that transitions a route from planning to active. The Order model gained scopeUnrouted() and scopeWithCoordinates() — query scopes that make the route builder's data needs express naturally in Eloquent.

The route builder doesn't replace a dispatcher's judgment. It replaces the forty minutes of staring at a map and counting addresses that comes before the judgment.