Skip to content

fix: resolve geocoder endpoints through the configured fleetops geocoder - #408

Merged
roncodes merged 2 commits into
release/v0.6.74from
fix/geocoder-endpoints-use-configured-geocoder
Oct 19, 2026
Merged

roncodes merged 2 commits into
release/v0.6.74from
fix/geocoder-endpoints-use-configured-geocoder

Conversation

@roncodes

Copy link
Copy Markdown
Member

Fixes fleetbase/fleetbase#723

Problem

GET /int/v1/geocoder/query and /int/v1/geocoder/reverse return [] for addresses that places/lookup resolves without trouble. GeocoderController used the geocoder-laravel facade. Its Google provider is built from config/geocoder.php, and that file is evaluated when config loads, before the Google Maps API key from the settings table is set. So installs that set the key in the console end up with a provider that has no key. The facade's Chain provider catches the resulting failure and returns an empty collection, and the controller returns that as []. The config also passes the locale where the provider expects the region.

This breaks address lookups in ember-ui's CoordinatesInput, ModelCoordinatesInput and AutocompleteInput, for example on the place edit screen.

Fix

  • Add Geocoding::geocoder(), a public accessor for the geocoder that places/lookup and PlaceSearch already use. It reads the API key from settings and has the correct region and locale.
  • GeocoderController::forwardGeocode() and reverseGeocode() now run GeocodeQuery / ReverseQuery through that geocoder. The response shape is unchanged.

Provider errors, such as an invalid key, now propagate instead of turning into a silent []. The ember-ui consumers already catch fetch errors.

Tests

  • New contract test: the controller resolves both lookups through the injected fleetops.geocoder, and fails if anything touches the facade. Without the controller change it fails with geocoder facade should not be used.
  • LookupAndGeocoderControllerContractsTest, GeocodingInjectedClientTest, FleetOpsSupportContractsTest and PlaceSearchRankingTest all pass. php-cs-fixer is clean. phpstan output on the touched files is the same as before.

Not tested against a live Google Maps key.

Out of scope

Place::createFromGeocodingLookup / createFromReverseGeocodingLookup, PlaceSearch, and the public API PlaceController / DriverController still use the facade, so they have the same settings-key problem. They can move over in a follow-up.

The internal geocoder/query and geocoder/reverse endpoints used the
geocoder-laravel facade, whose Google provider is built from
config/geocoder.php when the config loads, before the API key from the
settings table is set. Its Chain provider swallowed the resulting
failure, so both endpoints returned [] while places/lookup, which goes
through Geocoding, resolved the same address.

Route both lookups through Geocoding::geocoder() so they share the
settings-backed API key, region and locale.

Fixes fleetbase/fleetbase#723
@roncodes
roncodes changed the base branch from main to release/v0.6.74 October 19, 2026 04:21
GeocoderController no longer resolves the geocoder-laravel facade, so
the seam test's app('geocoder') stand-in was never consulted and the
unbound fleetops geocoder tried a live Google request.
roncodes added a commit that referenced this pull request Oct 19, 2026
Place, PlaceSearch and the v1 Place and Driver controllers still called the
geocoder-laravel facade. Its Google provider is built from
config/geocoder.php when the config loads, before the settings-table API key
is set, and its Chain provider swallows the failure, so these lookups
silently returned no results (the same bug #408 fixed for the internal
geocoder endpoints).

They now go through Geocoding::geocoder(). Geocoding::lookupAddress() and
lookupCoordinates() return the raw address results; a failed lookup still
resolves to an empty collection, so place creation keeps its raw-address
fallback, but the failure is now logged instead of hidden. The driver
tracking endpoint keeps calling the geocoder directly so its failures still
reach Sentry.

config/geocoder.php now passes the region where GoogleMaps expects it
(it passed the locale) and uses the default cache store instead of a
'geocode' store that does not exist. It only matters for code outside
fleetops that still uses the facade.

Tests bind 'fleetops.geocoder' stand-ins instead of app('geocoder').

Refs fleetbase/fleetbase#723
@codecov

codecov Bot commented Oct 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (7887aa5) to head (891672d).
⚠️ Report is 1 commits behind head on release/v0.6.74.

Additional details and impacted files
@@                 Coverage Diff                 @@
##             release/v0.6.74      #408   +/-   ##
===================================================
  Coverage             100.00%   100.00%           
- Complexity             13591     13592    +1     
===================================================
  Files                    634       634           
  Lines                  49331     49333    +2     
===================================================
+ Hits                   49331     49333    +2     
Flag Coverage Δ
backend 100.00% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@roncodes
roncodes merged commit 8a09a98 into release/v0.6.74 Oct 19, 2026
8 checks passed
@roncodes
roncodes deleted the fix/geocoder-endpoints-use-configured-geocoder branch October 19, 2026 05:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] /api/int/v1/geocoder/query returns [] for valid addresses while places/search resolves them

1 participant