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

97 lines
6.2 KiB
Markdown

# 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**
С оговоркой о независимости из первого раздела.