mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-02 12:49:56 +00:00
151 lines
14 KiB
Markdown
151 lines
14 KiB
Markdown
# Код-ревью #122 — Isometric Stage 2: hidden visual polish (r2)
|
||
|
||
- Issue: https://github.com/Matysh/houseplan-card/issues/122
|
||
- Спецификация: `docs/specs/122-isometric-stage2.md` (SPEC-REVIEW-122-r1: green)
|
||
- Предыдущий цикл: `docs/reviews/CODE-REVIEW-122-r1.md` — красный, High: 2, Medium: 1 → #134
|
||
- Диапазон: `git diff origin/dev...HEAD`, новый коммит цикла —
|
||
`ef3cc98` (`fix: preserve isometric fallback rendering`), поверх `42b3f44`
|
||
(`feat: add hidden isometric stage 2`), `76ce755`/`4c73e2c`/`e13215c` (ТЗ и
|
||
документы ревью)
|
||
- Роль: ревьюер кода (свежая сессия, без контекста реализации и без контекста
|
||
сессии r1)
|
||
- **Вердикт: зелёный · цикл r2/4 · High: 0 · Medium: 0**
|
||
|
||
## Скоуп
|
||
|
||
Единственный продуктовый коммит цикла — `ef3cc98`. Класс файлов: A
|
||
(`src/houseplan-card.ts`, 13 insertions/4 deletions — два места: `_baseVb()` и
|
||
основной `<svg>`/`<g>` блок рендера плана) + B (`test/isometric-contract.test.mjs`,
|
||
+5 строк) + C (`docs/ISOMETRIC.md`, `docs/adr/122-isometric-stage2-composition.md`)
|
||
+ D (`dist/houseplan-card.js`, `custom_components/houseplan/frontend/houseplan-card.js`,
|
||
`demo/srv/assets/houseplan-card.js` — все три пересобраны и включены в тот же
|
||
коммит). Диапазон узкий и точечный: правка адресует ровно High-1 и High-2 из r1,
|
||
`demo/smoke_isometric_contract.mjs` и `demo/smoke_isometric_live_touch.mjs` в этом
|
||
коммите не менялись (они уже были частью `42b3f44`).
|
||
|
||
Трейлеры `ef3cc98`: `Issue: #122`, `User-Visible: no` — корректно, фича
|
||
по-прежнему за скрытым Labs-флагом `iso`, публичный changelog не требуется.
|
||
|
||
## Как проверялось
|
||
|
||
| Гейт | Команда | Результат |
|
||
|---|---|---|
|
||
| Typecheck | `npx tsc --noEmit` | green, без вывода |
|
||
| Unit | `npm test` | green, 766/766 |
|
||
| Build | `npm run build` | green |
|
||
| Синхронизация 3 копий бандла | `cmp dist/houseplan-card.js custom_components/houseplan/frontend/houseplan-card.js` и то же для `demo/srv/assets/houseplan-card.js` | **обе команды green** — байт-в-байт совпадают. High-1 из r1 закрыт |
|
||
| `npm run golden:verify` (диф меняет рендер — обязателен) | после `npm run build` + `cp dist/houseplan-card.js demo/srv/assets/houseplan-card.js` | 45/50 сценариев `passed`; 5 `different` — все пять из семейства «непринятые Iso-эталоны Stage 2» (`isometric-geometry-view-dark/light`, `isometric-live-layers-dark`, `isometric-touch-kiosk-dark`, `isometric-large-warm-remount-dark`), что и предсказывал §12.3 ТЗ и r1. **`isometric-no-borders-dark` теперь `passed`** (High-2 закрыт), **`large-house-zoom-250-dark` теперь `passed`** (Medium-1/#134 регрессия исчезла тем же коммитом) |
|
||
| Повтор `golden:verify` для этих двух сценариев | тот же прогон второй раз | оба снова `passed` — детерминированно, не флейк |
|
||
| Целевые браузерные смоки (названы в AC1/AC5-AC7/AC9-AC11 и напрямую тронуты правкой `_baseVb`/рендера) | `node demo/smoke_isometric_contract.mjs`, `node demo/smoke_isometric_live_touch.mjs` (после того же build+copy) | оба green; в `live_touch` явно проверяется `noBordersUsesFloorSymbols: true` и `visibleBordersRestoreStage2: true` — оба режима show_borders исполнены в реальном DOM, не только прочитаны |
|
||
| Трейлеры коммита | `git log --format=... ef3cc98` | `Issue: #122`, `User-Visible: no` — оба присутствуют и терминальны |
|
||
| Backend | не прогонялся | правок в `custom_components/**/*.py` нет — не применимо |
|
||
| Performance (`large-house-isometric-v1`) | не прогонялся | как и в r1 — pre-beta гейт, заблокирован #124 по решению владельца, вне скоупа этого код-ревью |
|
||
|
||
**Чего не проверял и почему:** полный набор из 127 браузерных смоков — правка
|
||
цикла ограничена двумя точками в одном файле плюс правкой рендера, которую уже
|
||
покрывают целевые смоки/golden; `python -m pytest tests_backend` — нет
|
||
Python-правок; принятие golden-эталонов Stage 2 Iso — не роль ревьюера и не
|
||
требуется до pre-beta (§12.3 ТЗ, решение владельца); дифференциальный прогон на
|
||
`origin/dev` — не повторялся отдельно в этом цикле, т.к. `origin/dev` не менялся
|
||
с r1 и там же было доказано, что оба сценария чисты на dev (причинность уже
|
||
локализована в диффе задачи).
|
||
|
||
## Находки
|
||
|
||
Отсутствуют. Оба High из r1 закрыты, новых High/Medium не найдено.
|
||
|
||
## Что проверено и корректно
|
||
|
||
- **High-1 (три копии бандла)** — закрыт. `cmp` подтверждает байт-в-байт
|
||
идентичность всех трёх копий после `npm run build`; коммит `ef3cc98` содержит
|
||
пересобранные `dist/houseplan-card.js`, `custom_components/houseplan/frontend/houseplan-card.js`
|
||
и `demo/srv/assets/houseplan-card.js` внутри себя же (не отдельным коммитом) —
|
||
правило «сгенерированное в том же коммите» соблюдено.
|
||
- **High-2 (`show_borders:false` в Iso ломал пиксельный контракт)** — закрыт.
|
||
Причина по коду (`src/houseplan-card.ts:4558-4573`, `_baseVb()`): при
|
||
`!showBorders` рамка теперь строится как `projectedFrame({ rect: flat,
|
||
wallHeight: ISO_WALL_HEIGHT })` — это в точности старая Stage-1 проекция без
|
||
вклада Stage 2 floor/opening-геометрии, а не безусловный `unionRect(flat,
|
||
isoOpeningBounds())`, который ломал сцену в 42b3f44. Синхронно с этим основной
|
||
`<svg>`/внутренний `<g>` (строки ~14181-14187) теперь используют
|
||
`isoLayers?.structural` вместо `iso` как условие для класса
|
||
`iso-floor-scene`/`transform`/viewBox — то есть в ветке «iso активен, но
|
||
структура скрыта» контент рендерится без Stage-2-трансформации, тем же путём,
|
||
что и Stage 1. Доказано исполнением: `golden:verify` даёт `passed` для
|
||
`isometric-no-borders-dark` с нулевым отличием от принятого Stage-1 baseline,
|
||
повторено дважды детерминированно; смок `live_touch` отдельно подтверждает
|
||
`noBordersUsesFloorSymbols: true` в реальном DOM.
|
||
- **Атрибут `class` внешнего `<svg>`** (`class=${isoLayers?.structural ? 'plan-svg' : nothing}`,
|
||
новая связка по сравнению с прежним безусловным `class="plan-svg"`) —
|
||
прочитано и проверено: `.plan-svg { z-index: 1; }` в `src/styles.ts:472`
|
||
имеет смысл только относительно братских `.iso-underlay-svg`/`.iso-shadows-svg`/`.iso-walls-svg`,
|
||
а те сами рендерятся строго под условием `iso && isoLayers?.structural`
|
||
(`src/houseplan-card.ts:14176`, `:14394`) — то есть ровно тогда же, когда
|
||
`plan-svg` получает класс. Вне Flat и вне structural-iso конкурирующих слоёв
|
||
с явным z-index нет, поэтому потеря класса не меняет порядок отрисовки.
|
||
Единственное внешнее использование селектора `.plan-svg` — `demo/smoke_isometric_contract.mjs:49`,
|
||
и там он опрашивается только в сценарии с `show_borders:true` (структурный),
|
||
где класс присутствует. Подтверждено исполнением: ни один из 44 не-iso
|
||
golden-сценариев (Flat, редакторы, lighting, tray, split-wall и т. д.) не
|
||
показал отличий.
|
||
- **Medium-1 / #134 (регрессия `large-house-zoom-250-dark` при выключенном
|
||
Labs)** — не было целью этого коммита (правка адресует High-1/High-2), но
|
||
сценарий проходит чисто тем же коммитом. Открытая гипотеза из r1 (обёртка
|
||
`<g class=${iso ? ... }>` как источник 0.1%-регрессии) теперь снята
|
||
экспериментально: смена условия с `iso` на `isoLayers?.structural` на этой же
|
||
строке устранила и её. Issue #134 остаётся открытым (`S1-new`) — закрытие
|
||
issue не входит в роль ревьюера кода (§6 PROCESS.md), но по факту дефект,
|
||
который он описывает, воспроизводимо больше не проявляется в этом дереве;
|
||
стоит отметить это релиз-менеджеру/автору при обработке #134, а не оставлять
|
||
как забытый висящий тикет.
|
||
- **AC7 (`unit`+`smoke`+`golden`)** — выполнен: `hide_openings` не трогает
|
||
cuts/state/light (не менялось в этом коммите, покрыто существующими тестами
|
||
из `npm test`); `show_borders:false` восстанавливает Stage-1 no-volume сцену —
|
||
подтверждено golden. **AC15** (Flat и `isometric-no-borders-dark` неизменны) —
|
||
выполнен для не-iso baseline; Stage-2-Iso-эталоны намеренно не приняты на
|
||
этом этапе (§12.3 ТЗ) и остаются `different` — соответствует контракту, а не
|
||
находка. **AC16** (три копии бандла байт-в-байт + зелёные typecheck/unit/build)
|
||
— выполнен, доказано `cmp`.
|
||
- **`test/isometric-contract.test.mjs`** (+5 строк) — источниковые
|
||
regex-проверки на буквальный текст новых веток `_baseVb()` и рендера
|
||
(`if (!this._spaceDisplayForRender().showBorders)`,
|
||
`projectedFrame({ rect: flat, wallHeight: ISO_WALL_HEIGHT })`,
|
||
`preserveAspectRatio=...'xMidYMid meet' : 'none'`, и т. д.). Тест умеет
|
||
падать при откате этих строк (буквальное совпадение с исходником), но сам по
|
||
себе не проверяет визуальный результат — это делает `golden:verify`
|
||
отдельно. Стиль согласован с уже существующими source-grep проверками того
|
||
же файла (AC8/AC9/AC14 в r1). Оценка: приемлемо как дополнительная страховка,
|
||
не как единственное доказательство AC7/AC15 — реальное доказательство даёт
|
||
golden.
|
||
- **Документация** (`docs/ISOMETRIC.md`, ADR) — обновлена в том же коммите,
|
||
описывает новое поведение точно (Stage-1 projected frame возвращается в
|
||
no-borders ветке вместо union с Stage-2-геометрией); расхождений с кодом не
|
||
найдено.
|
||
|
||
## Чего не проверял
|
||
|
||
- Полные 127 браузерных смоков — правка узкая (две точки в одном файле), вне
|
||
необходимости, определяемой diff'ом; прогнаны два целевых, прямо относящихся
|
||
к затронутому коду.
|
||
- `python -m pytest tests_backend` — нет изменений в Python.
|
||
- `large-house-isometric-v1` performance — вне гейта код-ревью, заблокирован
|
||
#124 (решение владельца, повторяет позицию r1).
|
||
- Принятие golden-эталонов Stage 2 Iso (5 `different`-сценариев) — не роль
|
||
ревьюера; это ожидаемое, задокументированное в ТЗ состояние, а не находка.
|
||
- Отдельный дифференциальный прогон на `origin/dev` в этом цикле — не
|
||
повторялся: `origin/dev` не изменился с r1, где причинность уже была
|
||
локализована в диффе задачи, а не в окружении/Chromium.
|
||
|
||
## Итог
|
||
|
||
Оба блокирующих High из r1 закрыты одним точечным коммитом (`ef3cc98`):
|
||
пересборка всех трёх копий бандла восстановлена и подтверждена `cmp`
|
||
(High-1); ветвление рамки/трансформации в `show_borders:false` теперь
|
||
воспроизводит принятую Stage-1 no-volume сцену вместо объединения с
|
||
Stage-2-геометрией, что подтверждено чистым `golden:verify` дважды подряд
|
||
(High-2). Ранее заведённая Medium-находка (#134) как побочный эффект того же
|
||
исправления тоже перестала воспроизводиться в golden — issue стоит закрыть
|
||
или, как минимум, обновить при её обработке, но это не входит в роль
|
||
ревьюера кода. Новых High/Medium-находок нет. Цикл r2/4 закрывается зелёным
|
||
вердиктом.
|