Files
houseplan-card/docs/reviews/CODE-REVIEW-390-r1.md
T
Matysh a47ec97a04 docs: self-review document for #390
Саморевью по указанию владельца, с оговоркой о независимости. Одна находка
Low на себя: утверждение «эмит тот же» в сообщении cbf5cc1b неверно —
побайтовая сверка нормализованных сборок показала расхождение в одном месте.
Поведение при этом тождественно, разбор в документе.

Отдельно разобрано, почему восемь разошедшихся golden-сцен не из этого
коммита.

Issue: #390
User-Visible: no
2026-08-30 19:29:13 +03:00

6.2 KiB

CODE-REVIEW-390-r1

Скоуп

Issue #390, коммит cbf5cc1b «fix: type the five any that slipped past the gate». Класс A (src/**) плюс сгенерированное (dist/**, custom_components/houseplan/frontend/**).

Оговорка о независимости. Это саморевью по прямому указанию владельца: автор и ревьюер — одна сессия. По PROCESS.md §6 ревьюер обязан быть свежей сессией без контекста реализации; здесь это условие не выполнено, и вес вердикта соответственно ниже. Независимое ревью остаётся доступным.

Что проверено

Проверка Результат
npm run typecheck зелёный
npm test 1635 pass, 0 fail
npm run build, bundle-sync, bundle-tree 8 ассетов, три копии совпадают
npm run bundle:budget 281785 B gzip при бюджете 300000, запас 18215
node scripts/no-new-any.mjs по диапазону чисто
Job «Фронтенд» в CI, прогон #2140 success

Не прогонялись: golden (в песочнице Chromium 149 против закреплённого 151), браузерные смоки, backend-харнесс. В CI на этом коммите смоки и фронтенд зелёные.

Находки

Low-1. Утверждение в сообщении коммита неверно

Коммит утверждает: «Поведение не меняется: аннотации типов стираются, эмит тот же». Первая половина верна, вторая — нет.

Сверка проведена побайтово: собранные деревья cbf5cc1b^ и cbf5cc1b нормализованы (отпечаток исходников и content-hash в именах чанков заменены на константы) и сравнены. Семь чанков из восьми совпали. Восьмой, houseplan-editor-runtime, разошёлся в одном месте:

до : const e=Array.isArray(s?.identifiers?.[0])?s.identifiers[0][0]:null;
пос: const e=s?.identifiers?.[0],i=Array.isArray(e)?e[0]:null;

Причина — введённая мной временная переменная в _registryIntegrations(). Эмит изменился, потому что изменился код, а не только типы.

Поведение при этом тождественно. Исходный вариант вычисляет identifiers[0] дважды: под optional chaining в проверке и без него при чтении. Второе обращение безопасно ровно тогда, когда Array.isArray вернул true. Мой вариант вычисляет один раз и читает то же значение. Разница видна только при геттере с побочным эффектом, чего в реестре HA нет — это словарь данных из MQTT/WS.

Решение ревьюера: снято с записью. Переписывать код ради побайтового совпадения эмита бессмысленно; исправляется утверждение, а не код. Запись здесь и есть исправление.

Урок общий: «эмит тот же» — это измеряемое утверждение, и мерить его надо до того, как оно попадёт в сообщение коммита, а не после.

Golden: восемь разошедшихся сцен — не из этого коммита

На прогоне #2140 (cbf5cc1b) golden показала восемь different, все device-inbox / device-dialog / toggle-entity. Проверено, что коммит к ним непричастен:

  1. История прогонов. Golden последний раз была зелёной на #2090. Дальше #2094 и #2110 показывали different по furniture-transform-light/dark (работа #383), затем девять прогонов подряд golden пропускалась, и первым исполнением после паузы стал #2140. То есть восемь сцен разошлись где-то внутри паузы, а не на моём коммите.
  2. Причина видна в диффах. 2e30daa3 («test: include device history icons in demo harness») меняет demo/srv/assets/icons.js — набор иконок самого стенда, с которого снимаются кадры. bdf81fad добавляет UI истории позиций в диалог устройства. Обе работы задевают ровно те поверхности, что в списке.
  3. Мой дифф их задеть не мог. Единственное изменение эмита — временная переменная внутри _registryIntegrations(), функции, которая собирает список интеграций для фильтра. Она не участвует в отрисовке лотка, диалога устройства и попапа цвета — а они в списке разошедшихся.

Приёмка этих восьми — отдельное решение владельца по артефакту CI, к #390 отношения не имеет.

Продуктовый вопрос

Пользователь не увидит ничего: изменение типовое, тексты, разметка и логика те же. User-Visible: no проставлен верно.

Вердикт

Вердикт: зелёный · цикл r1/4 · High: 0 · Medium: 0 · Low: 1 → снята с записью · Документ: docs/reviews/CODE-REVIEW-390-r1.md

С оговоркой о независимости из первого раздела.