--- type: data-requirements work_item_id: ET-007 title: "Требования к данным — ET-007: Спутниковая карта (Схема / Спутник)" version: 1 status: approved created_at: 2026-05-31 authors: - "agent:architect" --- # Требования к данным — ET-007 ## 1. Резюме ET-007 не вводит и не изменяет ни одной серверной структуры данных. Единственные «данные» фичи на стороне приложения — пользовательский UI-выбор подложки в `localStorage`. На стороне внешнего источника — бесконтекстные растровые плитки PNG/JPEG, потребляемые браузером. ## 2. Серверные данные | Аспект | Требование | |--------|------------| | Изменения схемы SQLite / Spatialite | Нет | | Новые таблицы / колонки / индексы | Нет | | Миграции (`migrations/`) | Нет | | Изменения контракта API `/api/*` | Нет | | Серверное логирование выбора подложки | Нет — выбор остаётся в браузере | ## 3. Внешние входные данные (спутниковые тайлы) | Параметр | Значение | |----------|----------| | Источник | Esri World Imagery (см. ADR-004 §1) | | URL-шаблон | `https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}` | | Протокол | HTTPS, без авторизации | | Формат | растровый PNG / JPEG, 256 × 256 px | | Размер плитки | ≈ 30–80 КБ | | Диапазон z | 0 … 19 | | Привязка | Web Mercator (EPSG:3857) — совместима с MapLibre по умолчанию | | Атрибуция (обязательна) | `"Source: Esri, Maxar, Earthstar Geographics, and the GIS User Community"` | | Содержимое запроса | `{z}`, `{y}`, `{x}` — обезличенные координаты тайла; больше ничего не передаётся | | Cookies / заголовки авторизации | Не отправляются | Изменение MapLibre source при будущей смене провайдера локализовано одним объектом source-spec в `applyBaseLayer()` — это единственная точка системы, знающая URL Esri (см. ADR-004 §1 «точка расширения»). ## 4. Клиентское хранилище | Параметр | Значение | |----------|----------| | Механизм | `localStorage` | | Ключ | `map-base-layer` | | Допустимые значения | `"schematic"` \| `"satellite"` | | Значение по умолчанию | `"schematic"` (при отсутствии ключа или некорректном значении) | | Объём полезной нагрузки | ≤ 16 байт на браузер | | Запись | в `onBaseLayerToggle(base)` при изменении выбора | | Чтение | в `restoreBaseLayerState()` — при старте приложения и в каждом вызове `rebuildMapOverlays()` (после `map.setStyle()`) | | Миграция со старых значений | Не требуется — ключ новый, конфликта нет | Имя ключа `map-base-layer` соответствует сложившейся в проекте конвенции UI-настроек в `localStorage` (`enduro-theme-mode`, `distance_unit`, `terrain-*`, `trails-*`, `poi-visible`, `MARKERS_KEY`). Префиксации проектом не предусмотрено. ## 5. Внутреннее состояние модуля Дополнительные неперсистентные данные, удерживаемые в памяти браузера в течение сессии: | Поле | Тип | Назначение | |------|-----|------------| | текущий базовый слой | `'schematic' \| 'satellite'` | проекция `localStorage['map-base-layer']` | | baseline-значения paint POI (text-halo, circle-stroke) | объекты per-layer | референсы для возврата с «Спутник» на «Схему» | | baseline-значения `background-color` для тёмной/светлой темы | две строковые константы | `#f0ede6` (light), `#1a1a1a` (dark) — задублированы из `style*.json`, см. ADR-004 §6 | | флаг «satellite source уже добавлен в стиль» | bool | оптимизация: при повторном входе в «Спутник» в той же сессии стиля не добавляем повторно | baseline POI-значения и `background-color` — единственные **задублированные** значения между `style*.json` и `app.js`. Их рассинхрон ловится UI-тестами AC-04 и AC-06. ## 6. Halo-слои в `style.json` В обоих `src/web/style.json` и `src/web/style-dark.json` добавляются парные «underlay»-слои halo для линий грунтовок/троп, например: | Базовый слой | Halo-слой | Назначение | |--------------|-----------|------------| | `trails-grade1` | `trails-grade1-halo-satellite` | широкая полупрозрачная белая обводка под основной линией | | `trails-grade2` | `trails-grade2-halo-satellite` | то же | | ... | ... | для каждой grade и для paths/bridleway | | `paths-bridleway` | `paths-bridleway-halo-satellite` | то же | Параметры halo-слоёв (ширина, цвет, opacity) — на этапе разработки; дизайн уточняется визуальной проверкой на тёмных снимках. У всех halo-слоёв `layout.visibility = "none"` по умолчанию; включаются в `applyBaseLayer('satellite')` через `setLayoutProperty`. Точные численные значения halo — данные дизайна, не данные домена; их изменение не требует миграции пользовательского состояния. ## 7. Персональные данные | Канал | PII | |-------|-----| | `localStorage['map-base-layer']` | нет (обезличенный UI-флаг) | | Запросы к `tile.openstreetmap.org` (уже существуют) | IP пользователя становится виден OSM при использовании «Схемы» | | Запросы к `server.arcgisonline.com` (новые) | IP пользователя становится виден Esri **только** при активном режиме «Спутник» (лениво — см. ADR-004 §3) | | Передача координат поездок / маршрутов на сторонние сервисы | Нет — координаты в URL не передаются, передаётся только `{z}/{y}/{x}` тайл-сетки | Это **не регрессия** относительно текущего состояния (OSM-tile уже работает на тех же условиях), но — расширение списка третьих сторон, к которым обращается клиент. Пользователи, никогда не включающие «Спутник», ни одного запроса в Esri не отправляют — это прямое следствие ленивого создания source (ADR-004 §3). См. также `10-tech-risks.md`, R-3. Серверных обязательств по хранению / удержанию / удалению PII ET-007 **не порождает** — на mva154 никаких новых данных не оседает. ## 8. Резервное копирование и ретенция Не применимо — серверных данных у ET-007 нет. Клиентский `localStorage['map-base-layer']` не подлежит резервному копированию (пользовательская UI-настройка, утрата которой безболезненна). ## 9. Вывод Серверная модель данных, схемы и контракты API ET-007 **не затрагивает**. Единственное персистентное данное — обезличенный клиентский флаг `localStorage['map-base-layer']` (≤ 16 байт). Внешний источник предоставляет публичные растровые тайлы; никакие данные пользователя в запросах к нему не передаются помимо штатной для HTTP-клиента информации (IP, User-Agent).