Files
enduro-trails/CHANGELOG.md
claude-bot eea6c846c2
Some checks failed
CI / lint (push) Failing after 5s
CI / test (push) Failing after 6s
CI / build (push) Has been skipped
CI / lint (pull_request) Failing after 4s
CI / test (pull_request) Failing after 5s
CI / build (pull_request) Has been skipped
feat(gps-tracks): GPX download from public track popup
Реализация 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>
2026-06-03 20:59:53 +00:00

68 lines
4.3 KiB
Markdown
Raw 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.
# 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 811) и 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()`. Данные треков хранятся только в памяти сессии