8.1 KiB
type, work_item_id, verdict, version, created_at, updated_at, authors, related
| type | work_item_id | verdict | version | created_at | updated_at | authors | related | |||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| review | ET-013 | APPROVED | 25 | 2026-06-04 | 2026-06-07 |
|
|
Review ET-013 — Перепады высот на z9-z11 (re-run #25)
Независимая сверка, свежий экземпляр reviewer. Перечитаны
02-trz.md(REQ-F-01..F-21),03-acceptance-criteria.md(AC-01..AC-22),06-adr/ADR-017-zoom-aware-terrain-paint.md,CLAUDE.md,13-test-report.md(verdict BLOCKED). Реализация сверена построчно с REQ и решениями ADR прямым чтением файлов рабочего дерева, без доверия предыдущим ревью. Unit-тесты прогнаны локально — 17/17 PASS (0.03 s).
1. Объём ревью
Четыре оси: соответствие ТЗ, соответствие ADR-017, качество кода,
качество тестов. Код фичи слит в main (commit 5be81f9); ревью
выполнено по фактическому состоянию рабочего дерева: src/web/app.js,
src/web/index.html, src/api/main.py, tests/unit/test_terrain_paint.py,
tests/integration/test_terrain_z9_tiles.py.
2. Соответствие ТЗ (REQ-F-01..F-21)
| REQ | Что проверено | Статус |
|---|---|---|
| F-01 / F-11 | updateHillshadeAvailability: if (zoom < 9) (app.js:3425); < 10 отсутствует |
✅ |
| F-02 | hillshade-вызов applyTerrainLayer(..., HILLSHADE_PAINT, 9, 15) (app.js:2825) |
✅ |
| F-03 | TRI-вызов applyTerrainLayer(..., TRI_PAINT, 5, 15) — minzoom=5 без изменений (app.js:2826) |
✅ |
| F-04 | Сигнатура applyTerrainLayer(id, tileUrl, enabled, opacityOrPaint, minzoom, maxzoom); нормализация typeof === 'number' → legacy paint (app.js:3371-3380) — обратно-совместимо |
✅ |
| F-05/06/07 | HILLSHADE_PAINT: opacity (9→0.65,10→0.60,11→0.55,12→0.50,14→0.40), contrast (9→0.40,10→0.35,11→0.30,12→0.15,14→0.00), 'nearest' (app.js:2734-2752) — дословно по ТЗ |
✅ |
| F-08/09 | TRI_PAINT: opacity (5→0.55,7→0.65,8→0.70,9→0.80,10→0.85,11→0.85,12→0.75,15→0.70), 'nearest' (app.js:2755-2768) |
✅ |
| F-10 | #terrain-hillshade-hint = «Зум 9+» (index.html:60) |
✅ |
| F-12 | onTerrainCheckbox контракт + persistence localStorage (terrain-hillshade/terrain-tri) без изменений |
✅ |
| F-13/14 | tests/unit/test_terrain_paint.py — 17 тестов: stops, регрессия z8=0.70, пик z9-z11≥0.80, монотонность, nearest, обратная совместимость, порог 9, hint, call-count |
✅ |
| F-15 | tests/integration/test_terrain_z9_tiles.py — параметризация по слою/зуму, skipif без данных, 404-регрессии независимы от данных |
✅ |
| F-17/F-18/F-19 | persistence без миграции; стили style.json/style-dark.json и конфиги не тронуты |
✅ |
ТЗ реализовано полностью и буквально. Все stops paint-выражений совпадают с REQ-F-05/F-08 до знака.
3. Соответствие ADR-017
- P-A (frontend paint-калибровка) — ✅ правка во фронтенде, без перегенерации тайлов, без смены paint-pipeline.
- O-B (linear interpolate stops) — ✅ stops совпадают с ADR §O-B; явная точка
8→0.70(регрессия AC-06) и clamping на верхнем стопе z14 (регрессия AC-10). - C-A (
raster-contrastzoom-aware только для hillshade) — ✅, TRI контраст не трогается. - R-A (
'nearest'глобально для обоих слоёв) — ✅. - U-A (UI-гейт hillshade понижен до z9, не до z8) — ✅.
- T-A (единый paint, theme-specific отложен в follow-up ADR-018) — ✅.
- A-A (обратно-совместимое расширение
applyTerrainLayer) — ✅. - M-A (константы рядом с
TERRAIN_BASE_URLвapp.js) — ✅.
Нарушений ADR нет.
4. Качество кода
applyTerrainLayerрасширена обратно-совместимо; веткаtypeof === 'number'сохраняет старый контракт (raster-opacity+linear). Объект paint пробрасывается вaddLayerкак есть.- Константы paint снабжены комментариями со ссылкой на ADR-017 и обоснованием stops; магических чисел в логике нет, калибровка изолирована в декларациях.
- z-order вставки слоя (
firstTrailLayer) сохранён; дублирования и мёртвого кода нет.
5. Качество тестов
- Unit (Вариант B по REQ-F-13) — статический парсинг
app.js/index.html: значения и монотонность stops, отсутствие старого порога< 10, обратная совместимость, hint-текст, число вызовов. Локальный прогон 17/17 PASS. - Integration — параметризация по обоим слоям, whitelist-регрессия,
cache-header; 404-проверки не зависят от наличия PNG, тайловые тесты
корректно
skipifпри отсутствии z9-данных. - Примечание по среде: локально модуль
tests/integration/...не импортируется из-за отсутствияshapely, ноshapely==2.0.4указан вsrc/api/requirements.txtиpyproject.toml→ в CI импорт проходит. Это дефект локального окружения, не кода.
6. Findings
| ID | Severity | Описание |
|---|---|---|
| F-INFO-1 | P3 (informational) | src/api/main.py:1252 добавляет tri в whitelist слоёв (hypso/hillshade/tri). Формально ТЗ §2 и REQ-F-18 декларировали «main.py без изменений», но это необходимый и уже завизированный прошлым ревью (F-1) фикс: фронтенд запрашивает /terrain/tri/{z}/{x}/{y}.png, и без whitelist слой «Перепады» возвращал бы 404 в dev-режиме (без nginx). Изменение обратно-совместимо, контракт endpoint'а не ломается (добавление допустимого значения, без новых query/headers/кодов). Покрыто регрессией test_known_terrain_layer_accepted_by_whitelist. Не блокер. |
Findings уровня P0/P1/P2 нет.
7. Примечание по статусу тестирования
13-test-report.md имеет verdict: BLOCKED. Блокировка относится к
данным деплой-стадии (на test-среде не нарезаны z9-тайлы hillshade →
pre-deploy gate AC-19 и визуальная приёмка z9 не проходят), а не к
коду. Разблокировка = PH-6 follow-up (догенерить z9-тайлы). Это вне
четырёх осей code-review. По коду, ТЗ, ADR и автотестам блокеров нет.
8. Вердикт
Реализация полностью соответствует ТЗ и ADR-017; код и тесты
качественны; unit-тесты зелёные. Единственное расхождение с буквой ТЗ
(whitelist tri в main.py) — обоснованный, задокументированный и ранее
завизированный фикс уровня P3. P0/P1 отсутствуют.
APPROVED.