7.0 KiB
7.0 KiB
type, work_item_id, title, version, status, created_at, updated_at, authors
| type | work_item_id | title | version | status | created_at | updated_at | authors | |
|---|---|---|---|---|---|---|---|---|
| brd | ET-008 | BRD: GPS-треки с публичных платформ на карте | 1 | draft | 2026-06-01 | 2026-06-01 |
|
BRD — ET-008: GPS-треки с публичных платформ на карте
1. Цель
Дать пользователю возможность увидеть на карте Enduro Trails GPS-треки с публичных источников без скачивания файлов вручную: либо вставив прямую ссылку на GPX, либо найдя чужие публичные треки в видимой области карты (через OSM Public GPS Traces).
2. Контекст
- ET-006 реализовал клиентский GPX-стек: парсер, модель
window.gpxTracks, sheet#sheet-gpx, статистика, профиль высот, переживаниеmap.setStyle()черезrebuildGpxOverlays(). Источник данных — только локальный файл пользователя. - Roadmap-фаза PH-3 «Smart Route» включает работу с GPX (импорт/экспорт).
- В стеке нет пользовательских аккаунтов и БД пользователей. Платформы с обязательным OAuth (Strava, Komoot) поэтому вне scope текущей итерации.
- Браузер не может тянуть GPX напрямую с большинства публичных платформ из-за CORS. OSM API не разрешает кросс-доменные запросы → прокси через FastAPI обязателен.
- OSM Public GPS Traces — открытый бесплатный источник публичных GPS-треков, формат GPX, есть bbox-поиск, нет авторизации для чтения.
3. Scope
In scope
| # | Функция |
|---|---|
| F-01 | Поле ввода URL прямой ссылки на GPX в #sheet-gpx |
| F-02 | Импорт GPX по URL через прокси-эндпоинт /api/gpx/fetch |
| F-03 | Кнопка «Найти публичные треки» в #sheet-gpx — поиск в bbox видимой области карты |
| F-04 | Прокси-эндпоинт /api/gpx/osm/traces для OSM Public GPS Traces |
| F-05 | Список найденных OSM-треков с метаданными (длина, точек, описание, автор) |
| F-06 | Импорт выбранного OSM-трека одним тапом |
| F-07 | Серверный LRU-кэш ответов внешних API (TTL 24 ч, in-memory) |
| F-08 | Источник трека (URL / OSM trace id + ссылка) виден в карточке трека |
| F-09 | Лимит размера загруженного по URL файла: 50 МБ (как ET-006) |
| F-10 | Внятные сообщения об ошибках (CORS-фейл, 404, лимит API, битый GPX) |
| F-11 | Импортированные треки попадают в общий список window.gpxTracks и неотличимы от локальных по поведению |
Out of scope
- OAuth-интеграции (Strava, Komoot)
- Платный API Wikiloc
- Поиск треков глобально (без bbox)
- Сохранение треков в БД между сессиями
- Подписки на пользователей других платформ
- Загрузка собственных треков на публичные платформы
4. Метрики успеха
| Метрика | Критерий |
|---|---|
| URL-импорт | Прямая ссылка на GPX до 50 МБ загружается за ≤ 5 сек на средней сети |
| OSM-поиск bbox | Запрос видимой области возвращает результат за ≤ 3 сек (с кэшем — мгновенно) |
| Точность | OSM-трек после импорта визуально совпадает с тем же треком из osm.org |
| Кэш | Повторный запрос той же области/URL в течение 24 ч — без обращения к внешнему API |
| UX | Все ошибки (CORS, 404, лимит, формат) — внятные toast-уведомления, не падение |
| Совместимость с ET-006 | Локальные и удалённые треки в одном списке, поведение идентично |
| Сохранение при смене стиля | Импортированные треки переживают переключение тёмной темы и слоёв рельефа |
5. Риски
| Риск | Вероятность | Влияние | Митигация |
|---|---|---|---|
| OSM API rate limit (1 запрос / IP / сек) | Высокая | Среднее | Серверный кэш по bbox + дебаунс на клиенте |
| URL-прокси превращается в open redirect / SSRF | Средняя | Высокое | Whitelist схем (http/https), блок приватных IP, лимит размера, таймаут |
| Большие OSM-страницы (1000+ треков) → длинный список | Средняя | Низкое | Пагинация: показывать первые N, кнопка «ещё» |
| GPX по URL не существует / 404 | Высокая | Низкое | Toast с понятной ошибкой |
Content-Type не application/gpx+xml |
Высокая | Низкое | Проверять по содержимому (DOMParser), не по заголовкам |
| Чужой публичный трек содержит вредоносный XML / XXE | Низкая | Высокое | DOMParser в браузере (XXE отключён), на бэкенде — defusedxml |
| Внешний API внезапно недоступен | Средняя | Низкое | Graceful degradation: показать сообщение, не блокировать другие функции |
6. Зависимости
- ET-006 — модель
window.gpxTracks, рендеринг, sheet#sheet-gpx, парсерparseGpx(). Без ET-006 эта задача не имеет смысла. - Backend (FastAPI) — новые эндпоинты
/api/gpx/fetch,/api/gpx/osm/traces, добавлениеhttpx(уже есть) иdefusedxml(новая зависимость, опционально — для server-side валидации). - Внешние сервисы:
https://api.openstreetmap.org/api/0.6/trackpoints— публичный API OSM, ограничения: 1 req/sec/IP, 5000 точек/страница, до 5 страниц.- Произвольные HTTPS-хосты (для URL-импорта) — без SLA, fail-soft.