Files
enduro-trails/docs/architecture/README.md
claude-bot bd8f60879e
All checks were successful
CI / lint (push) Successful in 3s
CI / lint (pull_request) Successful in 3s
CI / test (push) Successful in 6s
CI / build (push) Successful in 2s
CI / test (pull_request) Successful in 5s
CI / build (pull_request) Successful in 1s
developer(ET): auto-commit from developer run_id=40
2026-06-01 12:17:09 +00:00

86 lines
5.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Архитектура 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 Pipeline** — `gps-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 | HTML + GPX-ссылки | требует review | ADR-010 (proposed/blocked) | условно |
| 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 — слой скрыт (защита от шторма запросов).
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 |