Files
enduro-trails/CHANGELOG.md
claude-bot 543099b740
All checks were successful
CI / lint (push) Successful in 4s
CI / test (push) Successful in 12s
CI / build (push) Successful in 2s
CI / lint (pull_request) Successful in 4s
CI / test (pull_request) Successful in 12s
CI / build (pull_request) Successful in 2s
fix(infra): use python urllib for container healthcheck (ET-015)
Базовый образ `python:3.12-slim` не содержит `curl`, поэтому текущий
healthcheck `["CMD", "curl", "-f", ...]` всегда падает (`exec: "curl":
executable file not found`), и контейнер `enduro-trails-app-1` висит
в статусе `unhealthy` (≥31 час, FailingStreak 3762 при RestartCount 0),
несмотря на то что приложение исправно отвечает HTTP 200 на /api/health.

Заменяем healthcheck на python one-liner через stdlib `urllib.request`
(ADR-020). Изменения:

  • docker-compose.yml, сервис app:
      test: ["CMD", "python", "-c",
             "import urllib.request,sys; sys.exit(0 if
              urllib.request.urlopen(...timeout=3).status == 200 else 1)"]
      + start_period: 20s
    interval/timeout/retries сохранены (30s / 5s / 3).
    Внутренний urlopen(timeout=3) строго меньше внешнего healthcheck
    timeout=5s (AC-07).

  • Dockerfile НЕ меняется (никаких apt-get install curl/wget — BRD §6,
    AC-04). Деплой без ребилда: `docker compose up -d app` достаточно.

  • src/api/main.py НЕ меняется. Контракт /api/health сохранён (AC-08).

Покрытие:
  - tests/static/test_healthcheck_compose.py — 10 тестов (ST-01..ST-07
    + защита от регресса по target URL / start_period / baseline params).
  - tests/unit/test_healthcheck_oneliner.py — 6 тестов (UT-01..UT-03),
    исполняют ровно ту же one-liner-команду через subprocess против
    локального мок-HTTPServer (200/301/404/500/503) и неиспользуемого
    порта. URL подменяется через `_retarget`, чтобы тестировать живой
    код из compose, а не его копию.

ADR: docs/work-items/ET-015/06-adr/ADR-020-healthcheck-via-python-urllib.md
CHANGELOG: запись в [Unreleased] / Fixed.

Refs: ET-015

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-05 15:32:34 +00:00

12 KiB
Raw Blame History

Changelog

All notable changes to this project will be documented in this file. Format: Keep a Changelog

[Unreleased]

Fixed

  • ET-015: 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.ruhttps://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(). Данные треков хранятся только в памяти сессии