24 KiB
24 KiB
type, work_item_id, title, version, status, created_at, updated_at, authors, related
| type | work_item_id | title | version | status | created_at | updated_at | authors | related | ||
|---|---|---|---|---|---|---|---|---|---|---|
| brd | ET-009 | BRD: Новые источники GPS-треков — EnduroRussia и Wikiloc | 1 | draft | 2026-06-01 | 2026-06-01 |
|
|
BRD — ET-009: Новые источники GPS-треков — EnduroRussia и Wikiloc
1. Цель
Расширить пул реальных GPS-треков, видимых пользователю Enduro Trails,
за счёт двух новых источников — endurorussia.ru и wikiloc.com.
Pipeline сбора, БД, API и UI-слой уже построены в ET-008; ET-009
не строит инфраструктуру, а:
- Активирует EnduroRussia.ru как источник в продакшне (parser-код и
ADR-010 уже готовы, но source находится в
gps_sources.yamlкакenabled: false; конфиг ссылается наenduro-russia.ruс дефисом — расхождение с реальным доменомendurorussia.ruбез дефиса требует корректировки). - Включает Wikiloc как новый источник: добавляет запись в
gps_sources.yaml, привязывает к регионам, проверяет parser/lifecycle/ratelimit и активирует. - Гарантирует, что после первого продакшн-прогона в БД
data/gps_tracks.sqliteпоявляются треки с обоих новых источников и они корректно отдаются пользователю через существующие endpoints и UI-фильтры.
ET-009 — «заявить, подключить, доказать что работает», а не новая функциональность.
2. Контекст
- ET-008 разработал и развернул в test:
src/api/gps_tracks/(модели, БД, дедуп, MVT, endpoint, parsers).- Pipeline
scripts/gps_collect.pyс поддержкой нескольких источников. - Конфиги
config/gps_sources.yamlиconfig/gps_regions.yaml. - UI: чекбокс «Публичные треки», sheet фильтров, popup трека, halo-слой на спутнике.
- ADR-009/010/011/012 (licensing OSM / EnduroRussia / ttrails / Wikiloc).
- На момент старта ET-009:
osm—enabled: true, работает в проде.ttrails—enabled: false, в задаче ET-009 не активируется.enduro_russia— parser-код есть, ADR-010accepted, ноgps_sources.yamlсодержитenabled: falseи URLenduro-russia.ru(с дефисом). Реальный домен по бизнес-требованию —endurorussia.ru(без дефиса), это подтверждает и parser-код (src/api/gps_tracks/sources/enduro_russia.pydefaulthttps://endurorussia.ru).wikiloc— parser-код есть, ADR-012accepted, но вgps_sources.yamlотсутствует.
- API EnduroRussia: открытый JSON, без авторизации, 305+ треков по РФ:
GET https://endurorussia.ru/api/tracks?page=N&limit=50GET https://endurorussia.ru/api/tracks/{id}/gpx
- Wikiloc: публичного API нет, доступ только через HTML-парсинг страниц поиска и треков; rate-limit жёсткий — 10 сек между запросами; при 403/429 — graceful-stop.
3. Scope
In scope
| # | Функция |
|---|---|
| F-01 | Исправление gps_sources.yaml: enduro_russia.base_url → https://endurorussia.ru (без дефиса). |
| F-02 | gps_sources.yaml: enduro_russia.enabled → true. |
| F-03 | Верификация ADR-010 (accepted) на момент активации — pipeline-guard должен пропустить source. |
| F-04 | Добавление в gps_sources.yaml записи wikiloc с enabled: true, rate_limit_sec: 10, license_adr: docs/work-items/ET-008/06-adr/ADR-012-wikiloc-licensing.md. |
| F-05 | Обновление config/gps_regions.yaml: tsfo_plus_chuvashia.sources дополняется значением wikiloc (osm уже есть, enduro_russia уже есть). |
| F-06 | Интеграционные тесты на parser enduro_russia.py с фикстурами реальных ответов API: 1 страница списка + 3 GPX-файла + edge cases. |
| F-07 | Интеграционные тесты на parser wikiloc.py с фикстурами реальных HTML-страниц: страница поиска, страница трека, GPX. |
| F-08 | Тесты dedup-merge на пару (osm-трек, enduro_russia-трек) с одной поездкой → одна запись с sources=['osm','enduro_russia']. |
| F-09 | Тесты graceful-stop wikiloc на 403/429: парсер останавливается, не падает, pipeline_runs.status='partial' или 'rate_limited'. |
| F-10 | Health-эндпоинт /api/gps-tracks/health после прогона показывает tracks_by_source с ненулевыми значениями для enduro_russia и wikiloc. |
| F-11 | UI: фильтр «Источник» в #sheet-gps-filters динамически отображает 3 чекбокса — OSM, EnduroRussia, Wikiloc — по данным API. |
| F-12 | Атрибуция: в правом нижнем углу карты MapLibre Attribution содержит «EnduroRussia.ru» и «© Wikiloc contributors» при наличии треков из этих источников. |
| F-13 | Цветовая палитра по источнику в style.json/style-dark.json содержит цвета для enduro_russia и wikiloc (а не только OSM). |
| F-14 | Первый продакшн-прогон pipeline на test-сервере для региона tsfo_plus_chuvashia: собирает ≥ 200 треков с EnduroRussia и пробует Wikiloc (любое ненулевое количество приемлемо ввиду rate-limit). |
Out of scope
- Активация ttrails (Тропинки.ру) — отдельный work item.
- Изменение схемы БД — структура
gps_tracks.sqliteостаётся как в ET-008. - Новые поля метаданных — что собираем по каждому треку, определено ET-008.
- Wikiloc Premium / OAuth — пользуемся только публичными HTML.
- Расширение алгоритма дедупликации — берём как есть из ET-008.
- Запуск автоматического cron — расписание cron включается отдельным task'ом
после успешного ручного прогона (см. F-14). ET-009 ограничивается ручным
python scripts/gps_collect.py --region tsfo_plus_chuvashia. - Удаление stale-треков (GC) — отдельный концерн pipeline, не активируется в ET-009.
- Расширение на новые регионы — Северный Кавказ остаётся
enabled: false.
4. Источники — детальное описание
4.1 EnduroRussia.ru
| Параметр | Значение |
|---|---|
| Тип доступа | Публичный JSON API без авторизации |
| Базовый URL | https://endurorussia.ru |
| Endpoint list | GET /api/tracks?page=<N>&limit=50 → {items: [{id, name, difficulty, …}], total} |
| Endpoint GPX | GET /api/tracks/{id}/gpx → GPX 1.1 XML |
| Объём | ≥ 305 публичных треков (на момент составления BRD) |
| География | Россия, преимущественно ЦФО, эндуро-категория |
| Активность | enduro, мото, hard, soft, тур → MAPPING → enduro/moto |
| ToS | Публичные треки; нет явного запрета на программный доступ; см. ADR-010 |
| robots.txt | Не запрещает /api/ для программного доступа с явным UA (см. ADR-010 §2) |
| Attribution | «EnduroRussia.ru» в строке атрибуции карты |
| Rate-limit | 5 сек между запросами (rate_limit_sec: 5) |
| save_user_field | false — автор не сохраняется (ADR-010 §3) |
4.2 Wikiloc
| Параметр | Значение |
|---|---|
| Тип доступа | Парсинг публичных HTML-страниц (API недоступно) |
| Базовый URL | https://www.wikiloc.com |
| Endpoint поиска | GET /wikiloc/find.do?act=<code>&sw=<lat,lon>&ne=<lat,lon>&page=<N> → HTML с <a href="/trails/…/<id>"> |
| Endpoint трека | GET /trails/<slug>/<id> → HTML c ссылкой на GPX |
| Endpoint GPX | GET /wikiloc/downloadTrail.do?id=<id> → GPX XML |
| Активности (act код) | motorcycle=19, enduro=19, mtb=3 |
| ToS | Треки публичные; ADR-012 фиксирует условия некоммерческого использования |
| robots.txt | Не запрещает страницы треков с явным UA (см. ADR-012 §2) |
| Attribution | «© Wikiloc contributors» в строке атрибуции карты |
| Rate-limit | 10 сек между запросами (rate_limit_sec: 10) — жёстко |
| Graceful-stop | При HTTP 403/429 — немедленный stop без ретраев, статус прогона rate_limited или partial |
| Хрупкость | HTML-парсер. При смене структуры — парсер вернёт 0 треков без краша. См. риск R-1. |
| save_user_field | false — автор не сохраняется (ADR-012 §5) |
4.3 Контроль licensing
Pipeline-guard _check_license_adr() уже реализован (см.
scripts/gps_collect.py строки 37–73): при enabled: true source
загружается только если license_adr.status == 'accepted'. Перед
активацией ET-009 обязательно перечитать ADR-010 и ADR-012 и
убедиться, что обе ADR имеют status: accepted в YAML front-matter.
Если на момент работы ET-009 одна из ADR оказалась в другом статусе —
работу остановить, эскалировать архитектору.
5. Метрики успеха
| Метрика | Критерий |
|---|---|
| Конфиг корректен | gps_sources.yaml содержит запись enduro_russia с base_url: https://endurorussia.ru (без дефиса) и enabled: true. |
| Wikiloc заведён | gps_sources.yaml содержит запись wikiloc с enabled: true, rate_limit_sec: 10, license_adr: …ADR-012…. |
| Регион подписан | gps_regions.yaml для tsfo_plus_chuvashia содержит wikiloc в sources. enduro_russia уже подписан. |
| Pipeline-guard работает | При status: proposed в ADR-010 (искусственно) — pipeline пропускает source с pipeline_runs.status='skipped_license'. |
| Покрытие EnduroRussia | После прогона: tracks_by_source.enduro_russia ≥ 200 (исходим из ≥ 305 публичных треков с учётом фильтра bbox региона). |
| Покрытие Wikiloc | После прогона: tracks_by_source.wikiloc ≥ 1 (rate-limit 10 сек × ≥ 3 запроса на трек делает сбор медленным; любое ненулевое значение приемлемо для validation того, что парсер работает end-to-end). |
| Дедупликация работает | Среди ≥ 200 треков EnduroRussia: записи с sources=['osm','enduro_russia'] или sources=['enduro_russia','wikiloc'] существуют (хотя бы 1 в выборке). |
| Graceful-stop | Mock-эмуляция HTTP 403 / 429 от Wikiloc в integration-тесте → pipeline не падает, статус прогона rate_limited или partial. |
| Атрибуция | В правом нижнем углу карты после включения слоя видны строки «EnduroRussia.ru» и «© Wikiloc contributors». |
| UI-фильтр источников | В #sheet-gps-filters после первого прогона видны минимум 3 чекбокса: OSM / EnduroRussia / Wikiloc; снятие галки с источника убирает соответствующие линии. |
| Производительность не деградировала | /api/gps-tracks?bbox=… p95 не вырос относительно ET-008 baseline (≤ 300 мс на z ≥ 10, ≤ 500 треков в bbox). |
| Чистый health | /api/gps-tracks/health возвращает last_run_status='ok' или 'partial' (не 'error'), errors_count == 0 или ≤ 5%. |
6. Риски
| # | Риск | Вероятность | Влияние | Митигация |
|---|---|---|---|---|
| R-1 | Wikiloc меняет HTML → парсер возвращает 0 треков | Высокая | Среднее | Парсер уже спроектирован graceful: возвращает 0, не падает. Health-эндпоинт показывает 0 в tracks_by_source.wikiloc → видимый сигнал. |
| R-2 | Wikiloc банит IP mva154 | Средняя | Высокое | Rate-limit 10 сек + UA с контактом + graceful-stop на 403/429. После активации мониторим первые 3 прогона; при систематических 403 — enabled: false и эскалация. |
| R-3 | EnduroRussia API меняет схему ответа | Низкая | Среднее | Parser проверяет наличие ключевых полей (items, id); при KeyError — tracks_new=0, статус error. Контрактный тест на JSON. |
| R-4 | Расхождение конфига enduro-russia.ru vs реального endurorussia.ru |
Случилось | Высокое | F-01: исправляем gps_sources.yaml сразу. Регрессионный тест: parser отвечает на https://endurorussia.ru (не на enduro-russia.ru). |
| R-5 | EnduroRussia треки уже содержат creator=Wikiloc в GPX → массовые дубли при включении Wikiloc |
Высокая | Среднее | ADR-012 §4 явно фиксирует. Тест dedup-merge: одна и та же поездка из enduro_russia и wikiloc → одна запись, sources объединён. |
| R-6 | Cron первого прогона превышает окно (≥ 6 часов из-за rate-limit Wikiloc 10 сек × 305 EnduroRussia × 3 запроса/трек) | Средняя | Низкое | EnduroRussia: 305 треков × 5 сек ≈ 25 минут — окей. Wikiloc: per-source максимум max_tracks_per_run: 50 в первом прогоне (cap в конфиге). |
| R-7 | UI-фильтр «Источник» не подхватывает новые ID | Низкая | Среднее | UI динамически строит фильтр из API (/api/gps-tracks?stats=true или из выгрузки) — изменений в коде клиента не требуется. Проверка через UI-тест TC-UI-04 (расширен в ET-009). |
| R-8 | Цветовая палитра в стилях карты не содержит enduro_russia/wikiloc → линии серым |
Высокая | Низкое | F-13: добавить цвета в style.json/style-dark.json (match-expression line-color по get source). |
| R-9 | Дамп БД (если есть резервная копия с старым enduro-russia.ru URL в external_url) — orphan-записи |
Низкая | Низкое | До первого прогона новой версии: оператор может выполнить UPDATE tracks SET external_urls_json = REPLACE(external_urls_json, 'enduro-russia.ru', 'endurorussia.ru'). Опционально, в 14-deploy-log.md. |
| R-10 | ADR-010 / ADR-012 регрессировали в proposed |
Низкая | Высокое | F-03: pre-check на момент активации. Если ADR не accepted — задача останавливается, эскалация архитектору. |
7. Зависимости
Backend
src/api/gps_tracks/sources/enduro_russia.py— код существует (ET-008). Изменения возможны только при выявлении бага во время тестов F-06/F-08.src/api/gps_tracks/sources/wikiloc.py— код существует (ET-008). Изменения возможны только при выявлении бага во время F-07/F-09.scripts/gps_collect.py— без изменений, используется как есть.src/api/gps_tracks/db.py,dedup.py,endpoint.py,mvt.py— без изменений.
Конфиги
config/gps_sources.yaml— изменение F-01..F-04.config/gps_regions.yaml— изменение F-05.
Фронтенд
src/web/style.jsonиsrc/web/style-dark.json— F-13: расширить match-expressionline-colorдля слояgps-tracks-layer.src/web/gps_tracks.js(или модуль ET-008) — без изменений кода при условии, что фильтр-список источников строится из ответа API динамически. Если в ET-008 список захардкожен — добавитьenduro_russiaиwikilocв маппинг лейблов источников и палитру. Это будет уточнено в TRZ §3.
Тестовые фикстуры
tests/fixtures/gps-tracks/enduro-russia-api-tracks-page1.json— реальный snapshot ответа/api/tracks?page=0.tests/fixtures/gps-tracks/enduro-russia-track-{1,2,3}.gpx— три GPX.tests/fixtures/gps-tracks/wikiloc-search-page1.html— HTML страницы поиска.tests/fixtures/gps-tracks/wikiloc-trail-page.html— HTML страницы трека.tests/fixtures/gps-tracks/wikiloc-track.gpx— GPX из Wikiloc.tests/fixtures/gps-tracks/wikiloc-rate-limited.html— заглушка для 429-сценария.
Инфра
- mva154: исходящие HTTPS к
endurorussia.ruиwww.wikiloc.com(уже разрешены DevOps-политикой). - Размер
data/gps_tracks.sqliteне превысит 100 MB после первого прогона (200 треков × ~50 KB средний размер геометрии).
Документация
- BRD/TRZ/AC/Test-plan этого work item.
- Опциональный ADR
06-adr/ADR-013-domain-fix-enduro-russia.md— если расхождение конфиг/реальность сочтено архитектурным решением, а не баг-фиксом. По умолчанию — это bugfix, ADR не нужен. - Дополнения к
14-deploy-log.mdпосле первого прогона: команда запуска,tracks_by_source, длительность.
Связи с другими work items
- ET-008 — родительская задача; ET-009 расширяет её. Никаких изменений в артефактах ET-008 не делаем.
- ttrails — отдельный work item на активацию третьего источника (после ET-009).
- PH-3 Smart Route — растущая база публичных треков может в будущем улучшить smart-route. Не в scope.