13 KiB
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; приnochangelog не требуется и не тронут — соответствует правилу. - Имя ветки
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 нет.