New geocode_bp sibling to the existing /api/reverse?lat=&lon= route (which
is unchanged). Returns a flat 9-field bundle for the Central enrichment
framework: name, city, county, state, country, postal_code (Photon),
timezone (timezones.sqlite via R-tree + shapely), landclass (in-process
lookup_landclass), elevation_m (Valhalla /height).
- Each component lookup is independent and wrapped in try/except: a failure
logs a warning and yields null, never a 5xx. 400 only on unparseable /
out-of-range coordinates.
- lat/lon parsed manually rather than via Flask <float:>, which rejects
negative and integer coordinates and would 404 instead of 400.
- 10k-entry / 24h TTLCache keyed on coords rounded to 4 decimals.
- Tests mock Photon/Valhalla/landclass; one test exercises the real
timezones.sqlite. cachetools pinned in requirements.txt.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>