docs: review document for #269

Issue: #269
User-Visible: no
This commit is contained in:
claude[bot]
2026-08-26 06:10:29 +00:00
parent 676610c0cd
commit 98a0a24bd4
+110
View File
@@ -0,0 +1,110 @@
# 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 файлов, ровно то, что заявлено.