Files
enduro-trails/docs/work-items/ET-015/08-data-requirements.md
claude-bot 4f80c250cf
All checks were successful
CI / lint (push) Successful in 4s
CI / test (push) Successful in 10s
CI / build (push) Successful in 3s
architect(ET): auto-commit from architect run_id=102
2026-06-05 15:27:58 +00:00

14 KiB
Raw Blame History

type, work_item_id, title, version, status, created_at, authors
type work_item_id title version status created_at authors
data-requirements ET-015 Требования к данным — ET-015: Healthcheck enduro-trails-app через python urllib 1 approved 2026-06-05
agent:architect

Требования к данным — ET-015

1. Резюме

ET-015 — pure container-config change. Никаких изменений в данных: ни в БД, ни в файлах на диске, ни в localStorage, ни в API-контрактах, ни в конфигурациях приложения.

Меняется команда, которую Docker запускает для проверки живости контейнера — она перестаёт зависеть от curl (отсутствующего в образе) и переключается на python urllib.request. Запрос ходит на уже существующий эндпоинт /api/health (src/api/main.py:1224), который не меняется.

Меняется:

  • Runtime-состояние docker inspect enduro-trails-app-1 --format '{{.State.Health.Status}}': переключается с unhealthy (ложный) на healthy (честный).
  • Содержимое State.Health.Log: теперь пишутся реальные ExitCode: 0 результаты, а не exec: "curl": executable file not found in $PATH.

