fix(tradein/v2): настоящая карта Leaflet+OSM вместо декоративного псевдо-SVG #2528

Merged
lekss361 merged 2 commits from fix/tradein-v2-real-map into main 2026-07-26 20:02:29 +00:00
Owner

Summary

Жалоба пользователя: «при получении адреса карта над окном выбора не работает».

Диагноз: она и не работала — прямоугольник над полем адреса был декоративным SVG (сетка + вымышленные улицы + кольца радиуса), координаты в него не передавались вообще. Кнопки +/ масштабировали картинку, метка сверху зеркалила текст из инпута. Под ним стояла подпись «Схематично · не географическая карта · радиус не в масштабе» — единственное, что было сделано по прошлому аудиту (Fix #7).

Заменено на настоящую карту:

  • Leaflet + OSM-тайлы, тот же CDN-загрузчик с SRI-хешами, что уже используется в v2/SourcesMap.tsx — новых зависимостей нет, package.json/lock не тронуты.
  • Центр — на координатах выбранного адреса, маркер на доме (адрес экранируется, вставка только в текстовый узел).
  • Круг радиуса анализа — L.circle в реальных метрах, синхронизирован с дропдауном «РАДИУС АНАЛИЗА».
  • +/ управляют зумом настоящей карты, disabled на границах 11/19.
  • Подпись про «схематично» убрана — она стала неправдой. Атрибуция «© OpenStreetMap» приходит штатным attribution-control (требование лицензии тайлов).
  • Пока координат нет — аккуратная заглушка, инстанс Leaflet не создаётся вовсе.

Второй коммит — правка по pre-push ревью: флаг ошибки загрузки CDN не сбрасывался при повторной попытке, из-за чего один сбой unpkg убивал карту до перезагрузки страницы даже после выбора другого адреса.

Осознанные решения

  • «Ценовые пины» аналогов на новую карту НЕ перенесены. Их позиции были процентами по вымышленной фиксированной сетке с прижатием дальних к краям — перенос «как есть» на настоящую карту дал бы более тонкую версию ровно той нечестности, ради которой это чинится. Проп markers оставлен в интерфейсе (вызов из page.tsx не сломан), но не используется, о чём есть комментарий в коде.
  • Leaflet-загрузчик продублирован в файле, а не вынесен в общий модуль — так уже сделано намеренно в SourcesMap.tsx и MapPicker.tsx («each v2 file is a self-contained port»).

Известное ограничение (не в этом PR)

app/v2/page.tsx при восстановлении оценки по ссылке ?id= не прокидывает lat/lon в initialValues — только адрес и параметры. Это существующий пробел, не введённый здесь. Следствие: после перехода по ссылке на готовую оценку карта покажет заглушку, пока пользователь не выберет адрес заново из подсказок. Нужен отдельный тикет на проброс estimate.target_lat/target_lon.

Test plan

  • npx tsc --noEmit — чисто
  • npm run lint — чисто по изменённому файлу
  • pre-push code-review — без блокеров, единственное замечание исправлено вторым коммитом
  • Визуал на проде после мержа: центрирование, маркер, круг радиуса, зум-кнопки, заглушка до выбора адреса, смена радиуса (локально не проверить — RouteGuard без бэкенда рендерит пустой DOM)
## Summary Жалоба пользователя: «при получении адреса карта над окном выбора не работает». Диагноз: она и не работала — прямоугольник над полем адреса был декоративным SVG (сетка + вымышленные улицы + кольца радиуса), координаты в него не передавались вообще. Кнопки `+`/`−` масштабировали картинку, метка сверху зеркалила текст из инпута. Под ним стояла подпись «Схематично · не географическая карта · радиус не в масштабе» — единственное, что было сделано по прошлому аудиту (Fix #7). Заменено на настоящую карту: - Leaflet + OSM-тайлы, тот же CDN-загрузчик с SRI-хешами, что уже используется в `v2/SourcesMap.tsx` — новых зависимостей нет, `package.json`/lock не тронуты. - Центр — на координатах выбранного адреса, маркер на доме (адрес экранируется, вставка только в текстовый узел). - Круг радиуса анализа — `L.circle` в реальных метрах, синхронизирован с дропдауном «РАДИУС АНАЛИЗА». - `+`/`−` управляют зумом настоящей карты, disabled на границах 11/19. - Подпись про «схематично» убрана — она стала неправдой. Атрибуция «© OpenStreetMap» приходит штатным attribution-control (требование лицензии тайлов). - Пока координат нет — аккуратная заглушка, инстанс Leaflet не создаётся вовсе. Второй коммит — правка по pre-push ревью: флаг ошибки загрузки CDN не сбрасывался при повторной попытке, из-за чего один сбой unpkg убивал карту до перезагрузки страницы даже после выбора другого адреса. ## Осознанные решения - **«Ценовые пины» аналогов на новую карту НЕ перенесены.** Их позиции были процентами по вымышленной фиксированной сетке с прижатием дальних к краям — перенос «как есть» на настоящую карту дал бы более тонкую версию ровно той нечестности, ради которой это чинится. Проп `markers` оставлен в интерфейсе (вызов из `page.tsx` не сломан), но не используется, о чём есть комментарий в коде. - Leaflet-загрузчик продублирован в файле, а не вынесен в общий модуль — так уже сделано намеренно в `SourcesMap.tsx` и `MapPicker.tsx` («each v2 file is a self-contained port»). ## Известное ограничение (не в этом PR) `app/v2/page.tsx` при восстановлении оценки по ссылке `?id=` не прокидывает `lat`/`lon` в `initialValues` — только адрес и параметры. Это существующий пробел, не введённый здесь. Следствие: после перехода по ссылке на готовую оценку карта покажет заглушку, пока пользователь не выберет адрес заново из подсказок. Нужен отдельный тикет на проброс `estimate.target_lat`/`target_lon`. ## Test plan - [x] `npx tsc --noEmit` — чисто - [x] `npm run lint` — чисто по изменённому файлу - [x] pre-push code-review — без блокеров, единственное замечание исправлено вторым коммитом - [ ] Визуал на проде после мержа: центрирование, маркер, круг радиуса, зум-кнопки, заглушка до выбора адреса, смена радиуса (локально не проверить — `RouteGuard` без бэкенда рендерит пустой DOM)
lekss361 added 2 commits 2026-07-26 19:52:43 +00:00
01 ПАРАМЕТРЫ КВАРТИРЫ showed a fake SVG (grid + invented streets + radius
rings) above the address field, with no real coordinates driving it — the
+/- buttons scaled the picture, not a map. Replaced with a real Leaflet map
(same CDN-loader/tile pattern as SourcesMap.tsx/MapPicker.tsx):

- centred on coords from the picked geocode suggestion (lat/lon), with a
  marker on the address
- radius circle in real metres (L.circle), synced with РАДИУС АНАЛИЗА;
  "Авто" previews the backend's primary two-tier default (1000 m)
- +/- buttons drive real Leaflet zoom (zoomIn/zoomOut), not a CSS scale hack
- removed the "Схематично · не географическая карта" disclaimer (no longer
  true) — OSM attribution now comes from Leaflet's own attribution control
- tidy placeholder (icon + hint text) while no address is picked yet,
  instead of an empty box or a broken map

The old %-projected analog price pins (mapMarkers()) are not replotted on
the real map — their positions were fabricated against a fixed non-scale
grid and would be geographically wrong at the map's real zoom.
fix(tradein/v2): reset map CDN-error flag on retry
All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI / changes (pull_request) Successful in 12s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Successful in 1m14s
99f1a4a733
Без сброса ветка ошибки — тупик: она подменяет контейнер карты в дереве
рендера, поэтому mapContainerRef остаётся null и повторная попытка не может
удаться. Один сбой unpkg убивал карту до перезагрузки страницы, даже после
выбора другого адреса. Найдено на pre-push ревью.
lekss361 merged commit e0b63cc637 into main 2026-07-26 20:02:29 +00:00
lekss361 deleted branch fix/tradein-v2-real-map 2026-07-26 20:02:29 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#2528
No description provided.