All checks were successful
12-review.md (REQUEST_CHANGES, attempt 2/3) flagged 6 must-fix items
in the analysis/architecture artefacts plus matching bugs that had
already leaked into the committed implementation. This patch lands
both: documents corrected, code aligned with corrected specs, tests
updated.
P1-1: TRZ/ADR/Data/Risks referenced fictional layer ids
(`trails-grade1..5-halo-satellite`, `paths-bridleway-halo-satellite`).
Actual style*.json has only `trails-track-halo-satellite` and
`trails-path-bridleway-halo-satellite`; grade differentiation lives
inside one `match` expression on `tracktype` within `trails-track`.
Docs rewritten to operate on real ids.
P1-2: POI labels contrast was broken — spec changed only halo-color
to black, leaving `text-color: #333333` (light theme baseline)
unreadable over the new black halo. Code+docs now switch BOTH
`text-color` (-> `#ffffff` on satellite) AND halo together, with
per-theme baselines (`#333333` light / `#e0e0e0` dark) restored on
return to Schematic.
P1-3: BRD §5 hillshade risk said «hillshade auto-disabled on
satellite», contradicting TRZ/ADR/AC. BRD wording aligned: hillshade
keeps working over satellite; visual check is AC-04.
P1-4: background-color had four divergent sources (`#1a1a1a`,
`#2a2a2a`, `#1a1a2e`, `#f0ede6`), incl. an inverted-theme typo and a
baseline `#1a1a1a` that didn't match the actual `style-dark.json:28`
value `#1a1a2e`. Settled on ADR-004's single-constant model: `#2a2a2a`
on satellite for both themes; on Schematic restore per-theme baselines
`#f0ede6` (light) / `#1a1a2e` (dark). `_applyBackgroundForSatellite`
fixed accordingly.
P1-5: app.js already had `layerState.basemap` and `toggleLayer
('basemap')` (legacy «Базовая карта» switch). Neither TRZ nor ADR
specified the interaction. Added save&restore contract: on entering
Satellite save `layerState.basemap` to `_savedBasemapState` and
force-hide `osm-base`; on returning to Schematic restore osm-base
visibility from the saved value. CSS hook `body.satellite-active
#btn-basemap { display:none }` keeps the user from trying to enable
a hybrid mode (out of scope, BRD §3). TRZ §5.6, ADR-004 §8.
P1-6: `restoreTrailsState()` and `onTrailsCheckbox()` only managed
visibility of `trails-track` / `trails-path-bridleway`, leaving
their halo-underlay siblings as «phantom» halos when the user
unchecked grunты/тропы under Satellite. Introduced
`_applyTrailHaloVisibility(map, base)` reading checkbox state from
DOM; called from `onTrailsCheckbox`, `restoreTrailsState`, and both
branches of `applyBaseLayer`. Rule: halo visible ⇔ (base ===
satellite) AND (checkbox ON). TRZ §5.7, ADR-004 §9.
Docs bumped: BRD v2, TRZ v2, AC v2, Data v2, Risks v2; ADR-004
получает «Ревизии»-секцию (status remains accepted — only editorial
fixes, no decision change).
Tests:
- tests/unit/base_layer.test.js: rewritten 2 background-color
assertions (#1a1a1a expectation removed), added 6 new tests for
P1-2 / P1-4 (POI text-color per-theme baselines, single satellite
bg #2a2a2a, baseline restore on Schematic).
- All 33 JS unit tests + 22 pytest static checks green.
- Full pytest suite: 76 passed (excluding pre-existing
shapely-import skipped collection in tests/unit/test_health.py).
Refs: ET-007
Review: docs/work-items/ET-007/12-review.md (P1-1..P1-6)
ADR: docs/work-items/ET-007/06-adr/ADR-004-satellite-base-layer.md (rev. 2026-05-31)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
14 KiB
14 KiB
type, work_item_id, title, version, status, created_at, updated_at, changelog, authors
| type | work_item_id | title | version | status | created_at | updated_at | changelog | authors | ||
|---|---|---|---|---|---|---|---|---|---|---|
| acceptance-criteria | ET-007 | AC: Спутниковая карта (Схема / Спутник) | 2 | draft | 2026-05-31 | 2026-05-31 |
|
|
Acceptance Criteria — ET-007: Спутниковая карта (Схема / Спутник)
AC-01: UI переключателя
Feature: Переключатель подложки в попапе слоёв
Scenario: Открытие попапа показывает переключатель
Given пользователь находится на карте
When пользователь нажимает кнопку «Рельеф» (#terrain-toggle)
Then открывается попап #terrain-popup
And в попапе виден segmented-control «Подложка» с кнопками «Схема» и «Спутник»
And одна из кнопок имеет класс .active
Scenario: Default — Схема
Given localStorage пуст (или ключ 'map-base-layer' не задан)
When пользователь открывает попап слоёв
Then активна кнопка «Схема» (#base-btn-schematic)
And не активна кнопка «Спутник» (#base-btn-satellite)
AC-02: Переключение на «Спутник»
Feature: Переключение Схема → Спутник
Scenario: Базовое переключение
Given активна подложка «Схема»
When пользователь нажимает «Спутник» в попапе слоёв
Then кнопка «Спутник» получает класс .active
And кнопка «Схема» теряет класс .active
And на карте слой osm-base скрыт (visibility=none)
And на карте появляется слой satellite-base (visibility=visible)
And положение карты (center, zoom, bearing, pitch) не изменилось
Scenario: Атрибуция Esri отображается
Given пользователь включил режим «Спутник»
Then в нижнем правом углу карты видна атрибуция «Source: Esri, Maxar, Earthstar Geographics, and the GIS User Community»
Scenario: Кнопка «Базовая карта» скрывается на спутнике (P1-5)
Given активна подложка «Спутник»
Then UI-кнопка #btn-basemap не видна пользователю
And пользователь не может из UI включить osm-base поверх спутника (out of scope, BRD §3 — гибридный режим)
Scenario: Запоминание выбора «Базовая карта» при входе в Спутник (P1-5)
Given активна подложка «Схема»
And пользователь явно выключил «Базовую карту» (layerState.basemap === false, osm-base.visibility === 'none')
When пользователь переключается на «Спутник»
Then значение layerState.basemap сохраняется во внутреннем _savedBasemapState === false
And osm-base.visibility остаётся 'none' (принудительно)
AC-03: Переключение на «Схема»
Feature: Переключение Спутник → Схема
Scenario: Возврат на схему (layerState.basemap по умолчанию true)
Given активна подложка «Спутник»
And до входа в «Спутник» layerState.basemap === true (default)
When пользователь нажимает «Схема» в попапе слоёв
Then кнопка «Схема» получает класс .active
And слой osm-base снова виден (visibility=visible)
And слой satellite-base скрыт (visibility=none), но source остаётся в стиле
And положение карты не изменилось
And UI-кнопка #btn-basemap снова видна
Scenario: Возврат на схему с восстановлением выбора пользователя (P1-5)
Given активна подложка «Спутник»
And до входа в «Спутник» пользователь выключил «Базовую карту» (_savedBasemapState === false)
When пользователь нажимает «Схема»
Then слой osm-base остаётся скрытым (visibility=none) — выбор пользователя восстановлен
And layerState.basemap === false
And _savedBasemapState сбрасывается в null
AC-04: Совместимость со слоями приложения
Feature: Слои поверх спутника
Scenario: Грунтовки и тропы видны на спутнике
Given активна подложка «Спутник»
And в попапе включены «Грунтовки» и «Тропы»
Then на карте видны линии грунтовок (trails-track) и троп (trails-path-bridleway) поверх спутника
And halo-слой trails-track-halo-satellite visibility=visible
And halo-слой trails-path-bridleway-halo-satellite visibility=visible
Scenario: Выключение «Грунтовки» скрывает и halo (P1-6)
Given активна подложка «Спутник»
And чекбокс «Грунтовки» был ON
When пользователь снимает чекбокс «Грунтовки»
Then trails-track visibility=none
And trails-track-halo-satellite visibility=none (halo не остаётся «фантомом»)
Scenario: Выключение «Тропы» скрывает и halo (P1-6)
Given активна подложка «Спутник»
And чекбокс «Тропы» был ON
When пользователь снимает чекбокс «Тропы»
Then trails-path-bridleway visibility=none
And trails-path-bridleway-halo-satellite visibility=none
Scenario: На «Схеме» halo-слои всегда скрыты (P1-6)
Given активна подложка «Схема»
And чекбокс «Грунтовки» ON
Then trails-track visibility=visible
And trails-track-halo-satellite visibility=none
Scenario: POI видны и читаемы на спутнике (P1-2)
Given активна подложка «Спутник»
And в попапе включён «POI»
Then на карте видны маркеры POI поверх спутника
And poi-labels paint: text-color === '#ffffff'
And poi-labels paint: text-halo-color === '#000000'
And poi-labels paint: text-halo-width === 2
And poi-circles paint: circle-stroke-color === '#ffffff'
And poi-circles paint: circle-stroke-width === 2
Scenario: POI baseline восстанавливается на «Схеме» (P1-2)
Given был активен «Спутник», POI labels в режиме спутника
When пользователь возвращается на «Схему» (light-тема)
Then poi-labels paint: text-color === '#333333' (baseline light, Data §5)
And poi-labels paint: text-halo-color === '#ffffff' (baseline light)
And poi-labels paint: text-halo-width === 1.5 (baseline light)
Scenario: Hillshade поверх спутника
Given активна подложка «Спутник»
When пользователь включает «Тени рельефа»
Then на карте видны и спутник, и hillshade (hillshade поверх спутника)
Scenario: Маршрут OSRM поверх спутника
Given пользователь построил маршрут через OSRM
When пользователь переключает подложку на «Спутник»
Then маршрут остаётся виден поверх спутника
And статистика маршрута сохранена
Scenario: GPX-треки поверх спутника
Given пользователь загрузил GPX-трек
When пользователь переключает подложку на «Спутник»
Then GPX-линии и waypoints остаются видны поверх спутника
AC-05: Сохранение в localStorage
Feature: Persistence выбора подложки
Scenario: Сохранение при переключении
Given активна подложка «Схема»
When пользователь нажимает «Спутник»
Then localStorage['map-base-layer'] === 'satellite'
Scenario: Восстановление после reload
Given localStorage['map-base-layer'] === 'satellite'
When пользователь перезагружает страницу
Then после загрузки карты активна подложка «Спутник»
And кнопка «Спутник» имеет класс .active
AC-06: Восстановление при смене темы
Feature: Подложка переживает смену темы
Scenario: Переключение тёмной/светлой темы в режиме «Спутник»
Given активна подложка «Спутник»
When пользователь переключает тему (тёмная ↔ светлая)
Then после завершения map.setStyle() спутниковый слой восстановлен
And подложка «Спутник» остаётся активной
And все слои поверх (trails, POI, маршрут, GPX) восстановлены
Scenario: Переключение слоёв terrain в режиме «Спутник»
Given активна подложка «Спутник»
When пользователь включает или выключает «Тени рельефа» / «Перепады»
Then подложка «Спутник» остаётся активной
AC-07: Совместимость с режимами тулбара
Feature: Подложка не мешает другим режимам
Scenario: Режим «Маршрут» на спутнике
Given активна подложка «Спутник»
When пользователь активирует режим «Маршрут»
And тапает 2 точки на карте
Then маршрут строится корректно
And линия маршрута видна на спутнике
Scenario: Режим «Разведка» на спутнике
Given активна подложка «Спутник»
When пользователь активирует режим «Разведка» и тапает на карту
Then круг радиуса разведки видим
And статистика разведки отображается
Scenario: Линейка на спутнике
Given активна подложка «Спутник»
When пользователь активирует «Линейка» и расставляет точки
Then линия линейки видна
And расстояние отображается
Scenario: Поиск на спутнике
Given активна подложка «Спутник»
When пользователь нажимает «Поиск» и вводит запрос
Then результаты поиска отображаются
And карта корректно центрируется на найденной точке
AC-08: Производительность
Feature: Скорость переключения
Scenario: Переключение Схема → Спутник
Given активна подложка «Схема» и сеть ≥ 5 Мбит/с
When пользователь нажимает «Спутник»
Then первая спутниковая плитка отображается в течение ≤ 500 мс
Scenario: Переключение Спутник → Схема
Given активна подложка «Спутник» (тайлы уже подгружены)
When пользователь нажимает «Схема»
Then смена визуально мгновенная (≤ 100 мс)
AC-09: Mobile UI
Feature: Переключатель на мобильных устройствах
Scenario: Попап слоёв на мобильном
Given пользователь открыл приложение на мобильном устройстве (виртуальный viewport 375×812)
When пользователь открывает попап слоёв
Then переключатель «Подложка» виден полностью
And обе кнопки нажимаемы (touch target ≥ 34px)
And не перекрывает другие элементы попапа
AC-10: Не ломает существующий функционал
Feature: Регресс-проверка
Scenario: Все режимы работают как в режиме «Схема», так и в «Спутник»
Given пользователь использует приложение
Then режимы Маршрут, Связка, Красивый, Разведка, Линейка, Поиск, Метка, GPX
работают одинаково в обеих подложках
And переключение единиц измерения (км/мили) работает в обеих подложках
And переключение темы работает в обеих подложках