8.9 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 | 20 | 2026-06-04 | 2026-06-07 |
|
|
Review ET-013 — Перепады высот на z9-z11 (re-run #20)
Re-run #20 — независимая сверка, свежий экземпляр reviewer. Перечитаны TRZ (
02-trz.md), AC (03-acceptance-criteria.md), ADR-017, CLAUDE.md, актуальный13-test-report.md. Реализация сверена построчно с REQ-F-01..F-21 и решениями ADR-017 (P-A, O-B, C-A, R-A, U-A, A-A, M-A, T-A) прямым чтением файлов рабочего дерева, не доверяя предыдущим ревью. Unit-тесты прогнаны локально — 17/17 PASS (0.03 s).Состояние ветки.
git diff main...HEAD --statзатрагивает только docs (12-review.md,13-test-report.md) — кодовая часть ветки идентична merged/deployed-состоянию (фича вmain, PR #26 + whitelist-fix, deploy v0.0.5). Нового кода для ревью нет; корректность merged-кода подтверждена непосредственным чтением и прогоном тестов.
TL;DR
- Branch:
feature/ET-013-z9-z11-z8(код вmain; в ветке — только docs). - Scope: zoom-aware paint hillshade/TRI на z9-z11, понижение
UI-минзума hillshade z10→z9, обратно-совместимое расширение
applyTerrainLayer, расширение backend-whitelist наtri. - P0/P1 (по коду): нет.
- Вердикт: APPROVED.
Точки сверки в коде
| Объект | Локация | Результат |
|---|---|---|
HILLSHADE_PAINT |
app.js:2734-2752 | 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 — stops точно по TRZ/ADR ✅ |
TRI_PAINT |
app.js:2755-2768 | opacity z5:0.55,z7:0.65,z8:0.70 (регрессия),z9:0.80,пик z10-z11:0.85,z12:0.75,z15:0.70; nearest ✅ |
applyTerrainLayer |
app.js:3371-3414 | нормализация typeof===number→{raster-opacity, raster-resampling:'linear'} / object as-is; paint: paint в addLayer ✅ |
onTerrainCheckbox |
app.js:2825-2826 | hillshade minzoom=9+HILLSHADE_PAINT; tri minzoom=5+TRI_PAINT; persistence localStorage (2816-2817) и .active без изменений ✅ |
updateHillshadeAvailability |
app.js:3425 | zoom < 9; старый zoom < 10 в теле функции отсутствует ✅ |
| UI-hint | index.html:60 | «Зум 9+» ✅ |
| backend whitelist | main.py:1252-1253 | ("hypso","hillshade","tri"); 404 на прочее ✅ |
| Cache-Control | main.py:1261 | public, max-age=31536000, immutable сохранён ✅ |
Соответствие ТЗ (REQ-F-01..F-21)
Все функциональные требования реализованы. F-01/11 (порог z9), F-02
(hillshade minzoom=9 + paint), F-03 (TRI minzoom=5, только opacity),
F-04 (обратно-совместимая сигнатура), F-05/06/07 (hillshade paint),
F-08/09 (TRI paint), F-10 (hint), F-12 (контракт onTerrainCheckbox/
persistence), F-13/14 (unit + регрессии, Вариант B), F-15 (integration
smoke со skipif), F-18 (API контракт сохранён), F-19 (style.json/
style-dark.json/app.css/config не тронуты — подтверждено отсутствием в
diff), F-21 (документация) — ✅.
Соответствие ADR-017
- P-A (frontend paint-калибровка): zoom-aware paint через
interpolate ['linear'] ['zoom']; 0 перегенерации тайлов, 0 новых слоёв/источников/endpoint'ов. ✅ - O-B (linear-stops), C-A (contrast только hillshade), R-A
(
nearestглобально), U-A (UI-порог z9 + source.minzoom=9), A-A (обратно-совместимая сигнатура), M-A (константы рядом сTERRAIN_BASE_URL), T-A (один paint для всех тем) — все соблюдены. ✅ - Отклонённые «жирные» альтернативы (z-factor 2.5, raster-dem, theme-specific paint) корректно вынесены в follow-up (TD-1..TD-5). ✅
Качество кода
applyTerrainLayerрасширен строго обратно-совместимо; нормализация paint чистая, JSDoc/комментарий на месте.HILLSHADE_PAINT/TRI_PAINTрядом сTERRAIN_BASE_URLс пояснением логики stops; конфигурируемость через env/config справедливо отвергнута (ADR-017 M-A — калибровка живёт в коде).- Дублирования, необработанных ошибок, мёртвого кода не выявлено.
Качество тестов
- Unit (17/17 PASS): opacity/contrast stops + монотонность,
nearest, регрессия z8=0.70, пик z9-z11≥0.80, обратная совместимостьapplyTerrainLayer(number→legacy/linear, object as-is), порогzoom < 9(+ отсутствие< 10), текст hint «Зум 9+», число call-site, привязка paint-константы и minzoom к каждому слою. Парсер устойчив к пробелам/переносам. - Integration: TestClient против
src.api.main:app; тайло-зависимые кейсы параметризованы по слоям/зумам,skippedбез PH-6 данных; whitelist/404/Cache-Control-регрессии работают всегда. Дизайн адекватен.
Findings
| # | Severity | Файл | Описание | Статус |
|---|---|---|---|---|
| N-1 | P3 (info) | src/api/main.py:1252 |
TRZ §2 декларировал backend «без изменений», но в whitelist добавлен tri. Необходимый багфикс: в dev-режиме (FastAPI без nginx) /terrain/tri/... иначе → 404 «Unknown layer». Контракт endpoint'а (URL-шаблон, коды ответа, Cache-Control: immutable, отсутствие новых query/headers) не нарушен → REQ-F-18 соблюдён. Покрыто integration-регрессией (parametrize hypso/hillshade/tri + парный 404). Документировано в docstring. Не дефект. |
Принято. |
Замечание по статусу тестирования (вне content-review)
Test Report (13-test-report.md) фиксирует P1-01 / AC-19: на
test-среде отсутствуют нарезанные z9-тайлы hillshade (стек начинается
с z10), поэтому при понижённом UI-пороге z9 чекбокс активен, а слой
рисуется пустым (404).
Это инфраструктурный дефект данных/деплоя, не дефект кода ET-013:
- Код корректно реализует REQ-F-01/F-02 (порог и source.minzoom = 9) — именно так, как требует TRZ.
- TRZ сам предвидел этот случай: REQ-F-20 §1 и AC-19 явно предписывают pre-deploy gate и, при 404, остановку с догенерацией тайлов в рамках PH-6 follow-up — а не изменение кода ET-013.
- Runtime-детект 404 и удержание чекбокса disabled — вне scope TRZ (ADR-017/§6 умышленно выбрали pre-deploy gate вместо клиентского fallback'а); требовать этого от Developer'а нельзя.
Следствием AC-19 в отчёте помечены AC-03/07/13 (визуальная читаемость z9).
Разблокировка — зона Деплой/Инфра (догенерить data/terrain/ hillshade/9/* для ЦФО + повторный AC-19/Playwright), не Review.
Кодовых P0/P1 это не порождает.
⚠️ Для Деплоера: задача не может считаться функционально завершённой до прохождения AC-19 (HTTP 200 на z9/z10/z11 hillshade). Это deploy-gate, а не code-gate.
Вердикт
Реализация полностью соответствует TRZ и ADR-017; код чистый, тесты адекватны и зелёные (17/17). Кодовых P0/P1 нет; единственный блокер (AC-19) — данные/инфра, вне content-review. APPROVED.