Files
enduro-trails/CHANGELOG.md
claude-bot 6a28ed8e4d
All checks were successful
CI / lint (pull_request) Successful in 4s
CI / test (pull_request) Successful in 11s
CI / build (pull_request) Successful in 2s
deploy(ET-015): tag v0.0.7 + deploy log (SUCCESS)
Деплой ET-015 (фикс контейнерного healthcheck) на test прошёл успешно:
- Merge PR #30 → main (HTTP 200)
- Tag v0.0.7 запушен
- Deploy hook RC=0 (SSH slin@127.0.0.1)
- Healthcheck PASS (HTTP 200 на /enduro/, 1-я попытка)
- Smoke PASS (/, style.json, app.js, app.css на test)

Артефакты:
- docs/work-items/ET-015/14-deploy-log.md — deploy_status: SUCCESS
- CHANGELOG.md — раздел [v0.0.7] — 2026-06-05
2026-06-05 15:42:56 +00:00

173 lines
12 KiB
Markdown
Raw Permalink 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]
## [v0.0.7] — 2026-06-05
### Fixed
- ET-015 (deployed v0.0.7, PR #30): `docker-compose.yml` healthcheck сервиса `app` переведён с `curl -f`
(отсутствует в базовом `python:3.12-slim`) на python one-liner через
`urllib.request` из stdlib — без изменений `Dockerfile` и `src/api/main.py`,
без ребилда образа (достаточно `docker compose up -d app`). Внутренний
`urlopen(timeout=3)` меньше внешнего `healthcheck.timeout: 5s` (AC-07);
добавлен `start_period: 20s` для смягчения окна холодного старта uvicorn.
Контракт `/api/health` сохранён (HTTP 200 + JSON). Покрытие: 12 static-
тестов (`tests/static/test_healthcheck_compose.py`) + 6 unit-тестов
(`tests/unit/test_healthcheck_oneliner.py`, исполняют ровно ту же
one-liner-команду против мок-сервера). ADR-020. Refs: ET-015.
`fix(infra): use python urllib for container healthcheck (ET-015)`
### Changed
- ET-012: Слой публичных GPS-треков теперь виден с зума z=5 (раньше — с z=8).
Калибровка существующей tier-структуры `build_gps_mvt`/`_simplify_coords`
(ADR-016): для z≤5 фильтр `min_length=10 км`, `limit=1500`; для z=6 —
`5 км`/`2000`; для z=7 — без изменений (`2 км`/`3000`). DP-tolerance
расширен парой стопов: z=6 → 0.018° (~2 км), z≤5 → 0.04° (~4 км).
На клиенте константа `GPS_TRACKS_MIN_ZOOM` понижена до 5;
`line-width`/halo-stops в MapLibre получили stop на z=5 (0.8/1.8 px),
hint обновлён с «Зум 8+» на «Зум 5+». Контракт API
`/api/gps-tracks/tiles/{z}/{x}/{y}.mvt` не изменился (REQ-F-15);
z≥8 не затронут (регрессия). Тесты: 18 unit zoom-tier+simplify,
9 integration endpoint z5-z7, 2 perf (PERF-Z5-01/02; avg ~64 мс,
p95 ~89 мс при 500 треках — ниже бюджета 200 мс/500 мс по M-6).
*(Код уехал на прод в составе v0.0.5; отдельный deploy-log ET-012
не закрыт — см. ET-013/14-deploy-log.md, раздел «Что фактически
уехало в v0.0.5».)*
Refs: ET-012.
## [v0.0.6] — 2026-06-04
> Деплой задеплоен на test (https://openclaw.mva154.duckdns.org/enduro/).
> Healthcheck + smoke PASS. См. `docs/work-items/ET-014/14-deploy-log.md`.
### Fixed
- ET-014: Фикс UX-конфликта `terrain-popup ↔ bottom-sheet` на mobile.
При открытии любого bottom-sheet (route-details / settings / layers /
search / track-details) активный `terrain-popup` (hillshade / TRI /
hypso info) теперь корректно закрывается через `popup.remove()`,
а не остаётся висеть поверх sheet, перехватывая клики (ADR-019).
Поведение действует только при `window.innerWidth ≤ 768` (mobile);
на desktop popup сохраняется (AC-01..AC-08, REQ-F-1..F-8).
Файлы: `src/web/app.js` (+17 строк, новый блок «sheet-popup yield»
с обработчиком события `sheet:open`). Покрытие: 16 unit-тестов
(`tests/unit/sheet_popup.test.js` — 11 кейсов поведения + 5 boundary;
`tests/unit/test_sheet_popup.py` — 4 архитектурных invariants
ADR-019). API/БД/тайлы не затронуты. Refs: ET-014.
## [v0.0.5] — 2026-06-04
> Деплой задеплоен на test (https://openclaw.mva154.duckdns.org/enduro/).
> Healthcheck + smoke PASS. См. `docs/work-items/ET-013/14-deploy-log.md`.
### Added
- ET-013: Zoom-aware paint для terrain-слоёв `hillshade` и `tri`
(Terrain Ruggedness Index) на z9-z11. UI-минзум `hillshade` понижен
с 10 до 9; raster-paint обоих слоёв переведён в zoom-aware форму через
MapLibre `interpolate`. На z9-z11 — пик `raster-opacity`/`raster-contrast`
(видимость рельефа сопоставима с z8); на z12-z14 — возврат к исходным
значениям (регрессия по AC-10). TRI на z8 сохранил opacity 0.70
(регрессия по AC-06), пик 0.80-0.85 на z9-z11. Файлы: `src/web/app.js`
(константы `HILLSHADE_PAINT` / `TRI_PAINT`, `applyTerrainLayer`
расширена для поддержки object-paint, обратно-совместимо), `src/web/index.html`.
Тесты: 17 unit `tests/unit/test_terrain_paint.py` (валидация
interpolate-stops, инварианты opacity/contrast по zoom), 6 integration
`tests/integration/test_terrain_z9_tiles.py` (`(hillshade, tri) × (z9, z10, z11)`).
ADR-017. Refs: ET-013.
- ET-013 (review F-1 fix): Слой `tri` добавлен в whitelist
FastAPI-endpoint'а `GET /terrain/{layer}/{z}/{x}/{y}.png` (`src/api/main.py`).
На test/prod-среде nginx перехватывает `/enduro/terrain/*` и отдаёт
PNG напрямую с диска, но в dev-режиме (`make dev` → FastAPI на :5556
без nginx) endpoint должен поддерживать `tri` нативно. Изменение
аддитивное: ответ-контракт и заголовки идентичны существующим слоям
(`hypso`, `hillshade`); REQ-F-18 «API contract без изменений» не нарушен.
Регрессия: integration-тест `test_known_terrain_layer_accepted_by_whitelist`
параметризован по `(hypso, hillshade, tri)` и проверяет, что для
заведомо отсутствующего файла возвращается `detail: "Tile not found"`,
а не `"Unknown layer"`. Refs: ET-013, review F-1.
### Changed
- ET-013 (review F-2 fix): Integration-тест
`tests/integration/test_terrain_z9_tiles.py` параметризован по
`(layer ∈ {hillshade, tri}) × (zoom ∈ {9, 10, 11})` — 6 кейсов
вместо 3, покрывает оба слоя на расширенном диапазоне зумов
(ранее покрывался только `hillshade`). Refs: ET-013, review F-2.
## [v0.0.4] — 2026-06-04 (tagged earlier, deploy log pending)
> Тег `v0.0.4` создан в рамках ET-012 deploy, но 14-deploy-log пишется
> в отдельном PR `deploy/ET-012-v0.0.4-log` (см. PR #25). Артефакты
> ET-012 живут под `[Unreleased]` до закрытия того PR — не трогаю.
## [v0.0.3] — 2026-06-03 (tagged, NOT deployed)
> ⚠️ Тег создан и запушен, PR смерджен в `main`, но docker-образ на test
> **не задеплоен**: deploy-hook `/home/slin/bin/enduro-deploy-hook.sh`
> упал на `Permission denied` при записи в `/var/log/enduro-trails/`
> (каталог root-owned, у `slin` нет права записи и нет `NOPASSWD sudo`).
> Подробности и инструкция для ops: `docs/work-items/ET-011/14-deploy-log.md`.
### 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()`. Данные треков хранятся только в памяти сессии