Files
houseplan-card/docs/reviews/CODE-REVIEW-269-r1.md
T
2026-08-26 06:10:29 +00:00

111 lines
14 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-269-r1
- **Issue:** [#269](https://github.com/Matysh/houseplan-card/issues/269) — «Показывать сущности» в USER-GUIDE.ru.md расходится с i18n-ключом `marker.show_entities`
- **Трек:** trivial (короткий трек, §5.1)
- **Заход:** r1 (первый) · блокирующих циклов израсходовано 0 из 2 (лимит трек-trivial)
- **Материал:** `git log --oneline origin/dev..HEAD` → один коммит `676610c0` (`fix: align marker.show_entities with the user guide wording (#269)`)
- **SHA на момент вердикта:** `676610c0cdc41709823d431bca39b2a536c18a5f` (сверено `git rev-parse HEAD` непосредственно перед подведением итогов)
- **Ветка:** `issue/269-show-entities-term`
## Скоуп
Диапазон `origin/dev...HEAD` — 6 файлов:
```
custom_components/houseplan/frontend/houseplan-card.js | 4 ++--
dist/houseplan-card.js | 4 ++--
docs/CHANGELOG.md | 4 ++++
docs/CHANGELOG.ru.md | 3 +++
docs/images/screenshots.json | 22 +++++++++++-----------
src/i18n/ru.json | 2 +-
6 files changed, 23 insertions(+), 16 deletions(-)
```
Содержательное изменение — одна строка `src/i18n/ru.json`:
```diff
- "marker.show_entities": "Отображать сущности",
+ "marker.show_entities": "Показывать сущности",
"marker.show_entities_tip": "Добавляет в список не только устройства, но и все их сущности",
```
`marker.show_entities_tip` не тронут, `en.json` не тронут (подтверждено пустым `git diff origin/dev...HEAD -- src/i18n/en.json`). Остальное — производное: два бандла (собраны из изменённого `ru.json`), фингерпринт скриншотов документации (пересчитывается по всему `src/**`), оба changelog.
Issue помечен `trivial`: маршрут `S2-analysis → S5-ready → S6-in-progress → S7-code-review`, ТЗ живёт в комментарии-аналитике владельца (AC1–AC3), файла в `docs/specs/` нет — соответствует §5.1 и подтверждено `process-gate.mjs` (WARN п.3 ожидаем и допустим при метке `trivial`).
Класс изменения: `src/i18n/ru.json` — класс A (продукт), issue существует и находится в `S7-code-review`; условие §1 выполнено.
## Как проверялось
| Гейт | Команда | Результат |
|---|---|---|
| Typecheck | `npx tsc --noEmit` | 0 ошибок |
| Unit-тесты | `npm test` | `# tests 1336 / pass 1335 / fail 0 / skipped 1` — совпадает с заявленным автором |
| Build + сверка 3 копий бандла | `npm run build && cmp dist/houseplan-card.js custom_components/houseplan/frontend/houseplan-card.js` | пересборка идентична закоммиченным файлам: `cmp` без вывода, `git diff --stat` после `npm run build` пуст для обоих путей бандла |
| Docs fingerprint | `node scripts/check-docs.mjs` (обязателен — диф трогает `src/**` через `ru.json`) | `Documentation checks passed (7 files, 10 external links)` |
| Process gate | `node scripts/process-gate.mjs --base origin/dev --head HEAD` | «гейт пройден, предупреждений 1» (ожидаемый WARN п.3 для trivial-трека) |
| Выбор браузерных смоков | `node scripts/smoke-select.mjs --base origin/dev --head HEAD` | «Исполняемого frontend-диффа нет (`src/**/*.ts` не тронут). Browser-smoke этим диффом не выбираются... Тронуто файлов: 6.» — прогон смоков не требуется |
**Не прогонялось и почему:**
- **Браузерные смоки (`demo/smoke_*.mjs`)** — инструмент `smoke-select.mjs` не выбрал ни одного: правка не задевает ни один `.ts`-файл, только скомпилированный артефакт словаря. Отдельно проверил единственный смок, упоминающий это семейство ключей — `demo/smoke_binding_ui.mjs:30` сравнивает `title`-атрибут с `c._t('marker.show_entities_tip')` **динамически** (не хардкодит строку), и этот ключ данным коммитом не менялся. Значит прогон этого смока не подтвердил бы и не опроверг бы фикс — не запускал.
- **`npm run golden:verify`** — диф не меняет геометрию/стили/слои, а меняет только текст чекбокса в диалоге привязки маркера. Проверил `demo/golden/matrix.mjs`: ни один golden-сценарий не снимает диалог привязки маркера (grep по `dialog:` на `marker|bind|entit` — пусто), т.е. покрытия для этого экрана не существует в принципе. Не запускал: не даёт информации об этом диффе.
- **`node scripts/model-invariants.mjs`** — диф не трогает геометрию, рёбра, `layout`, `marker.space`, `open_spans`; не применимо.
- **`python -m pytest tests_backend -q`** — `custom_components/**/*.py` не тронут; не применимо.
## Проверка AC (по комментарию владельца в S2-analysis)
1. **AC1** — `marker.show_entities` = «Показывать сущности», `show_entities_tip` не изменён.
Доказательство: чтение диффа `src/i18n/ru.json` (см. выше). **Выполнено**, проверено чтением.
2. **AC2** — «Расхождений гайд↔UI по этому термину не остаётся: `grep "Отображать сущности"` по репозиторию пуст».
Прогнал `grep -rn "Отображать сущности" .` (искл. `node_modules`) — **не пуст**: две строки в `docs/reviews/SPEC-REVIEW-262-r1.md` (историческая находка ревью #262, дословно цитирует старое значение как часть текста находки, а не как живую документацию или UI-текст). В `docs/USER-GUIDE.ru.md` расхождений не осталось (3 вхождения «Показывать сущности» на строках 698, 714, 1683 — сам гайд этим коммитом не менялся, был канонoм с самого начала). Живого расхождения гайд↔UI не осталось — фактическая цель AC2 достигнута; буквальная формулировка AC2 (пустой grep по всему репозиторию) — нет. См. находку Low ниже.
3. **AC3** — «Паритет ключей i18n не тронут (только значение), существующий тест паритета зелёный».
Доказательство: `test/i18n.test.mjs:9-13` (`i18n: en and ru dictionaries carry the same key set`) — часть зелёного прогона `npm test`. Тест умеет падать: `assert.deepEqual` по отсортированным спискам ключей, ловит любое расхождение набора ключей. Значение ключа не влияет на этот тест, что соответствует заявке AC3 «только значение». **Выполнено**.
## User-Visible / changelog
`User-Visible: yes` на коммите, оба changelog правлены в этом же коммите:
- `docs/CHANGELOG.md` — «The Russian binding dialog names its entities toggle exactly as the user guide does: «Показывать сущности» (#269).»
- `docs/CHANGELOG.ru.md` — «Флаг диалога привязки называется «Показывать сущности» — как в руководстве пользователя (#269).»
Обе записи в разделе Unreleased/Не выпущено, ссылаются на #269, согласованы по содержанию. Трейлеры `Issue: #269` и `User-Visible: yes` на месте, ветка `issue/269-show-entities-term` соответствует конвенции.
## Одно число — один источник
Величина в этом диффе не числовая, а текстовая метка чекбокса. Единственная точка рендера — `src/houseplan-card.ts:21374`: `${this._t('marker.show_entities')}`. Проверил репозиторий на дублирующий хардкод строки — единственные вхождения «Показывать сущности» — в `src/i18n/ru.json` (источник) и в двух собранных бандлах (производное от него, побайтово идентичное свежей сборке). Второго источника нет.
## Что проверено и корректно
- Единственная содержательная правка — значение одного i18n-ключа, ключ и структура словаря не тронуты.
- `en.json` не тронут, что соответствует заявлению коммита и решению об источнике истины (гайд).
- Оба бандла (`dist/`, `custom_components/.../frontend/`) идентичны свежей сборке и друг другу.
- Фингерпринт скриншотов документации пересчитан верно (`check-docs.mjs` зелёный).
- Тест паритета ключей i18n доказуемо ловит регресс набора ключей.
- Формат коммита, трейлеры, changelog, имя ветки — по процессу.
- Диапазон `origin/dev...HEAD` не содержит ничего, кроме заявленных 6 файлов — скоуп не расширен.
## Находки
### Low — буквальная формулировка AC2 не выполняется, хотя цель AC2 достигнута
- **Файл:** `docs/reviews/SPEC-REVIEW-262-r1.md:81,112`
- **Суть:** AC2 требует пустой `grep "Отображать сущности"` по репозиторию; фактически две строки старого текста остаются в историческом документе ревью #262, где они цитируют находку как часть описания дефекта на момент его обнаружения.
- **Почему не блокирует:** это архивный документ, фиксирующий состояние на момент прошлого ревью (аналогично git-истории — переписывать его задним числом не имеет смысла и запрещено духом §7.3 канона: «документы ревью... описывают код, которого уже нет»). Живого расхождения между `docs/USER-GUIDE.ru.md` и UI (i18n-словарём) не осталось — именно это было предметом issue #269.
- **Решение ревьюера:** снимается без правки, с записью здесь. Правка автора не нужна: буква AC разошлась с духом AC, а не код с намерением.
High: 0. Medium: 0.
## Чего не проверял (и почему — см. таблицу гейтов выше)
- Браузерные смоки — не выбраны инструментом, единственный релевантный по имени не тестирует изменённую строку.
- `golden:verify` — нет ни одного сценария, снимающего затронутый диалог.
- `model-invariants` и `pytest tests_backend` — диф не затрагивает геометрию и Python-бэкенд.
- Реальный визуальный осмотр диалога привязки маркера в браузере не делал — ручного тестирования в цикле нет по правилам процесса; AC доказаны чтением диффа и автотестами.
## Вердикт
Зелёный. AC1 и AC3 выполнены полностью и доказаны (чтением диффа и падающим тестом соответственно), AC2 достигает заявленной цели (расхождение гайд↔UI устранено), несмотря на не полностью буквальное совпадение с грепом — расхождение признано Low и снято ревьюером без возврата автору. Обязательные дешёвые гейты (`typecheck`, `test`, `build`+сверка бандлов, `check-docs.mjs`) зелёные. Диф скоупирован строго — 6 файлов, ровно то, что заявлено.