Files
enduro-trails/docs/architecture
claude-bot 4f80c250cf
All checks were successful
CI / lint (push) Successful in 4s
CI / test (push) Successful in 10s
CI / build (push) Successful in 3s
architect(ET): auto-commit from architect run_id=102
2026-06-05 15:27:58 +00:00
..

Архитектура Enduro Trails

Обзор

Веб-приложение для планирования эндуро-маршрутов с визуализацией рельефа.

Компоненты

  • Frontend — MapLibre GL JS, vanilla JS (ES modules)
  • Backend API — FastAPI (Python 3.12), uvicorn
  • Tile Server — статические raster tiles (PNG), раздаются через FastAPI/nginx
  • Routing Engine — OSRM с кастомным эндуро-профилем
  • Database — SQLite + Spatialite (точки интереса, маршруты, публичные GPS-треки)
  • GPS Tracks Pipelinegps-collector (docker-compose service, profiles: [batch]), запускается host cron'ом 12 раза в неделю; собирает публичные GPS-треки с внешних платформ в data/gps_tracks.sqlite (ET-008 / ADR-007)

Слои карты

  • Base map: Схема (OpenStreetMap raster) либо Спутник (Esri World Imagery raster) — переключается в UI (ET-007 / ADR-004)
  • Hillshade (рельеф с тенями)
  • TRI (Terrain Ruggedness Index — сложность рельефа)
  • Hypsometric (высотная раскраска)
  • Trails (маршруты из OSM)

Внешние тайл-провайдеры

Клиент (браузер) обращается напрямую к двум внешним raster-tile сервисам. Сервер mva154 эти тайлы не проксирует и не кэширует.

Провайдер Назначение URL Активация API-ключ
OpenStreetMap Базовый слой «Схема» https://tile.openstreetmap.org/{z}/{x}/{y}.png всегда (default подложка) нет
Esri World Imagery Базовый слой «Спутник» https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x} лениво — только при включении «Спутник» пользователем (ET-007) нет

Атрибуция обоих провайдеров выводится MapLibre автоматически при активном source.

GPS Tracks Pipeline (ET-008)

Серверный офлайн-pipeline сбора публичных GPS-треков. Не часть runtime API, изолирован отдельным docker-compose service'ом и отдельной БД.

Компонент

  • Сервис: gps-collector в docker-compose.yml, profiles: ["batch"], тот же образ что app, не стартует при docker compose up -d.
  • Точка входа: scripts/gps_collect.py (см. src/api/gps_tracks/).
  • Расписание: cron на mva154, Mon + Thu 03:00 UTC; + ежемесячный GC.
  • БД: data/gps_tracks.sqlite (SQLite + Spatialite, отдельный файл от centralfederal.sqlite).

Внешние источники pipeline

Скрейпинг/API только из контейнера gps-collector, при наличии accepted-ADR на источник.

Источник Доступ Лицензия ADR MVP
OSM Public GPS Traces API api.openstreetmap.org/api/0.6/trackpoints ODbL ADR-009 (accepted) да
EnduroRussia.ru публичный JSON API endurorussia.ru/api/tracks публичная, обезличенно (без user) ADR-010 (accepted; активирован в ET-009) да
Wikiloc HTML-парсинг www.wikiloc.com + downloadTrail.do proprietary, некоммерческое использование, обезличенно ADR-012 (accepted; активирован в ET-009) да
ttrails.ru / Тропинки.ру HTML + GPX-ссылки требует review ADR-011 (proposed/blocked) условно

Источник без status: accepted в ADR pipeline'ом пропускается (см. ADR-007 §6 licensing guard).

Клиентский слой публичных треков

Двухрежимная отдача (см. ADR-008):

  • z=8..11 — MVT через GET /api/gps-tracks/tiles/{z}/{x}/{y}.mvt + сервер-LRU.
  • z≥12 — GeoJSON через GET /api/gps-tracks?bbox=...&activity=...&source=....
  • z<8 — слой скрыт (защита от шторма запросов).

Скачивание одного трека из popup карты (ET-011): GET /api/gps-tracks/{track_id}/download — отдаёт GPX 1.1 с правильным Content-Disposition и UTF-8 именем по RFC 5987. Разрешено только для источников с download_allowed: true в config/gps_sources.yaml (MVP: только osm). Cap 200000 точек → 413 Payload Too Large. См. ADR-014 / ADR-015.

Health/observability: GET /api/gps-tracks/health — состояние БД, число треков по источникам, последний прогон.

Деплой

Один Docker Compose на mva154. Nginx проксирует /enduro/ на контейнер.

Клиентские модули (src/web/)

Модуль Описание Work Item
app.js Главный модуль: MapLibre, роутинг, UI, тёмная тема PH-1..PH-6
units.js Централизованный форматтер расстояний (км/мили), localStorage, событие unitchange ET-005
gpx.js GPX 1.1 парсер (DOMParser), рендеринг треков/waypoints, canvas-профиль высот, rebuildMapOverlays() ET-006
gps_tracks.js Слой публичных GPS-треков (MVT + GeoJSON гибрид по zoom), фильтры по активности/источнику, popup с метаданными, halo на спутнике, restorePublicTracksState() ET-008
style.json MapLibre стиль (светлая тема) PH-1/PH-5
style-dark.json MapLibre стиль (тёмная тема) PH-5