Backend /api/v1/geocode/reverse теперь возвращает snapped_lat/snapped_lon
центра matched здания (от Yandex Point.pos / Nominatim response.lat-lon /
cadastral row) + precision. Раньше endpoint echo'ил input lat/lon —
адрес resolved'ился до canonical «ул. Малышева, 125», но marker
оставался где кликнул user (часто в проезде / дворе).
Backend:
- reverse_geocode: str | None → ReverseGeocodeResult | None
(address + snapped_lat/snapped_lon + precision + provider).
Provider fallback Cadastral FDW → Yandex (если key) → Nominatim.
Yandex /reverse дёргаем с kind=house чтобы сразу получить здание.
- /api/v1/geocode/reverse: новый Pydantic ReverseResponse model.
- snap_precision_useful() helper для frontend logic parity.
- Legacy _cadastral_reverse_sync сохранён для backward compat.
Frontend MapPicker:
- После reverse — если precision in (exact, number, cadastral) и
snapped >5m от клика → marker.setLatLng + map.panTo с animate
- precision=street/range/locality → marker остаётся где кликнули
(не врём что нашли точное здание).
- Hint «Точка дома по Яндексу» под address с aria-live="polite"
(var(--fg-tertiary) — token compliance).
- haversineMeters helper для distance check (6371000m Earth radius).
Tests: 37 backend pass, ruff + tsc clean.
Code-reviewer LGTM, 1 nit applied inline (hex → var(--fg-tertiary)).
Closes#582 (Phase 5).