Не меняется:

  • Содержимое и схема БД centralfederal.sqlite, gps_tracks.sqlite.
  • Содержимое и формат PNG-тайлов в data/terrain/*.
  • Файлы OSRM-графа (data/osrm/*), OSM-данные (data/osm/*).
  • Контракты API (/api/gps-tracks/*, /terrain/*, /api/route/*, /api/health, прочие).
  • Эндпоинт /api/health — формат ответа, поведение, путь (src/api/main.py:1224) (AC-08).
  • Ключи localStorage фронтенда.
  • style.json, style-dark.json.
  • config/*.yaml.
  • src/web/*, src/api/*, Dockerfile, миграции, скрипты деплоя.

2. Архитектурные границы данных

Слой данных Тип Расположение Изменения в ET-015
OSM-vector (trails) существующий /app/data/centralfederal.sqlite нет
Публичные GPS-треки (ET-008) существующий /app/data/gps_tracks.sqlite нет
OSRM-граф существующий /app/data/osrm/enduro.osrm.* нет
Terrain PNG-тайлы существующий data/terrain/* нет
Личные GPX-треки (ET-006) существующий браузер (memory) нет
User UI state существующий localStorage нет
MapLibre client tile cache существующий браузер (LRU MapLibre) нет
Серверный кэш не предусмотрен n/a нет
Docker container state runtime Docker daemon на mva154 меняется: State.Health.Status: unhealthy → healthy, FailingStreak: 3762 → 0, Log[].ExitCode: -1 → 0
docker-compose.yml конфигурация git, mva154 меняется: секция app.healthcheck
CHANGELOG.md документация git меняется: +1 строка в Unreleased

3. Серверные данные

3.1 БД

Без изменений vs ET-014/ET-013/ET-008/ET-012.

  • centralfederal.sqlite — read-only для ET-015 (даже не читается).
  • gps_tracks.sqlite — read-only для ET-015 (даже не читается).
  • Никаких ALTER/CREATE/INSERT/UPDATE/DELETE.
  • Никаких миграций.

Косвенная связь: эндпоинт /api/health возвращает поле db_exists (os.path.exists(DATA_PATH)). Это проверка наличия файла, не открытия БД, не SELECT'а. ET-015 не делает БД «зависимостью healthcheck'а» больше, чем она уже была.

3.2 Тайлы на диске

Без изменений. data/terrain/*, data/osm/*, data/osrm/* — не трогаются. Healthcheck не обращается ни к одной плитке.

3.3 Статика src/web/

Без изменений. Healthcheck не задевает фронтенд.

Файл Изменение
src/web/app.js нет
src/web/app.css нет
src/web/index.html нет
src/web/gps_tracks.js нет
src/web/gpx.js нет
src/web/units.js нет
src/web/style.json нет
src/web/style-dark.json нет

3.4 Backend src/api/

Без изменений. /api/health (src/api/main.py:1224) не правится (AC-08, BRD §7).

Файл Изменение
src/api/main.py нет
src/api/requirements.txt нет (никаких новых python-зависимостей)
src/api/gps_tracks/* нет
Прочие модули нет

3.5 Конфиги

Файл Изменение
Dockerfile нет (см. ADR-020 Cons Варианта B)
docker-compose.yml да — секция app.healthcheck
config/gps_sources.yaml нет
config/gps_regions.yaml нет
nginx-config на хосте нет
systemd / cron на mva154 нет

3.6 Скрипты и миграции

Каталог Изменение
scripts/ нет (никакого scripts/healthcheck.py — отклонено в Вариант E ADR-020)
migrations/ нет
tests/ нет (новые тесты опциональны, см. test-plan; не блокируют merge)

4. Клиентские данные

4.1 localStorage

Без изменений. ET-015 фронтенд не задевает. Никаких новых ключей, никакой миграции.

4.2 MapLibre LRU (browser-side)

Без изменений. Тайловый кэш не задействован.

4.3 DOM runtime state

Без изменений. UI не меняется.

4.4 In-memory constants

Без изменений.

5. Контракты API

5.1 Backend endpoints

Без изменений. ET-015 не добавляет, не модифицирует и не удаляет ни один endpoint.

Endpoint До ET-015 После ET-015
GET /api/health HTTP 200, JSON {"status": "ok", "db_path": ..., "db_exists": ...} без изменений (AC-08)
GET /api/gps-tracks/health без изменений без изменений
GET /api/gps-tracks/tiles/{z}/{x}/{y}.mvt без изменений без изменений
GET /api/gps-tracks?bbox=… без изменений без изменений
GET /api/gps-tracks/{id}/download без изменений без изменений
GET /terrain/{layer}/{z}/{x}/{y}.png без изменений без изменений
GET /api/route/* без изменений без изменений
GET /api/trails/* без изменений без изменений

5.2 Внутренний контракт healthcheck-команды

Контракт До ET-015 После ET-015
Команда curl -f http://localhost:5556/api/health python -c "import urllib.request,sys; sys.exit(0 if urllib.request.urlopen('http://localhost:5556/api/health', timeout=3).status == 200 else 1)"
Тип команды (Docker) CMD (массив) CMD (массив)
Зависимость от пакетов curl (отсутствует ⇒ exec error) stdlib (присутствует ⇒ работает)
Exit code при HTTP 200 0 (если бы curl был) 0
Exit code при HTTP 4xx/5xx ≠ 0 (-f фейлит на 4xx/5xx) ≠ 0 (HTTPError ⇒ ненулевой код)
Exit code при connection refused ≠ 0 (если бы curl был) ≠ 0 (URLError ⇒ ненулевой код)
Exit code при отсутствии команды -1 (exec error) n/a (команда есть)
Внутренний timeout запроса n/a (использовал default Docker) 3 с (urlopen(..., timeout=3))
Внешний timeout Docker 5 с 5 с (без изменений)
Interval 30 с 30 с (без изменений)
Retries 3 3 (без изменений)
Start period не задан 20 с (новое)

5.3 Что не становится зависимостью

  • БД (centralfederal.sqlite, gps_tracks.sqlite): healthcheck не открывает их. /api/health только проверяет os.path.exists() — это файловая операция, БД-движок не задействован.
  • OSRM (http://172.22.0.1:5559): healthcheck не дёргает routing.
  • Тайл-каталог: healthcheck не запрашивает PNG-плитки.
  • Внешние тайл-провайдеры (OSM, Esri): не задействованы.
  • nginx: не на пути healthcheck-запроса.

6. Миграции

Нет. Никаких миграций БД, миграций localStorage, миграций конфигов приложения.

При деплое в test:

  • data/* — без изменений.
  • БД — без изменений.
  • localStorage — старые ключи интерпретируются как раньше.
  • MapLibre LRU — без изменений.
  • Контейнер enduro-trails-app-1 пересоздаётся (старый удаляется, новый создаётся с тем же образом и тем же файловым состоянием). Все volume-mounts (./data:/app/data, ./src/web:/app/src/web, ./config:/app/config:ro) подхватываются как раньше → никаких потерь данных.

7. Тестовые данные

7.1 Для unit-тестов

См. 04-test-plan.yaml UT-01..UT-03:

  • UT-01: live uvicorn на :5556 (через make dev) либо mock-сервер; запуск python one-liner с хоста; проверка exit code 0.
  • UT-02: никто не слушает :5556; запуск python one-liner; проверка exit code ≠ 0 (URLError).
  • UT-03: mock-сервер отдаёт 500; запуск python one-liner; проверка exit code ≠ 0.

Тестовые данные минимальны: либо реальный uvicorn (с реальной БД, которая уже есть), либо python http.server-mock. Никаких fixtures, seed-данных, моков БД.

7.2 Для integration-тестов

См. 04-test-plan.yaml IT-01..IT-04:

  • IT-01..IT-04: реальный docker compose up -d app на машине с доступом к data/. Данные реальные; ET-015 их не меняет.
  • Никаких новых fixtures, никаких CSV/JSON seed-файлов.

7.3 Для UI-тестов (Playwright)

Не применимо. ET-015 не трогает UI.

7.4 Для E2E на mva154

См. 04-test-plan.yaml E2E-01..E2E-02:

  • E2E-01: ssh mva154 'docker inspect ...' — данные читаются напрямую из Docker daemon, никакие тестовые fixtures не нужны.
  • E2E-02: curl https://openclaw.mva154.duckdns.org/enduro/api/health — проверка живого эндпоинта; ответ — реальный JSON с реальной БД на mva154.

8. Резервные копии и DR

Без изменений. ET-015 не пишет данных. RPO = 0.

Если деплой ET-015 сломается (например, новый healthcheck сам по себе помечает контейнер unhealthy из-за неучтённой особенности):

  • БД, тайлы, конфиги — не затронуты.
  • Rollback = git revert + docker compose up -d app (см. 07-infra-requirements.md §6.3).
  • RTO ≤ 5 минут.

9. Privacy / Compliance

Аспект Требование
PII Нет. ET-015 не собирает, не обрабатывает, не передаёт никаких пользовательских данных
Licensing Не применимо
Attribution MapLibre attribution control — без изменений
GDPR / 152-ФЗ Не применимо (healthcheck — loopback внутри контейнера, не пересекает периметр)
Egress на внешние сервисы Нет (healthcheck не делает egress)
Логирование PII Нет (healthcheck-логи Docker содержат только exit code и stdout/stderr команды — пустые)

10. Связанные документы

  • 01-brd.md §1 (контекст), §2 (корень проблемы), §3 (бизнес-проблема), §4 (цель), §6 (ограничения), §7 (out of scope)
  • 02-trz.md §1 (постановка), §2 (текущее состояние), §3 (целевое состояние), §4 (альтернативы), §5 (R-1..R-5), §6 (тестирование)
  • 03-acceptance-criteria.md AC-01..AC-10
  • 04-test-plan.yaml ST-01..ST-07, UT-01..UT-03, IT-01..IT-04, E2E-01..E2E-02
  • 06-adr/ADR-020-healthcheck-via-python-urllib.md §«Решение», §«Что НЕ меняется», §«Технический долг»
  • 07-infra-requirements.md §2 (контейнеры), §5 (конфигурация)
  • 10-tech-risks.md
  • docs/architecture/README.md §«Компоненты», §«GPS Tracks Pipeline» (для контекста: ET-015 эту pipeline не трогает)
  • docs/work-items/ET-014/08-data-requirements.md — образец «pure client UI change» документа (наследие)
  • docs/work-items/ET-013/08-data-requirements.md — образец «read-only data» документа (наследие)