99 lines
7.0 KiB
Markdown
99 lines
7.0 KiB
Markdown
---
|
||
type: brd
|
||
work_item_id: ET-008
|
||
title: "BRD: GPS-треки с публичных платформ на карте"
|
||
version: 1
|
||
status: draft
|
||
created_at: 2026-06-01
|
||
updated_at: 2026-06-01
|
||
authors:
|
||
- "agent:analyst"
|
||
---
|
||
|
||
# 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.
|