reviewer(ET): auto-commit from reviewer run_id=230
All checks were successful
CI / lint (push) Successful in 4s
CI / test (push) Successful in 9s
CI / build (push) Successful in 3s

This commit is contained in:
2026-06-06 23:06:51 +00:00
parent d2265fb368
commit 4153b5bcd0

View File

@@ -2,7 +2,7 @@
type: review
work_item_id: ET-013
verdict: APPROVED
version: 11
version: 12
created_at: 2026-06-04
updated_at: 2026-06-06
authors:
@@ -14,90 +14,85 @@ related:
- "ET-013:test-report"
---
# Review ET-013 — Перепады высот на z9-z11 (re-run #11)
# Review ET-013 — Перепады высот на z9-z11 (re-run #12)
> **Re-run #11 (independent).** Перечитаны TRZ (`02-trz.md`), AC
> (`03-acceptance-criteria.md`), ADR-017, CLAUDE.md. Снят content-diff
> фичи: `git show 5be81f9 099669d -- src/`. Построчно сверены
> paint-stops в `src/web/app.js` (`HILLSHADE_PAINT`/`TRI_PAINT`) с
> REQ-F-05/06/07/08/09 — совпадают точно (hillshade opacity 9:0.65→14:0.40,
> contrast 9:0.40→14:0.00; TRI z8=0.70, пик z9-z11=0.85; оба `nearest`).
> Проверены `updateHillshadeAvailability` (`zoom < 9`), hint «Зум 9+»
> в `index.html`, обратно-совместимая нормализация `applyTerrainLayer`
> (number→legacy / object as-is), backend-whitelist в `src/api/main.py`
> (`tri` добавлен, контракт сохранён). Unit-тесты перезапущены локально —
> **17/17 PASS (0.04 s)**. Integration-тест (`test_terrain_z9_tiles.py`)
> структурно корректен (TestClient + `skipif` для отсутствующих PH-6
> данных + whitelist-регрессии без тайлов); в текущем sandbox не
> собирается из-за отсутствия `shapely` в окружении — это инфра-зависимость
> импорта FastAPI-приложения, не дефект кода фичи. **С момента v9 ни
> `src/`, ни `tests/` не менялись** — содержательные коммиты прежние
> (`5be81f9` feat, `099669d` fix-whitelist), остальное — docs-коммиты
> ревью/тестера. Вердикт подтверждён повторно: **APPROVED**.
> **Re-run #12 (independent).** Перечитаны TRZ (`02-trz.md`),
> AC (`03-acceptance-criteria.md`), ADR-017, CLAUDE.md. Построчно сверена
> реализация в рабочем дереве (`src/web/app.js`, `src/web/index.html`,
> `src/api/main.py`) с REQ-F-01..F-19 и решениями ADR-017 (P-A, O-B,
> C-A, R-A, U-A, A-A, M-A). Содержательные коммиты фичи (`5be81f9` feat,
> `099669d` fix-whitelist) уже в `main`; ветка `feature/ET-013-z9-z11-z8`
> относительно `main` содержит **только docs** (`12-review.md`,
> `13-test-report.md`) — `src/`/`tests/` идентичны merged-состоянию.
> Unit-тесты перезапущены локально — **17/17 PASS (0.03 s)**. Вердикт
> подтверждён повторно: **APPROVED**.
## TL;DR
- **Branch:** `feature/ET-013-z9-z11-z8`
- **Branch:** `feature/ET-013-z9-z11-z8` (фича уже в `main`; в ветке — docs).
- **Содержательные коммиты:** `5be81f9` (feat: zoom-aware paint),
`099669d` (fix: whitelist `tri` — фикс F-1 из v1).
- **Scope:** zoom-aware paint (hillshade/TRI) на z9-z11, понижение
`099669d` (fix: whitelist `tri`).
- **Scope:** zoom-aware paint hillshade/TRI на z9-z11, понижение
UI-минзума hillshade z10→z9, обратно-совместимое расширение
`applyTerrainLayer`, расширение backend-whitelist на `tri`.
- **P0/P1 findings:** нет.
- **Вердикт:** **APPROVED**.
## Соответствие ТЗ
## Соответствие ТЗ (проверено по коду)
| REQ | Требование | Статус |
|---|---|---|
| F-01 | UI-минзум hillshade `zoom < 10``zoom < 9` | ✅ `app.js` updateHillshadeAvailability |
| F-02 | minzoom source hillshade 9, paint = HILLSHADE_PAINT | ✅ onTerrainCheckbox |
| F-03 | TRI minzoom остаётся 5, paint = TRI_PAINT | ✅ |
| F-04 | `applyTerrainLayer(opacityOrPaint)` обратно-совместимо | ✅ нормализация number→legacy / object as-is |
| F-05/06/07 | HILLSHADE_PAINT: opacity+contrast interpolate, nearest | ✅ stops точно по TRZ (9:0.65→14:0.40; contrast 9:0.40→14:0.00) |
| F-08/09 | TRI_PAINT: opacity interpolate (z8=0.70, пик z9-z11=0.85), nearest | ✅ |
| F-10 | hint «Зум 10+» → «Зум 9+» | ✅ index.html |
| F-11/12 | порог в updateHillshadeAvailability; контракт onTerrainCheckbox | ✅ persistence/`.active` без изменений |
| F-13/14 | unit-тесты paint + регрессии (Вариант B, Python-парсер) | ✅ 17 тестов |
| F-15 | integration smoke z9 тайлов с `skipif` | ✅ параметризован по hillshade/tri + whitelist-регрессии |
| F-18 | API контракт без изменений (Cache-Control immutable) | ✅ покрыто IT-TILE-CACHE-HEADER |
| F-01/11 | `updateHillshadeAvailability`: `zoom < 9` (app.js:3425) | ✅ старый `< 10` отсутствует |
| F-02 | hillshade minzoom=9, paint=HILLSHADE_PAINT (app.js:2825) | ✅ |
| F-03 | TRI minzoom=5/maxzoom=15, paint=TRI_PAINT (app.js:2826) | ✅ не тронут |
| F-04 | `applyTerrainLayer(opacityOrPaint)` (app.js:3371-3380) | ✅ number→legacy(linear) / object as-is |
| F-05/06/07 | HILLSHADE_PAINT opacity 9:0.65→14:0.40; contrast 9:0.40→14:0.00; nearest | ✅ stops точно по TRZ/ADR |
| F-08/09 | TRI_PAINT opacity z8=0.70, пик z9-z11=0.85, спад до 0.70; nearest | ✅ stops точно |
| F-10 | hint «Зум 9+» (index.html:60) | ✅ |
| F-12 | контракт `onTerrainCheckbox`, persistence `localStorage`, `.active` | ✅ без изменений |
| F-13/14 | unit-тесты (Вариант B, Python-парсер) + регрессии | ✅ 17 тестов, PASS |
| F-15 | integration smoke z9 (`test_terrain_z9_tiles.py`) с `skipif` | ✅ присутствует |
| F-18 | API контракт `/terrain/{layer}/{z}/{x}/{y}.png`, `Cache-Control: immutable` | ✅ сохранён (main.py:1260) |
| F-19 | style.json/style-dark.json/app.css/config не тронуты | ✅ diff чист |
## Соответствие ADR-017
- Выбран вариант **P-A (frontend paint-калибровка)** — реализация ему
следует точно: zoom-aware `interpolate` по `['zoom']`, 0 перегенерации
тайлов, 0 новых слоёв/источников/endpoint'ов. ✅
- Реализация точно следует **P-A** (frontend paint-калибровка): paint
zoom-aware через `interpolate ['linear'] ['zoom']`, 0 перегенерации
тайлов, 0 новых слоёв/источников. ✅
- O-B (linear-stops), C-A (contrast только hillshade), R-A (`nearest`
глобально), U-A (UI-порог z9), A-A (обратно-совместимая сигнатура),
M-A (константы в `app.js`) — все соблюдены. ✅
- Отклонённые «жирные» альтернативы (z-factor 2.5, raster-dem,
theme-specific paint) не затронуты — корректно вынесены в follow-up. ✅
theme-specific paint) корректно вынесены в follow-up (TD-1..TD-5). ✅
## Findings
| # | Severity | Файл | Описание | Статус |
|---|---|---|---|---|
| F-1 | (resolved) | `src/api/main.py:1252` | Whitelist endpoint'а не включал `tri`, хотя фронт его запрашивает (404 в dev без nginx). | Исправлено в `099669d`, покрыто регрессией IT-TILE-TRI-WHITELIST. |
| N-1 | P3 (info) | `src/api/main.py` | TRZ §2 формально декларировал backend «без изменений», но фикс F-1 — необходимая корректная правка (TRI был latent-broken в dev). Документирована в коде и тесте. Не дефект. | Принято. |
| F-1 | (resolved) | `src/api/main.py:1252` | Whitelist endpoint'а не включал `tri`404 в dev без nginx. | Исправлено в `099669d`, документировано, покрыто integration-регрессией. |
| N-1 | P3 (info) | `src/api/main.py` | TRZ §2 декларировал backend «без изменений», но фикс F-1 — необходимая корректная правка (TRI был latent-broken в dev). Контракт endpoint'а (URL, коды, `Cache-Control`) не нарушен → REQ-F-18 соблюдён. Не дефект. | Принято. |
## Качество кода
- Сигнатура `applyTerrainLayer` расширена обратно-совместимо; ветвление
`typeof opacityOrPaint === 'number'` корректно собирает legacy-paint
(`raster-opacity` + linear) и пробрасывает object as-is. JSDoc обновлён.
- Константы `HILLSHADE_PAINT`/`TRI_PAINT` вынесены рядом с
`TERRAIN_BASE_URL`, с пояснением логики stops конфигурируемость через
env/config справедливо отвергнута (калибровка живёт в коде).
- `applyTerrainLayer` расширен обратно-совместимо; ветвление
`typeof opacityOrPaint === 'number'` собирает legacy-paint
(`raster-opacity` + `linear`) либо пробрасывает object as-is. JSDoc/комментарии на месте.
- `HILLSHADE_PAINT`/`TRI_PAINT` вынесены рядом с `TERRAIN_BASE_URL` с
пояснением логики stops; конфигурируемость через env/config справедливо
отвергнута (калибровка живёт в коде).
- Дублирования, необработанных ошибок, мёртвого кода не выявлено.
## Качество тестов
- **Unit (17):** покрывают opacity/contrast stops, монотонность,
`nearest`, регрессию z8=0.70, пик z9-z11≥0.80, обратную совместимость
- **Unit (17):** opacity/contrast stops, монотонность, `nearest`,
регрессия z8=0.70, пик z9-z11≥0.80, обратная совместимость
`applyTerrainLayer`, порог `zoom < 9`, текст hint, число call-site,
привязку minzoom к каждому слою. 17/17 PASS локально.
привязка paint-константы и minzoom к каждому слою. Парсер устойчив к
пробелам/переносам. **17/17 PASS локально (0.03 s).**
- **Integration:** TestClient против `src.api.main:app`; тайло-зависимые
кейсы помечаются `skipped` (PH-6 данные не в repo), а whitelist/404
регрессии работают всегда. Парные проверки «known layer → 404 Tile not
found» vs «unknown → 404 Unknown layer» — аккуратно различают по телу.
кейсы `skipped` при отсутствии PH-6 данных, whitelist/404-регрессии
работают всегда.
## Вердикт
@@ -105,5 +100,5 @@ related:
адекватны и зелёные. **APPROVED.**
Ручная/визуальная приёмка (AC-03..AC-13, AC-19, AC-21) и сетевая
регрессия M-10 — зона ответственности этапов Тестирование/Деплой
(см. `13-test-report.md`, `14-deploy-log.md`), вне content-review кода.
регрессия M-10 — зона этапов Тестирование/Деплой (см. `13-test-report.md`,
`14-deploy-log.md`), вне content-review кода.