mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-02 04:38:55 +00:00
139 lines
20 KiB
Markdown
139 lines
20 KiB
Markdown
# Код-ревью #459 — заход r2
|
||
|
||
Настройка «Zigbee links»: подсказка о функции, её ограничениях и легенда цветов, пунктира и стрелок.
|
||
|
||
Ветка `issue/459-zigbee-links-help`, HEAD `50bc1d6955dc59ffbd9c10cc31be26418bf1674d`, база `origin/dev` = `7320937f627f18d0f473ca526d68906bea620a27` (после ребейза; `#457` уже влился в `dev`).
|
||
|
||
## Почему разбор ПОЛНЫЙ, а не по дельте
|
||
|
||
Раунд r2 открыт не находкой ревьюера, а ребейзом: код-ревью r1 (`951cbd01`) вынесло **зелёный** вердикт (комментарий 9), но к моменту его публикации `dev` продвинулся на 10 коммитов и слияние конфликтовало (комментарии 10–11). Автор сделал `git rebase origin/dev`, запушил `50bc1d69` и вернул `S7-code-review` (комментарий 12).
|
||
|
||
Ребейз на ушедший вперёд `dev` — это один из явно названных случаев, когда разбор остаётся полным независимо от размера дельты (§7.2, §2.9): база изменилась, а не только правка автора. Поэтому я:
|
||
|
||
1. заново прогнал все дешёвые гейты на текущем `HEAD` (ниже);
|
||
2. заново подтвердил каждый AC самостоятельно (тестом или чтением);
|
||
3. отдельно проверил, что именно изменилось при ребейзе и что — нет.
|
||
|
||
## Материал ребейза: что реально изменилось
|
||
|
||
Побайтовое сравнение продуктовых файлов задачи между `951cbd01` (материал r1) и `50bc1d69` (текущий HEAD):
|
||
|
||
```
|
||
git diff 951cbd0174bb HEAD -- src/hp-zigbee-topology-settings.ts src/i18n/topology.ts
|
||
```
|
||
— **пусто**. Файл-компонент и резолвер `hasTopologyTranslation` не изменились ни на символ.
|
||
|
||
Блок тестов `#459` в `test/zigbee-topology.test.mjs` (от маркера `// #459.` до конца файла) сравнен построчно — **идентичен**. Дифф всего файла между теми же SHA показывает изменения (162 строки), но это тесты `#457`, добавленные в `dev` после `951cbd01`, не пересекающиеся с блоком `#459`.
|
||
|
||
Четыре словаря `topology/{en,ru,de,fr}.json` получили от `#457` три новых ключа (`route_device_not_on_plan`, `route_coordinator_not_on_plan`, `route_other_space`) — не пересекаются со строками `help`/`help_aria` этой задачи и добавлены во все четыре языка одинаково (паритет AC6 не пострадал — проверено гейтом ниже).
|
||
|
||
`scripts/mutation-gate.mjs`: два мутанта `topology-help-*` этой задачи не менялись; `#457` добавил в тот же файл свои четыре мутанта рядом.
|
||
|
||
Конфликт при ребейзе (по словам автора, комментарий 12) был только в производных/документационных файлах: `docs/CHANGELOG*.md` (обе записи, `#457` и `#459`, сохранены — проверил чтением, обе на месте в обоих языках), `docs/images/screenshots.json` (отпечаток источника, пересчитан штатно) и весь закоммиченный бандл (пересобран заново). Я подтвердил это сверкой дифф-статов и содержимого, а не принял на слово.
|
||
|
||
`src/hp-help.ts`, `hp-zigbee-topology-overlay.ts`, `device-presentation.ts`, `logic.ts` — не тронуты ни этой задачей, ни ребейзом (`git diff origin/dev...HEAD` по этим путям пуст). Контракт §5 ТЗ («что не меняется») держится.
|
||
|
||
## Как проверялось
|
||
|
||
Материал — `git log --oneline origin/dev..HEAD` (5 коммитов) и `git diff origin/dev...HEAD` (42 файла: 8 продуктовых/тестовых + генерируемые + документация). Зелёного Validate на `50bc1d69` нет: единственный прогон на этом SHA (33954914944) — **failure**, один упавший джоб «Смоки в браузере (шард 1 из 3)», лог которого называет ровно `FAIL smoke_furniture` — то же самое, что автор описал в комментарии 12 и на что завёл отдельный `#460` (`trivial`, `S6-in-progress`, не про `#459`). Проверил сам, не на слово: `gh run view 33954914944 --log-failed` показывает единственную причину падения — `smoke_furniture`, диф `#459` этот файл не трогает.
|
||
|
||
Поэтому дешёвые гейты прогнал сам, на `50bc1d69`:
|
||
|
||
| Гейт | Результат |
|
||
|---|---|
|
||
| `npx tsc --noEmit` | OK, без ошибок |
|
||
| `npm test` | **1987 pass / 0 fail / 1 skip** (1988 тестов, `npm run inventory` подтверждает то же число); все 7 тестов `#459` (`AC1, AC2, AC3, AC3b, AC4, AC5, AC6`) — `ok` |
|
||
| `npm run build` | чисто, `git status` после сборки пуст — закоммиченный `dist` byte-for-byte совпадает со свежей сборкой |
|
||
| `npm run bundle:sync` | пересборка + синхронизация `custom_components/houseplan/frontend` и `demo/srv/assets`; `git status` после — чисто, три копии совпадают |
|
||
| `npm run bundle:budget` | initial View **297 496 Б** (потолок 298 000±2000, budget 300 000) — совпадает с заявленным автором числом; потолок не поднимался; предупреждение о низком запасе — унаследованный долг `#367`, не новый |
|
||
| `node scripts/check-docs.mjs` | passed, 7 файлов, 12 внешних ссылок |
|
||
| `node scripts/mutation-gate.mjs --check` | 463 якоря (совпадает с заявленным автором «Реестр 457 → 459»), оба мутанта `topology-help-*` — `ok`; один посторонний `FAIL` — backend-гейт `tests_backend/test_ha_websocket.py` падает из-за отсутствующего локально модуля `pytest`, окружение не задевает `custom_components/**/*.py` (не тронут этой задачей) |
|
||
| `node scripts/mutation-gate.mjs --id=topology-help-renders-without-aria` | **лично применил мутацию** — целевой тест покраснел, дерево вернулось чистым |
|
||
| `node scripts/mutation-gate.mjs --id=topology-help-drops-arrow-legend` | то же — покраснел, поймано |
|
||
| `node demo/smoke_zigbee_topology_hover.mjs` (AC8) | **OK**, 21/21 проверок `true` — оверлей, цвета, стрелки, default-off, ленивая загрузка не изменились |
|
||
| `node scripts/smoke-select.mjs --base origin/dev --head HEAD` | **НЕОПРЕДЕЛЁННОСТЬ** — 2 изменённых файла `src/**`, 7 символов (`DICTIONARIES`, `Lang`, `TopologyI18nKey`, `_help`, `hasTopologyTranslation`, `langOf`, `topologyT`), ни один не связан ни с одним из 223 смоков доказуемо. Единственный смок, названный в AC (`smoke_zigbee_topology_hover`, AC8), прогнан отдельно выше вручную — инструмент про него не обязан знать, так как оверлей сам не менялся |
|
||
| `npm run golden:verify` | **153/153 passed, 0 расхождений** — включая `general-color-popover-desktop-en`, единственную сцену, задетую этой задачей (принятый на r1 эталон пережил ребейз без нового расхождения) |
|
||
| `node --test test/single-source-numbers.test.mjs` | 3/3 pass (общий гейт «одно число — один источник», диф его не расширяет и не нарушает) |
|
||
|
||
Не прогонял: `python -m pytest tests_backend` (диф не трогает `custom_components/**/*.py`); полные performance-профили (не названы в AC, диф не задевает чувствительные пути); `npm run invariants` (диф не касается стен/`layout`/`marker.space`/`open_spans` — задача только про словарь и один компонент настройки, геометрия не затронута).
|
||
|
||
## Проверка по AC — заново, не по памяти r1
|
||
|
||
- **AC1** — `render()` кладёт `${this._t('title')}${this._help()}` в `.section` (строка 187 файла, не изменилась с r1), не в `.toggle`. Тест `подсказка вызывается из блока настройки топологии` проверяет именно эту разметку — прогнан, зелёный. Открытие по наведению/фокусу/клику — поведение самого `hp-help.ts` (не тронут).
|
||
- **AC2** — `_help()` проверяет `hasTopologyTranslation(lang,'help')` и `...'help_aria'` до рендера, иначе `nothing`. Мутант `topology-help-renders-without-aria` лично применён и пойман (см. таблицу выше).
|
||
- **AC3 / AC3b** — тест `подсказка называет все шесть пунктов легенды` проверяет 10 паттернов по нормативной ru-строке (LQI, 40, 180, пунктир, исходящая→координатор, входящие, «без стрелки», «подпись на конце стрелки», «отсутствие стрелки»); отдельный тест ловит оговорку о приближённости (`дерево маршрут`, `не путь пакета`). Прогнаны — зелёные. Мутант `topology-help-drops-arrow-legend` лично применён и пойман.
|
||
- **AC4** — тест импортирует `lqiColor` из собранного `test-build/logic.js` и берёт `hue(40)=0`, `hue(180)=120` из функции, затем ищет те же числа в тексте — границы не захардкожены в тесте отдельной константой. Прогнан — зелёный.
|
||
- **AC5** — для всех четырёх словарей: нет `\n` в `help`, обе строки (`help`, `help_aria`) непустые. Прогнан — зелёный.
|
||
- **AC6** — гейт паритета ключей и плейсхолдеров четырёх словарей против английского; проверил, что три новых ключа `route_*` от `#457` не сломали паритет (все четыре языка получили одинаковый набор). Прогнан — зелёный.
|
||
- **AC7** — `core-file-budget` не задет (файл не входит в список ядровых), `bundle:budget` — 297 496 Б, на 2 Б меньше `dev` по словам автора; лично прогнал и подтвердил число, потолок не поднимался.
|
||
- **AC8** — `smoke_zigbee_topology_hover.mjs` лично прогнан, все проверки `true`.
|
||
|
||
Утверждённый нормативный текст §4.1 (654 знака ru) сверен посимвольно (`len(help)==654` в Python) — совпадает дословно с текстом, зафиксированным владельцем в теле issue. Переводы en/de/fr прочитаны целиком: каждый несёт все пункты легенды и оговорку о приближённости без потерь смысла.
|
||
|
||
## Закрытие раунда r1
|
||
|
||
Раунд r1 (комментарий 9, документ `docs/reviews/CODE-REVIEW-459-r1.md`, SHA `951cbd01`) вынес **зелёный** вердикт без Medium — переоткрытия по существу не было, только вынужденный технический возврат из-за конфликта слияния (комментарий 11). Формальных «находок к исправлению» из r1 нет; ниже — судьба трёх Low, отмеченных там:
|
||
|
||
| Находка r1 (Low) | Статус в r2 |
|
||
|---|---|
|
||
| Отчёт реализации называл «шесть новых тестов», в дифе — семь | не тронуто и не требовалось: чисто редакторская неточность отчёта, к коду отношения не имеет |
|
||
| Новый `_help()` не проставляет `data-help-key` (в отличие от `houseplan-editor-runtime.ts:1232`, `houseplan-onboarding-runtime.ts:58`) | **не исправлено, по-прежнему так** — проверил чтением всех трёх мест повторно; не блокирует ни один AC, поведение кружка не страдает |
|
||
| Гейт паритета AC6 лёг в `test/zigbee-topology.test.mjs`, а не в `test/i18n.test.mjs`, как называли «Затронутые файлы» ТЗ | не тронуто — организационное расхождение, гейт работает (перепроверил падением не требовалось: тест сам содержит зелёную/фейлящую пару сценариев) |
|
||
|
||
Ни одна не блокирует и в r2 не эскалируется — все три и раньше были приняты без правки с запиской, а код с тех пор не менялся.
|
||
|
||
## Унаследовано из r1 без повторного построчного разбора
|
||
|
||
Ниже — то, что я не выводил заново с нуля, а принял на основании доказанной побайтовой идентичности кода (раздел «Материал ребейза» выше) и полного документа `docs/reviews/CODE-REVIEW-459-r1.md` (SHA `951cbd01`):
|
||
|
||
- построчная сверка контракта §1–§5 ТЗ с кодом (импорт `hp-help`, локальный `_help()`, namespace `topologyT`, отказ от переиспользования редакторского `_help()`) — код не менялся, вывод r1 в силе;
|
||
- перевод легенды на en/de/fr сверен вручную построчно в r1; я самостоятельно перечитал все три файла в этом раунде (раздел AC выше) и подтверждаю тот же вывод независимо, а не только по ссылке;
|
||
- откат (§ ТЗ «Откат») — не проверялся заново, код рендера и словарей не менялся, ревертить по-прежнему нечего кроме вызова хелпера.
|
||
|
||
Каждый AC при этом я подтвердил **заново сам** (гейты и тесты выше), а не принял на слово — «унаследовано» здесь относится только к смысловому построчному разбору контракта, не к проверяемости.
|
||
|
||
## Что проверено и корректно
|
||
|
||
- Все восемь AC доказаны прогонами на текущем `HEAD`, не на памяти о r1.
|
||
- Оба мутанта реально ловятся — применил лично, не поверил реестру.
|
||
- `golden:verify` — 153/153, включая сцену, задетую этой задачей и ребейзом.
|
||
- Ребейз не потерял ни одной записи `CHANGELOG`, не сломал паритет словарей, не задел оверлей/`hp-help`/`logic.ts`.
|
||
- Единственный красный CI на `50bc1d69` — независимо подтверждённый предсуществующий флейк `smoke_furniture` (`#460`), не имеющий отношения к `#459` и не тронутый этим диффом.
|
||
- Трейлеры коммитов: `Issue: #459` на всех пяти, `User-Visible: yes` в `feat`-коммите сопровождается правкой обоих changelog в том же коммите; `Release:`/`Baseline-Reviewed:` на коммитах, трогающих `demo/golden/baselines/**`.
|
||
|
||
## Чего не проверял и почему
|
||
|
||
- `python -m pytest tests_backend` — `custom_components/**/*.py` в дифе нет.
|
||
- Полные performance-профили — не названы в AC, диф не задевает чувствительные к перфу пути (текст словаря и один компонент настройки).
|
||
- `npm run invariants` — диф не касается стен, `layout`, `marker.space`, `open_spans` или иных геометрических ссылок.
|
||
- Остальные 222 браузерных смока сверх названного в AC8 — инструмент отбора вернул НЕОПРЕДЕЛЁННОСТЬ, тематически ни один не относится к namespace-компоненту без побочных эффектов на других поверхностях.
|
||
|
||
## Итог
|
||
|
||
Продуктовый код и тесты этой задачи не изменились ни на символ со времени зелёного r1 — ребейз задел только производные файлы и документацию, и это подтверждено сравнением, а не заявлено. Полный самостоятельный прогон гейтов на текущем `HEAD` (`50bc1d69`) — тесты, сборка, бюджет, документация, мутанты, golden, целевой смок — зелёный. Восемь AC доказаны заново. Три Low из r1 остаются в силе, без блокировки. Красный CI на этом SHA — подтверждённо посторонний флейк, заведённый отдельным issue.
|
||
|
||
**Вердикт: зелёный.**
|
||
|
||
---
|
||
|
||
<!-- material-anchors: подготовлено ревьюером r2 -->
|
||
|
||
## Материал раунда
|
||
|
||
- Ветка: `issue/459-zigbee-links-help`, HEAD `50bc1d6955dc59ffbd9c10cc31be26418bf1674d`.
|
||
- База: `origin/dev` = `7320937f627f18d0f473ca526d68906bea620a27`.
|
||
- Предыдущий материал (r1, зелёный): `951cbd0174bbbc4cb069cf5f8832da8cc49f2ace`, документ `docs/reviews/CODE-REVIEW-459-r1.md`.
|
||
- Побайтовое сравнение продуктовых файлов `951cbd01`→`50bc1d69`: `src/hp-zigbee-topology-settings.ts`, `src/i18n/topology.ts` — пусто (идентичны); блок `#459` в `test/zigbee-topology.test.mjs` — идентичен построчно.
|
||
|
||
---
|
||
|
||
<!-- material-anchors: сгенерировано конвейером (#414) -->
|
||
|
||
## Материал раунда
|
||
|
||
- Ветка: `issue/459-zigbee-links-help`, коммит `50bc1d6955dc` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
|
||
- Дерево материала: `4cb9c23fd0ca54ef2841de18ac1b353fc54c5c3c`
|
||
```
|
||
git log --all --format='%H %T' | grep 4cb9c23fd0ca
|
||
```
|