Реализация ET-011: кнопка «Скачать GPX» в popup публичного GPS-трека и
новый эндпоинт GET /api/gps-tracks/{track_id}/download (GPX 1.1 +
Content-Disposition с UTF-8 именем по RFC 5987). Реэкспорт защищён
per-source флагом `download_allowed` в `config/gps_sources.yaml`
(default-deny, MVP whitelist = `osm`).
Backend:
- `src/api/gps_tracks/export.py` — чистый stdlib-builder GPX 1.1
(`build_gpx`) + санитизация имени файла (`safe_filename`, RFC 5987).
- `src/api/gps_tracks/endpoint.py` — новый route с проверками
400 / 403 / 404 / 413; cap 200 000 точек (REQ-NF-02).
- `src/api/gps_tracks/config.py` — `load_download_allowed_sources()`
читает YAML, default-deny при отсутствии поля; fallback на `{"osm"}`
при отсутствии конфига.
- `src/api/main.py` — пробрасывает `GPS_SOURCES_CONFIG_PATH` в router.
Frontend:
- `src/web/gps_tracks.js` — кнопка в `_renderTrackPopupHtml`,
обработчик `_downloadPublicTrack` (fetch + Blob + a.download — тот же
паттерн, что в `app.js::downloadGPX`, R-1 митигирован), парсер
`_parseFilenameFromCD` для RFC 5987, маппинг ошибок
`_handleDownloadError` (403/404/413/5xx → showToast).
- `src/web/app.css` — стиль кнопки, 32×32 CSS px (REQ-NF-04).
Тесты:
- 13 unit для GPX-builder (UT-01/02/03/05; XSD-валидация против
`tests/fixtures/gpx-1.1/gpx.xsd`).
- 10 unit для `safe_filename` (UT-04).
- 11 integration для download-эндпоинта (IT-01..08 +
ANY-rule license check + default-deny без конфига).
ADR-014 (gpx-download-endpoint), ADR-015 (source-redistribution-policy).
Refs: ET-011
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
68 lines
4.3 KiB
Markdown
68 lines
4.3 KiB
Markdown
# Changelog
|
||
|
||
All notable changes to this project will be documented in this file.
|
||
Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
|
||
|
||
## [Unreleased]
|
||
|
||
### Added
|
||
- ET-011: Скачивание GPX из popup публичного трека. Новый эндпоинт
|
||
`GET /api/gps-tracks/{track_id}/download` собирает GPX 1.1 из геометрии
|
||
трека и отдаёт с `Content-Disposition: attachment` (UTF-8 имя файла по
|
||
RFC 5987). В popup на карте появилась кнопка «Скачать GPX» (32×32 CSS px,
|
||
mobile-friendly). Реализация: новый модуль `src/api/gps_tracks/export.py`
|
||
(`build_gpx`, `safe_filename`); расширение `config/gps_sources.yaml`
|
||
per-source флагом `download_allowed` (default-deny; MVP whitelist = `osm`,
|
||
см. ADR-015); helper `load_download_allowed_sources` в `config.py`.
|
||
Тесты: 13 unit GPX-builder + 10 unit filename + 11 integration download.
|
||
ADR-014, ADR-015. Refs: ET-011.
|
||
|
||
## [v0.0.2] — 2026-06-02
|
||
|
||
### Added
|
||
- ET-009: Активация GPS-источников EnduroRussia и Wikiloc — `config/gps_sources.yaml`
|
||
включает оба источника (`enabled: true`), для Wikiloc добавлен soft-cap
|
||
`max_tracks_per_run: 50` и activity-фильтр; `config/gps_regions.yaml` подписывает
|
||
`wikiloc` на регион `tsfo_plus_chuvashia`. Парсер `wikiloc.py` извлекает время из
|
||
GPX-metadata (для корректной дедупликации) и поддерживает `max_tracks_per_run`
|
||
cap. UI: цвет `wikiloc`, чекбокс источника, динамическая атрибуция
|
||
(`GPS_SOURCE_ATTRIBUTIONS`) подтягивается с `/api/gps-tracks/health`.
|
||
Тесты: 10 unit ER + 10 unit WL + 5 integration + 2 contract (nightly only).
|
||
PR #16, tag v0.0.2.
|
||
|
||
### Fixed
|
||
- ET-009: исправлен URL `enduro_russia` в `config/gps_sources.yaml`
|
||
(`https://enduro-russia.ru` → `https://endurorussia.ru`, без дефиса).
|
||
|
||
## [v0.0.1] — 2026-06-01
|
||
|
||
### Added
|
||
- ET-008: GPS-треки с публичных платформ на карте — новый модуль `src/web/gps_tracks.js`
|
||
с отображением публичных GPS-треков (OSM Traces, enduro_russia, ttrails) в виде
|
||
MVT-тайлов (z 8–11) и GeoJSON (z ≥ 12); фильтрация по активности и источнику,
|
||
попап с мета-данными трека, z-order ниже личных GPX-треков (AC-10).
|
||
Backend: FastAPI-пакет `src/api/gps_tracks/` (endpoint, MVT, LRU-кэш, дедупликация),
|
||
миграция `migrations/gps_tracks_001_init.sql`, pipeline-скрипт `scripts/gps_collect.py`,
|
||
Docker-сервис `gps-collector`. PR #12, tag v0.0.1.
|
||
|
||
## [Unreleased]
|
||
|
||
- Initial project structure
|
||
- CLAUDE.md project passport
|
||
- Agent system prompts (architect, developer, reviewer, tester, deployer)
|
||
- CI pipeline (Gitea Actions)
|
||
- Docker configuration
|
||
- ET-002: чекбокс «POI» в попапе рельефа — показ/скрытие маркеров POI
|
||
с сохранением состояния в localStorage (ключ `poi-visible`)
|
||
- ET-005: переключатель единиц измерения расстояний (км/мили) в попапе
|
||
рельефа — новый модуль `src/web/units.js` с централизованным
|
||
форматтером `Units.formatDistance()`; выбор сохраняется в localStorage
|
||
(ключ `distance_unit`), пересчёт всех видимых расстояний выполняется
|
||
единым оркестратором по событию `unitchange`
|
||
- ET-006: загрузка и визуализация GPX-треков — новый модуль
|
||
`src/web/gpx.js` с клиентским парсингом GPX 1.1 (`DOMParser`,
|
||
чанковая конвертация), отрисовкой треков и waypoints на карте,
|
||
панелью `#sheet-gpx` со списком треков, статистикой и canvas-профилем
|
||
высот; GPX-слои восстанавливаются после смены стиля карты через
|
||
`rebuildMapOverlays()`. Данные треков хранятся только в памяти сессии
|