Files
houseplan-card/docs/reviews/CODE-REVIEW-176-r1.md
T
2026-08-19 13:24:29 +00:00

147 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CODE-REVIEW-176-r1
Issue: #176 — удалить мёртвый код старого инструмента Partition после #173.
Трек: `small` (лёгкий), тип `tech-debt`, `User-Visible: no`.
Ревьюер ≠ автор, свежая сессия без контекста реализации.
## Скоуп
Диапазон: `git log --oneline origin/dev..HEAD` → один коммит
`f66e671 refactor: remove dead partition tool state` (`Issue: #176`,
`User-Visible: no`), ветка `issue/176-remove-dead-partition-tool`.
`git diff origin/dev...HEAD --stat`: 16 файлов, +142/−127. Продукт:
`src/houseplan-card.ts`, `src/i18n/en.json`, `src/i18n/ru.json`. Гейты/тесты:
`test/unified-wall-tool-source.test.mjs` (новый), `test/golden-matrix.test.mjs`,
`demo/smoke_free_walls.mjs`, `demo/smoke_plan_snap_overlay.mjs`,
`demo/golden/harness.mjs`. Документация: `docs/STATUS.md`, `docs/TESTING.md`,
`docs/images/screenshots.json` + два PNG. Сгенерированное: три bundle-копии.
Состав в точности совпадает с разделом «Затрагиваемые поверхности» ТЗ —
расширения скоупа нет.
ТЗ (лёгкий трек, тело issue) прошло `SPEC-REVIEW-176-r1` зелёным цветом.
## Как проверялось
| Гейт | Прогнан | Результат |
|---|---|---|
| `npx tsc --noEmit` | да | чисто, без ошибок |
| `npm test` | да | 908/908, совпадает с хендоффом автора |
| `npm run build` + сверка 3 bundle-копий | да | `cmp` dist↔frontend↔demo/srv — идентичны |
| `test/unified-wall-tool-source.test.mjs` изолированно, затем на **дореформенном** `src/houseplan-card.ts`+`en.json`+`ru.json` (снятых из `origin/dev`) | да | на новом коде: 2/2 green; на старом коде (до #176): оба подтеста падают (`title.markup_partition` присутствует, `this._tool === 'partition'` matches) — тест умеет падать |
| `node demo/smoke_unified_wall_tool.mjs` (назван в AC2) | да | все 19 проверок `true`, `OK` |
| `node demo/smoke_free_walls.mjs` (назван в AC2, тронут диффом) | да | все 13 проверок `true`, `OK` |
| `node demo/smoke_plan_snap_overlay.mjs` (назван в AC2, тронут диффом) | да | все 35 проверок `true`, `OK` |
| `node scripts/check-docs.mjs` (без `--external`) | да | «Documentation checks passed (7 files, 10 external links)» — проверяет ровно то, что тронул диффом `screenshots.json` |
| `python -m pytest tests_backend` | нет | диапазон не касается `custom_components/**/*.py` (проверено `git diff --stat -- '*.py'` — пусто) |
| `npm run golden:verify` | нет | диапазон не меняет golden-baseline (`demo/golden/baselines/**` не тронут) и не расширяет визуальный контракт: оба реальных `planSnap`-сценария в `demo/golden/matrix.mjs` уже используют `tool: 'draw'` — сужение допустимых значений в `golden-matrix.test.mjs`/`harness.mjs` не меняет поведение существующих сценариев. Отложено на предрелизный гейт по правилу «полные наборы — гейт релиза, не ревью» |
| Остальные 124 браузерных смока | нет | диапазон касается только draw/partition-веток Plan editor; названные в AC покрывают все тронутые файлы, остальные поверхности (View, Devices editor, sun/light, isometric и т.д.) не задеты диффом |
| Полный производительный профиль | нет | в AC не назван, диффом не затронут (изменение — вычитание мёртвых веток, не новый путь выполнения) |
## Проверка AC по пунктам
**AC1 — «мёртвый tool-state удалён».**
Подтверждено чтением и исполнением. `grep` по `src/houseplan-card.ts` не находит
ни одного сравнения `this._tool` с `'partition'` в любом порядке, самого
`MarkupTool`/`MARKUP_TOOLS` без `'partition'`, метод `_partitionClick` отсутствует.
Диспетчер клика (`_markupClick`, ветка после `'column'`, строка ~6826) падает в
единственный default-путь Walls, ровно как заявлено в контракте №1. Источник
доказательства — `test/unified-wall-tool-source.test.mjs`, который я прогнал и
на новом, и на дореформенном исходнике: тест умеет падать (см. таблицу выше).
**Доказано.**
**AC2 — «совместимость и существующие независимые стены сохранены».**
- Legacy warm-token: `normalizeUnifiedWallTool('partition') === 'draw'`
(`src/wall-face-graph.ts:53-55`) не тронут этим диффом; покрыт существующим
(неизменённым) `test/wall-face-graph.test.mjs:21` и я прогнал `npm test`
зелёным. Проверено чтением цепочки `normalizeMarkupTool` →
`normalizeUnifiedWallTool`, вызываемой из `_restoreViewport` при
`this._tool = normalizeMarkupTool(vp.tool)` (строка 2651) — единственная точка
присвоения `_tool` из внешнего/сохранённого значения.
- Persisted-модель: `space.partitions`, `PartitionCfg`, `kind: 'partition'` у
selection/drag/opening-host, `_partitionDeleteDialog`, `_limitReached('partition')`
(лимит на количество, не tool-state), история `history.partition_add`,
`physical.partition_properties` — все на месте, я перечислил их `grep`ом и
ни один не зависит от `this._tool`.
- Создание независимой стены через завершение открытой Walls-chain, snap
первого/второго клика, pan/pinch/pointercancel, свойства и удаление —
подтверждено исполнением `smoke_unified_wall_tool`, `smoke_free_walls`,
`smoke_plan_snap_overlay` (все green, см. таблицу).
**Доказано.**
**AC3 — «удалены только осиротевшие тексты и тестовый старый API».**
En/ru сверены построчно (`grep` по обоим locale): отсутствуют
`title.markup_partition`, `markup.hint_partition`, `physical.partition_size_title`
— ровно три ключа из ТЗ, включая самостоятельно найденный автором третий; при
этом `markup.partition`, `physical.partition_properties`, `history.partition_add`
присутствуют. Дополнительная проверка вне репозитория подтвердила, что удалённые
ключи не используются больше нигде (`grep` по `*.ts/*.mjs/*.json/*.md` — только
исторические документы ревью). Golden matrix/harness теперь принимают только
`'draw'`; я проверил, что оба реальных `planSnap`-сценария в
`demo/golden/matrix.mjs` уже были на `'draw'`, так что визуальный результат не
меняется (подтверждено чтением, не `golden:verify`). `npm run build` и `cmp`
трёх bundle-копий — зелёные. **Доказано.**
## Побочная находка — не дефект
`docs/images/06-device-editor.png` и `06-device-display-preview.png` изменили
`imageSha256` (не только `sourceSha256`) — на первый взгляд странно для
`User-Visible: no` рефактора Plan editor, раз эти два скриншота относятся к
Device editor. Извлёк оба PNG из `origin/dev` и `HEAD`, сравнил пикселями
(`PIL.ImageChops.difference`): разница ограничена одним пикселем на координате
(1141,18)-(1142,19), отклонение ±1 только по одному каналу — это шум
рендеринга/антиалиасинга при пере-захвате скриншотов, обязательном из-за смены
`sourceFingerprint` (хеш всего `src/**`, а не только тронутых строк), а не
видимое изменение продукта. Остальные 7 скриншотов вообще не изменили
`imageSha256`. Не является находкой — зафиксировано, чтобы объяснить бинарный
diff, а не оставить его без разбора.
## Находки
Нет находок уровня High или Medium. Low не заведено — не найдено ни одного
предмета, который стоило бы фиксировать как Low.
## Что проверено и корректно
- Все обязательные быстрые гейты зелёные (typecheck/test/build+cmp).
- AC1–AC3 доказаны либо автотестом с проверенной способностью падать, либо
прямым исполнением названных в AC браузерных смоков, либо чтением с явной
пометкой.
- Трейлеры коммита корректны: `Issue: #176`, `User-Visible: no`; при `no`
changelog не требуется и не тронут — соответствует правилу.
- Имя ветки `issue/176-remove-dead-partition-tool` соответствует трейлеру.
- Скоуп диффа совпадает с «Затрагиваемые поверхности» ТЗ файл-в-файл; попутных
правок «раз уж я здесь» не найдено.
- Граница «мёртвый tool-code vs живая persisted-модель независимых стен»
выдержана по всему файлу — ни одно использование `kind: 'partition'` /
`space.partitions` не привязано к `this._tool`.
- `docs/TESTING.md` обновлён точно: новая строка про legacy-токен ссылается на
`wall-face-graph.test` — этот тест существовал и до #176 (диффом не тронут),
проверил утверждение `assert.equal(normalizeUnifiedWallTool('partition'), 'draw')`
напрямую в файле.
- `docs/STATUS.md` корректно добавляет #176 в описание текущего цикла бета-4.
## Чего не проверял
- Полный HA-бэкенд-харнесс (`python -m pytest tests_backend`) — диапазон не
трогает `custom_components/**/*.py`, гейт не применим.
- `npm run golden:verify` — не прогонял; аргументация в таблице выше (сужение
контракта не задевает реальные сценарии, подтверждено чтением
`demo/golden/matrix.mjs`). Это сознательное решение, а не молчаливый пропуск;
выполнится штатно на предрелизном гейте.
- Оставшиеся 124 из 127 браузерных смоков — не относятся к тронутым draw/
partition-путям Plan editor; полный набор не запускался, т.к. задача не
задевает все поверхности.
- Performance-профили — не названы в AC и не затронуты диффом (чистое
вычитание недостижимого кода не меняет hot path).
- `node scripts/check-docs.mjs --external` (сетевые ссылки) — прогнан без
`--external`, сетевую часть не гонял, чтобы не делать внешние вызовы из
ревью-сессии; она не зависит от этого диффа (никакие ссылки не менялись).
- Ручного тестирования в браузере не было — по процессу его нет в цикле;
роль ручной проверки здесь выполняет прогон именованных в AC смоков.
## Вердикт
Зелёный. Цикл r1/2 (лёгкий трек, лимит код-ревью — 2). High: 0. Medium: 0.
Находок для возврата или для отдельного issue нет.