23 KiB
type, work_item_id, title, version, status, created_at, authors
| type | work_item_id | title | version | status | created_at | authors | |
|---|---|---|---|---|---|---|---|
| infra-requirements | ET-013 | Инфраструктурные требования — ET-013: Zoom-aware paint для terrain-слоёв на z9-z11 | 1 | approved | 2026-06-04 |
|
Инфраструктурные требования — ET-013
1. Резюме
ET-013 — frontend paint-калибровка. Меняются два файла исходного
кода (src/web/app.js, src/web/index.html) + добавляются тесты.
Инфраструктура не меняется:
- 0 новых docker-сервисов;
- 0 изменений в
Dockerfile; - 0 изменений в
docker-compose.yml; - 0 новых файлов БД, миграций, индексов;
- 0 новых cron-записей;
- 0 новых env / секретов / API-ключей;
- 0 новых исходящих HTTPS-соединений;
- 0 новых портов;
- 0 изменений в nginx (тайлы рельефа отдаются с тех же путей
/enduro/terrain/{layer}/{z}/{x}/{y}.png); - 0 изменений в backend (
src/api/main.py:terrain_tileбез правок).
Эскалация: minor change (см. ADR-017 §«Классификация изменения»).
2. Контейнеры и сервисы
| Аспект | Требование |
|---|---|
| Новый сервис | Нет |
Изменения Dockerfile |
Нет |
Изменения docker-compose.yml |
Нет |
Перезапуск app после деплоя |
Нужен — docker compose up -d --no-deps app (≈ 5 сек простоя). Подхватывает обновлённые src/web/app.js и src/web/index.html (отдаются как статика из контейнера) |
Перезапуск gps-collector |
Не нужен (не затронут) |
| Очистка серверных кэшей | Не требуется (backend не меняется; /terrain/* endpoint и Cache-Control: max-age=31536000, immutable без изменений) |
| Очистка клиентских кэшей | Не требуется как часть деплоя, но пользователю при первой загрузке после деплоя браузер дёрнет свежий app.js (cache-busting через nginx if-modified-since) |
2.1 Зависимости между сервисами
Без изменений vs PH-6 / ET-007:
app→ файлы/app/data/terrain/{hillshade,tri,hypso}/{z}/{x}/{y}.png(read-only при отдаче клиенту).nginx (host)→app:8000через docker-network bridge.
3. Сеть
| Аспект | Требование |
|---|---|
| Новые входящие порты | Нет |
| Изменения nginx | Нет (location /enduro/terrain/ без правок; новые комбинации (z, x, y) для z=9 — просто другие значения существующего path-параметра) |
| nginx gzip для PNG | Не применяется (PNG уже сжат). Без изменений vs PH-6 |
Кэш-заголовки на /terrain/* |
Без изменений: Cache-Control: public, max-age=31536000, immutable (см. src/api/main.py:1252). Браузерный кэш + nginx-кэш агрессивно поглощают повторы |
| Новые исходящие соединения | Нет — никаких внешних API не дёргается, всё локально |
| CORS | Без изменений; /terrain/* отдаётся в том же origin, что и index.html |
| HTTPS / TLS | Без изменений — nginx с Let's Encrypt сертификатом DuckDNS |
3.1 Ingress / Egress — оценка дельты
Изменения сетевого паттерна (BRD M-10, NFR-03):
- Hillshade: UI-минзум понижается с 10 до 9 → пользователь видит слой на одной zoom-ступени раньше. Один тайл z9 == 4 тайла z10 по покрытию территории, поэтому при «активной zoom-сессии» z=8→z=12 с включённым hillshade добавляется ≤ 1 zoom-ступень тайлов.
- TRI: minzoom источника не меняется (5), opacity меняется только для уже-запрашиваемых тайлов. Дельта запросов 0.
- Итого: при типичной сессии «10 зумов между z8 и z12 с обоими слоями» объём PNG растёт ≤ 35% (BRD M-10, AC-21).
Размер одного PNG-тайла рельефа (terrain) ≈ 8-30 KB (без gzip — PNG уже сжат). На сессию: было ~60 тайлов × 20 KB = 1.2 MB, станет ~80 тайлов × 20 KB = 1.6 MB. Дельта на пользователя: ~0.4 MB.
При 10 одновременных пользователях на mva154 — пик ≈ 4 MB/сек дополнительного uplink, мизер по сравнению с uplink сервера (≥ 100 Mbps по DuckDNS).
Кэш браузера (immutable, max-age=31536000) поглощает 2-й и
последующие визиты целиком.
3.2 Rate-limit на /terrain/*
Не вводим в этой итерации. PNG-тайлы — статика с агрессивным кэшем; DDoS-стоимость низкая (sendfile из ФС без вычислений). Если в проде обнаружится скан z=9-z=14 grid'а — добавляется отдельным DevOps-task'ом, не в ET-013.
4. Серверные ресурсы
| Аспект | Требование |
|---|---|
CPU app |
Без изменений по архитектуре. Раздача PNG — FileResponse (sendfile, zero-copy через ядро), CPU-cost пренебрежимый. Рост запросов до +35% даёт +0.5% CPU на сервере при пике сессий |
RAM app |
Без изменений. PNG не буферизуются в памяти; sendfile из файловой системы |
Disk app |
Без изменений. Тайлы рельефа лежат в /home/slin/enduro-trails/data/terrain/{hillshade,tri,hypso}/{z}/{x}/{y}.png (объём по PH-6 baseline). Никаких новых файлов / volume |
CPU gps-collector |
Без изменений (не затронут) |
RAM gps-collector |
Без изменений |
Disk gps-collector |
Без изменений |
4.1 Размер тайлов рельефа на диске
Не меняется. ET-013 не перегенерирует тайлы; используются существующие нарезки z8-z14 из PH-6. Если pre-deploy smoke (см. §6.2 шаг 1) обнаружит отсутствие тайлов z9-z11 — задача останавливается, открывается PH-6 follow-up на догенерацию (BRD R-11, AC-19).
5. Конфигурация и секреты
| Аспект | Требование |
|---|---|
| Новые env-переменные | Нет |
| Новые секреты | Нет |
| Новые API-ключи | Нет |
Изменения config/*.yaml |
Нет |
| Изменения runtime config | Нет — HILLSHADE_PAINT и TRI_PAINT — JS-константы, живут в коде и меняются коммитом (BRD §6 q&a, ADR-017 §M) |
Изменения style.json / style-dark.json |
Нет — растровые terrain-слои добавляются динамически из JS, в стилях не описаны |
6. Деплой
6.1 Среды
- dev (локально):
make dev(docker compose upapp). Достаточноgit pull && make devдля смены поведения. - test (mva154):
https://openclaw.mva154.duckdns.org/enduro/. CI/CD — Gitea Actions; деплой черезmake deploy-testили ручной SSH +docker compose up -d --no-deps --build app(см. §6.2). - prod — пока не задействован; ET-013 деплоится только в test.
6.2 Процедура деплоя в test
Последовательность шагов (REQ-F-20 в TRZ §3):
- Pre-deploy smoke: проверить наличие тайлов z9-z11 на test-среде:
Ожидается
curl -sI 'https://openclaw.mva154.duckdns.org/enduro/terrain/hillshade/9/308/158.png' | head -1 curl -sI 'https://openclaw.mva154.duckdns.org/enduro/terrain/hillshade/10/617/317.png' | head -1 curl -sI 'https://openclaw.mva154.duckdns.org/enduro/terrain/hillshade/11/1234/635.png' | head -1HTTP/1.1 200 OKна все три. Если хотя бы один 404 — merge приостанавливается (AC-19), открывается PH-6 follow-up на догенерацию тайлов. - Сборка образа:
docker compose build appна mva154 (послеgit pull). - Перезапуск
app:docker compose up -d --no-deps app. - Post-deploy smoke:
# Проверка статики app.js обновился curl -s 'https://openclaw.mva154.duckdns.org/enduro/app.js' | grep -c 'HILLSHADE_PAINT' # Ожидается ≥ 1 - Ручная валидация AC-03..AC-12 через DevTools:
- открыть карту, центр над Окой/югом Москвы (
[37.6, 54.5]); window._map.setZoom(9)— кнопка «Тени рельефа» активна, hint скрыт;- включить «Тени рельефа» и «Перепады»;
- скриншоты на z9/z10/z11/z14 → визуальная приёмка AC-07..AC-10;
- переключить тему
theme-dark→ проверить AC-11; - переключить подложку
#base-btn-satellite→ проверить AC-12.
- открыть карту, центр над Окой/югом Москвы (
- Запись результатов в
13-test-report.mdи14-deploy-log.md.
6.3 Rollback
В случае проблем (например, AC-11 «hillshade сливается с dark-темой», без возможности быстрой donastройки stops):
- Frontend rollback:
git revert <commit>+docker compose up -d --no-deps --build app. - Cache invalidation: не требуется (backend не меняется, browser
cache на статике
app.jsинвалидируется по if-modified-since автоматически).
RTO: ≤ 5 минут (один docker compose up -d --no-deps app).
RPO: 0 — никаких изменений в БД, никаких данных не теряется.
6.4 CI/CD-гейты
make lint(ruff + eslint) — должен быть зелёным (AC-18).make test(pytest unit + integration) — зелёный (AC-15..AC-17).pytest tests/integration/test_terrain_z9_tiles.py— c@pytest.mark.skipifдля CI без данных (AC-16), не блокирует merge.
7. Observability / Логирование
| Аспект | Требование |
|---|---|
| Новые лог-сообщения | Нет (NFR-06 в TRZ §4) |
| Существующие лог-сообщения | uvicorn.access логирует все запросы к /terrain/* с длиной ответа — этого достаточно для мониторинга дельты трафика после деплоя |
| Метрики / Prometheus | Не вводим в MVP |
| Health-endpoint | GET /api/health (если есть) — без изменений |
7.1 Что мониторить после деплоя
В nginx access.log на mva154 (вручную, без алёртов) — первая неделя:
- Запросы к
/terrain/hillshade/9/*/*.png: должны появиться (раньше клиент их не дёргал). Если 404 —data/terrain/hillshade/9/отсутствует, инцидент (BRD R-11). - Объём ответов: ≤ +35% к baseline на терминальную пользовательскую сессию (BRD M-10, AC-21).
- Status codes: только 200/304 (304 от if-modified-since). Никаких 500/502 быть не должно.
8. Резервное копирование / Disaster recovery
| Аспект | Требование |
|---|---|
| Backup БД | Без изменений vs ET-008/PH-6 (ET-013 не трогает БД) |
| Backup тайлов рельефа | Без изменений vs PH-6. Регенерируемы из SRTM при необходимости |
| Время восстановления (RTO) | ≤ 5 минут (rollback контейнера, см. §6.3) |
| Точка восстановления (RPO) | 0 — никаких данных не теряется |
9. Безопасность
| Аспект | Требование |
|---|---|
| Auth / Authorization | Без изменений (NFR-05 в TRZ §4). /terrain/* — публичный (как и был) |
| Валидация входных данных | Без изменений; existing валидация (z, x, y) в terrain_tile уже корректно принимает любые валидные z |
| CSP | Без изменений |
| Rate-limit | Не вводим в MVP (см. §3.2) |
| TLS | Без изменений — nginx с Let's Encrypt сертификатом DuckDNS |
10. Совместимость
| Аспект | Требование |
|---|---|
API контракт /terrain/* |
Не меняется (REQ-F-18). Любые клиенты (старые tab'ы со старым app.js) продолжают работать; они просто не дёргают z=9 hillshade |
| MapLibre GL JS совместимость | MapLibre 4.7.0 (index.html:10) поддерживает interpolate для raster-opacity и raster-contrast. raster-resampling не поддерживает interpolate — поэтому глобально 'nearest' (см. ADR-017 §R) |
| Совместимость с PH-6 stack | Никаких изменений; калибровка идёт поверх существующих PH-6 тайлов |
| Совместимость с ET-007 (Спутник) | AC-12 проверяет визуально. В случае проблем — открывается ADR-018 (theme-specific paint) |
| Совместимость с ET-005 (units), ET-006 (GPX), ET-008 (public tracks) | Без изменений; ET-013 трогает только terrain-слои |
| Совместимость с OSRM | Не затронуто (роутинг работает с OSRM-графом независимо) |
| localStorage migration | Не нужно (REQ-F-17). Существующие ключи terrain-hillshade, terrain-tri — без изменений. Пользователи с включённым hillshade автоматически увидят слой на z9 при следующей загрузке |
11. Связанные документы
01-brd.md§3 (F-01..F-14), §6 (Зависимости, инфра), AC §AC-19 (pre-deploy check)02-trz.md§3 REQ-F-20 Деплой и валидация, §4 NFR06-adr/ADR-017-zoom-aware-terrain-paint.md§«Классификация изменения», §«Последствия»08-data-requirements.md(этот пакет)10-tech-risks.md(этот пакет)docs/work-items/ET-012/07-infra-requirements.md— образец «zero-infra» work-item (наследие)docs/work-items/ET-011/07-infra-requirements.md— образец «zero-infra» work-item (наследие)