mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-04 21:58:56 +00:00
208 lines
16 KiB
Markdown
208 lines
16 KiB
Markdown
# SPEC-REVIEW-493-r1
|
||
|
||
Issue: [#493](https://github.com/Matysh/houseplan-card/issues/493) — «Сводная панель: ограничить picker и исправить локальные настройки,
|
||
мобильную форму и lifecycle».
|
||
ТЗ: [`docs/specs/493-summary-panel-hardening.md`](https://github.com/Matysh/houseplan-card/blob/issue/493-summary-panel-hardening/docs/specs/493-summary-panel-hardening.md)
|
||
(коммит `14beeb84`, докс-only: `docs/specs/493-summary-panel-hardening.md` +
|
||
`docs/specs/README.md`).
|
||
Этап: ТЗ на ревью (S4-spec-review). Заход r1. Блокирующих циклов израсходовано 0/4.
|
||
Трек: полный (аналитик назвал 4 нарушенных критерия `small` — сложность/риск >3,
|
||
больше одной поверхности, есть межwriter-совместимость, есть влияние на
|
||
производительность и touch).
|
||
|
||
## Скоуп ревью
|
||
|
||
Материал — ровно коммит `14beeb84` на ветке `issue/493-summary-panel-hardening`
|
||
(рабочая копия уже на нём, `git diff --check` показывает только этот коммит,
|
||
никакого продуктового кода в диапазоне `71aeb860..14beeb84` нет). Задача
|
||
продолжает утверждённое исключение #437 из `docs/SCOPE.md` (read-only summary
|
||
overlay, J1/J6) и закрывает пять подтверждённых аудитом acceptance-пробелов
|
||
(F3–F6, B4), не дублируя #490 (lost-ACK recovery/live invalidation).
|
||
|
||
## Как проверялось
|
||
|
||
1. Прочитаны `docs/SCOPE.md`, `AGENTS.md`, `PROCESS.md` (§1–§10, §2.10 для
|
||
формата раунда — не понадобился, это r1 без предшествующего вердикта).
|
||
2. Прочитано тело issue #493 и все три комментария (аналитика S2, «ТЗ готово»,
|
||
и отчёт о сбое автопрогона ревью).
|
||
3. Прочитан ТЗ-документ целиком (482 строки).
|
||
4. Сверены обязательные разделы §7.1 PROCESS.md построчно с оглавлением
|
||
документа — все 13 присутствуют (см. таблицу ниже).
|
||
5. **Фактическая проверка проблемы (§3 ТЗ) по текущему коду**, а не на слово
|
||
автора — аудит цитирует конкретные строки на устаревшем SHA `ea6061e9`,
|
||
и с тех пор в код никто не коммитил (ветка ТЗ — чисто docs), так что
|
||
актуальный код на HEAD это тот же код:
|
||
- F3 подтверждён: `src/summary-panel-editor.ts:45-52,219-222` — `allEntities`
|
||
строится сортировкой всего `hass.states` внутри рендер-функции и
|
||
`entities.map()` кладёт полный список `<option>` в **каждую** value-строку.
|
||
- F4 подтверждён: `src/houseplan-card.ts:3182-3183` в `setConfig()`
|
||
перезаписывает `_kioskScale` из `LS_KIOSK` безусловно; `loadLocal()` в
|
||
`src/summary-panel-runtime-loaded.ts:276-288` перезатирает то же поле
|
||
местным `parseSummaryLocal`, но порядок вызовов (`setConfig` →
|
||
`connectedCallback` → `loadLocal`) — источник наблюдаемого сброса.
|
||
- F5 подтверждён: `_leaveCardRoute()` (`src/houseplan-card.ts:7472-7533`)
|
||
обнуляет explicit editor/dialog поля (`_supportDialog`, `_markerDialog`,
|
||
…), но нигде не трогает `this._summary` (summary runtime/dialog),
|
||
который создаётся отдельно (`src/houseplan-card.ts:2285,2613`).
|
||
- F6 подтверждён: `.summary-local-sizes` в `src/summary-panel-style.ts:188-190`
|
||
— жёсткая трёхколоночная grid `max-content minmax(140px,1fr) 48px`, без
|
||
media/container query.
|
||
- B4 подтверждён: `config/set` вызывает `preserve_summary_panel_namespace` и
|
||
`validate_summary_panel_references` (`custom_components/houseplan/websocket_api.py:1588,1593`),
|
||
`ws_plan_optimize` (там же, `:1890-1970`) их не вызывает вообще.
|
||
6. Сверены заявленные в ТЗ канонические контракты с действующими документами
|
||
подсистемы:
|
||
- `docs/CONFIG-COMPATIBILITY.md` («Summary panel namespace (#437)») —
|
||
omission-preserve и change-aware reference validation, которые ТЗ §10
|
||
расширяет на Optimize, совпадают с уже описанным контрактом `config/set`,
|
||
это последовательное расширение, а не новое изобретение.
|
||
- `docs/TOUCH-SUPPORT.md` — «summary panel… and its simple settings form»
|
||
прямо названы поддерживаемой touch-first View-поверхностью с требованием
|
||
44×44 px и «reachable content on a narrow viewport»; это точно то, что ТЗ
|
||
§9/AC6 требует для **обеих** форм (admin и local-only), значит требование
|
||
не является новым UX-контрактом, а закрывает уже объявленный, но
|
||
нарушенный на практике (F6) контракт.
|
||
- `docs/specs/437-summary-panel.md:580` уже требовал «200% browser zoom» —
|
||
значит требование 200%-увеличенного текста в AC6 не изобретено этим ТЗ, а
|
||
унаследовано из уже принятого контракта #437 (и совпадает с паттерном,
|
||
который используется в #57/#86/#180 для аналогичных форм).
|
||
- `docs/USER-GUIDE.ru.md` §«Сводная панель» — термины ТЗ («Настройки сводной
|
||
панели», локальный показ, два ползунка размера) совпадают с уже описанной
|
||
пользователю формулировкой; новых пользовательских терминов не введено.
|
||
7. Проверено, что `local identity` (ключ включает `hass.user.id`) — уже
|
||
действующее поведение (`summary-panel-runtime-loaded.ts:252-254`), а не
|
||
новое продуктовое решение, которое требовало бы вопроса владельцу.
|
||
8. Проверены лимиты 10 блоков / 20 значений в текущем коде
|
||
(`summary-panel-editor.ts:230,242`) — совпадают с «не в скоупе» ТЗ §4.
|
||
9. Проверена регистрация ТЗ в `docs/specs/README.md` (двусторонняя ссылка
|
||
issue ↔ ТЗ на месте) и трейлеры коммита (`Issue: #493`, `User-Visible: no`
|
||
— корректно для чисто документационного коммита).
|
||
10. `git diff --check` на диапазоне коммита: единственное замечание — лишняя
|
||
пустая строка в конце файла (см. Low ниже).
|
||
|
||
## Гейты
|
||
|
||
Материал этого раунда — документ (класс C, докс-only коммит). Продуктовый код,
|
||
тесты и бандл не менялись, поэтому дорогие/дешёвые гейты (`typecheck`, `npm
|
||
test`, `npm run build`, смоки, golden, `check-docs`, инварианты модели) к этому
|
||
диффу неприменимы и не гонялись — гонять их значило бы проверять код, который
|
||
эта задача ещё не написала. Зелёный Validate на `14beeb84`, на который ссылается
|
||
задание, покрывает ровно то же самое docs-only состояние дерева. Единственная
|
||
механическая проверка, применимая к самому файлу ТЗ, — `git diff --check`
|
||
(см. выше, результат — Low).
|
||
|
||
## Проверка обязательных разделов ТЗ (PROCESS.md §7.1)
|
||
|
||
| Раздел §7.1 | Есть в документе | Где |
|
||
|---|---|---|
|
||
| Сценарий | да | §1 |
|
||
| Что человек увидит до/после | да | §2 |
|
||
| Проблема | да | §3, с проверяемыми числами и ссылками на код |
|
||
| Скоуп и не-скоуп | да | §4 |
|
||
| Контракт поведения | да | §5–§8, §10–§11 |
|
||
| UX | да | §6, §9 |
|
||
| Модель данных и миграция | да | §12 |
|
||
| i18n | да | §13 |
|
||
| AC1…ACn с доказательством | да | §15, все 10 называют метод и негативного свидетеля |
|
||
| План автотестов | да | §16 |
|
||
| Риски | да | §17 |
|
||
| Откат | да | §18 |
|
||
| Release-артефакты | да | §19 |
|
||
|
||
Дополнительно: продуктовые вопросы владельцу не заданы, и это оправдано —
|
||
видимое поведение уже зафиксировано #437/аудитом, а раздел §20 «Принятые
|
||
технические предположения» корректно выносит все нерешённые технические детали
|
||
(лимит 100 строк, место backend helper, механизм инвалидации индекса,
|
||
имена файлов) в явный блок «предположительно, поменять свободно», как требует
|
||
§7.1. Ни одного случая, когда догадка о поведении подана как факт без пометки,
|
||
не найдено — там, где ТЗ утверждает конкретное поведение (F3–F6, B4, лимиты,
|
||
touch-контракт, 200%-zoom), утверждение подтверждено либо действующим кодом,
|
||
либо действующим каноническим документом.
|
||
|
||
## Находки
|
||
|
||
### Low — лишняя пустая строка в конце файла ТЗ
|
||
|
||
`docs/specs/493-summary-panel-hardening.md` заканчивается двумя `\n\n`
|
||
(`git diff --check` подтверждает: «new blank line at EOF»). Чисто
|
||
косметическое, не влияет на содержание, ссылки или AC. **Снимается** решением
|
||
ревьюера без правки — цена отдельного цикла ради одного символа выше цены
|
||
находки.
|
||
|
||
Других находок — High, Medium в скоупе или Medium вне скоупа — не выявлено.
|
||
|
||
## Что проверено и корректно
|
||
|
||
- Все 13 обязательных разделов §7.1 присутствуют и содержательны.
|
||
- Каждый из пяти «подтверждённых сценариев» проблемы (F3–F6, B4) верифицирован
|
||
чтением текущего кода на HEAD, а не принят на слово автора.
|
||
- Все 10 AC пронумерованы, для каждого указан способ доказательства
|
||
(unit/backend/smoke/golden/performance) и названа мутация/негативный
|
||
свидетель, который должен покраснеть — соответствует требованию
|
||
«доказуемость» на этапе ТЗ.
|
||
- Touch- и zoom-требования (AC6, 44×44 px, 200% text, 320/390 px) — не новый
|
||
UX-контракт, а закрытие уже объявленного в `docs/TOUCH-SUPPORT.md` и
|
||
`docs/specs/437-summary-panel.md` контракта, нарушенного на практике (F6).
|
||
- Backend-контракт (§10, писательская матрица §11) — прямое расширение уже
|
||
задокументированного в `docs/CONFIG-COMPATIBILITY.md` поведения `config/set`
|
||
на `plan/optimize`, без новых persisted-полей и без version bump (§12), что
|
||
соответствует `docs/SCOPE.md` (не расширяет панель до dashboard framework).
|
||
- Раздел «Принятые технические предположения» (§20) корректно отделяет
|
||
нерешённые инженерные детали от продуктового контракта; все пункты не
|
||
затрагивают видимое поведение и могут быть оспорены ревьюером кода без
|
||
возврата к владельцу.
|
||
- Откат (§18) назван реалистично и явно запрещает частичный откат
|
||
(backend guard без generation token и наоборот).
|
||
- Issue ↔ ТЗ связь двусторонняя (`docs/specs/README.md` обновлён в том же
|
||
коммите), трейлеры коммита корректны (`Issue: #493`, `User-Visible: no`).
|
||
|
||
## Чего не проверял
|
||
|
||
- Не проверялась реализация (её ещё нет — коммит docs-only); всё, что относится
|
||
к фактическому поведению кода после реализации, — предмет код-ревью.
|
||
- Не прогонялись `typecheck`/`test`/`build`/смоки/golden/`check-docs` — диапазон
|
||
ревью не содержит изменений `src/**` или `custom_components/**`, эти гейты
|
||
неприменимы к этапу спецификации.
|
||
- Не проверялись предположения §20 на техническую реализуемость (например,
|
||
выбор конкретного DOM-примитива для picker) — это осознанно оставлено
|
||
инженеру и ревьюеру кода.
|
||
- Не запрашивалось у владельца ничего сверх того, что уже решено в
|
||
комментарии аналитика — открытых продуктовых вопросов в ТЗ нет и не найдено.
|
||
|
||
## Вердикт
|
||
|
||
**Зелёный.** ТЗ полно, каждый заявленный факт проблемы подтверждён чтением
|
||
действующего кода, каждый AC проверяем и называет негативного свидетеля,
|
||
обязательные разделы на месте, технические предположения явно отделены от
|
||
продуктового контракта, скоуп не выходит за рамки утверждённого исключения
|
||
#437. Единственная находка — Low, снята без правки.
|
||
|
||
---
|
||
|
||
## Материал раунда
|
||
|
||
- SHA материала: `14beeb8470a7189ddef5a8bd99a15630e2232d4e`
|
||
(ветка `issue/493-summary-panel-hardening`, рабочая копия HEAD detached на
|
||
этом коммите).
|
||
- Дерево ТЗ: `docs/specs/493-summary-panel-hardening.md` — 481 строка, добавлен
|
||
этим коммитом целиком (см. `git show --stat 14beeb84`).
|
||
- Предшествующего вердикта нет — это r1; раздел «Унаследовано из r0» не
|
||
применяется.
|
||
|
||
---
|
||
|
||
<!-- material-anchors: сгенерировано конвейером (#414) -->
|
||
|
||
## Материал раунда
|
||
|
||
- Ветка: `issue/493-summary-panel-hardening`, коммит `14beeb8470a7` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
|
||
- Дерево материала: `ff7e45438b049665f1e751ef4943d9ee25044779`
|
||
```
|
||
git log --all --format='%H %T' | grep ff7e45438b04
|
||
```
|
||
- ТЗ `docs/specs/493-summary-panel-hardening.md`, блоб `19ebcb9df3035661a422cc0d02af71897b73f7c5`
|
||
```
|
||
git log --all --find-object=19ebcb9df3035661a422cc0d02af71897b73f7c5 -- docs/specs/493-summary-panel-hardening.md
|
||
```
|
||
- Вердикт конвейера: `green` · High 0
|