Files
houseplan-card/docs/reviews/SPEC-REVIEW-373-r1.md
T
2026-08-29 21:13:28 +03:00

155 lines
13 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.
# SPEC-REVIEW-373-r1
Issue: [#373](https://github.com/Matysh/houseplan-card/issues/373) — Add a
fit-to-content / crop option for `houseplan-space-card`.
ТЗ: [`docs/specs/373-space-card-house-fit.md`](https://github.com/Matysh/houseplan-card/blob/issue/373-space-card-house-fit/docs/specs/373-space-card-house-fit.md)
Материал ревью (SHA): `e7ba22c623f6e9c0e5493cfe2a1706443621184b` (= текущий
`HEAD`, `git rev-parse HEAD` сверен перед выводом).
Заход: r1 · блокирующих циклов израсходовано 0 из 4 (первый заход, лимита ещё
нет; полный трек, лимит 4).
## Скоуп проверки
Первый заход — разбор полный, дельты нет. Прочитано в порядке инструкции:
`docs/SCOPE.md`, `PROCESS.md`, тело issue #373 и все четыре комментария
(владелец → OUARZA → владелец → аналитика владельца → хендофф автора ТЗ),
`docs/USER-GUIDE.md` (раздел 18 «Static space card»), `docs/CANVAS.md`
целиком (§4, §4.1, §4.2, «every place that assumed the unit square»),
`docs/TOUCH-SUPPORT.md`, `docs/CONFIG-COMPATIBILITY.md` (фрагменты про
`view_box`/новые поля), `docs/ARCHITECTURE.md` (раздел про
`houseplan-space-card`), и сам файл ТЗ целиком.
Дополнительно сверено с текущим кодом, чтобы отличить факт от досочинённого
поведения:
- `src/space-render.ts:260-316` — подтверждает буквально описанный в ТЗ вызов
`spaceFrame(space, placed, o.compactTopFrame ? {...} : 0.05)`, включая
сбор `zeroWalls`, `physicalBodyParts(...).all` (drafts/partitions/columns) и
device-маркеров как voter'ов текущего content frame;
- `src/space-geometry.ts:382-446` — `contentFrame`/`spaceFrame` реализуют
ровно ту логику 5%-паддинга и outlier-голосования, которую ТЗ называет
«текущим поведением» и явно исключает из нового `house`-режима;
- `src/render/opening-symbol.ts:53-150` — подтверждает, что jamb/leaf/arc для
door/window/gate — существующая, общая для static и full карточек
геометрия, а не новая подсистема;
- `src/space-card.ts:58-71`, `src/space-editor.ts:40-54` — подтверждают
форму `SpaceCardConfig`, паттерн `ha-form`/`selector.select.dropdown` (уже
используется для `space`) и отсутствие конфликта имени `fit` с
существующими полями;
- `src/i18n/{en,ru,de,fr}.json` — все четыре локали существуют, план i18n
реалистичен;
- `package.json` — `bundle:budget`, `bundle:sync` существуют;
`demo/smoke_space_card.mjs` существует (`ls demo/smoke_*.mjs | wc -l` = 203);
- `docs/specs/README.md` и `git show <commit>` для #372 (`d696541a`) и #373
(`e7ba22c6`) — сверка соглашения об индексе, см. находку L1 ниже.
Гейты в этом заходе не гонялись: этап — ревью ТЗ, кода к диффу нет (в ветке
задачи только новый файл `docs/specs/373-space-card-house-fit.md`, класс C).
`typecheck`/`test`/`build` не применимы к этапу spec-review.
## Как проверялось
Не «согласился с автором», а состязательно: для каждого утверждения о
«текущем поведении» найдена конкретная строка кода, которая его подтверждает
(список выше). Для каждого продуктового решения — конкретный комментарий в
issue, который его фиксирует. Отдельно искал: (а) утверждения о поведении,
которого нет ни в одном документе и которое не помечено как предположение;
(б) технические вопросы, ошибочно поднятые как продуктовые к владельцу —
не найдено ни одного, все продуктовые вопросы уже закрыты перепиской
владелец↔OUARZA до аналитики; (в) несоответствие треку `small`/`trivial` —
аналитик обоснованно выбрал полный трек и назвал нарушенный критерий (новый
публичный UX-контракт).
## Находки
### L1 (Low) — `docs/specs/README.md` не обновлён
Коммит `e7ba22c6`, добавивший `docs/specs/373-space-card-house-fit.md`,
меняет только этот один файл. Действующее соглашение репозитория — индекс
`docs/specs/README.md` обновляется в том же коммите, что и сам файл ТЗ:
коммит `d696541a` (#372) правит одновременно новый файл ТЗ и
`docs/specs/README.md` (+1 строка). Для #373 такой строки в индексе нет —
`grep -n "373" docs/specs/README.md` не находит ничего.
**Почему Low, не Medium.** Не влияет ни на один AC, не меняет проверяемость
и не продуктовое поведение — чисто индекс. Правится одной строкой в любой
момент до слияния; не обязано блокировать переход в «Готово к разработке».
**Что сделать:** автор добавляет строку в таблицу `docs/specs/README.md`
(вероятно `P2`, судя по метке issue) в этом же ТЗ-коммите или в первом
коммите реализации. Не требует отдельного цикла ревью.
## Проверено и корректно
- **Продуктовая рамка (§7.1, первые два раздела).** «Сценарий» называет
персону из `docs/SCOPE.md` (домашний администратор встраивает
`custom:houseplan-space-card` в компактный dashboard) и поверхность
(View/kiosk на планшете/телефоне). «Что человек увидит» сформулировано без
терминов реализации. Задача закрывает J1 («компактная houseplan-space-card
должна использовать ограниченную площадь dashboard») — соответствует
`docs/SCOPE.md`, не задевает ни один пункт «Out of scope».
- **Продуктовые вопросы закрыты перепиской, не додуманы.** Проверил дословно:
владелец спросил, должен ли backdrop/объект-вне-комнат входить в кадр или
только геометрия дома; OUARZA ответил категорично — «fitting bounds should
use room/house geometry» (не только «вне комнат»), что и оправдывает
контрактный пункт 8 ТЗ (исключение backdrop/decor/labels/markers/badges из
голосования кадра как единого правила, а не частного случая «вне комнат»).
Это не догадка, а прямое следствие ответа репортёра.
- **Каждое утверждение о «текущем поведении» проверено по коду**, а не
принято на слово (список файлов/строк в разделе «Скоуп проверки» выше).
Ни одного расхождения не найдено.
- **AC1–AC8 однозначны и указывают способ доказательства** (`unit`/`smoke`/
code review), включая обратную совместимость (AC1), геометрию (AC2/AC3),
безопасный fallback на вырожденных/пустых пространствах (AC4), редактор и
i18n (AC5), touch/View паритет (AC6), перформанс (AC7), документацию и
релиз (AC8). Каждый снабжён конкретной фикстурой или сценарием, а не общей
фразой «работает корректно».
- **Раздел «Assumptions accepted provisionally» явно отделяет техническое
решение от продуктового** и помечен как оспоримый ревьюером — ни одно из
семи предположений не маскирует продуктовое решение под техническое;
все семь — действительно нейтральные для пользователя технические выборы
(имена внутренних хелперов, аналитический envelope без `getBBox()`,
точные фикстуры тестов).
- **Не-скоуп корректно отсекает соседнее поведение**: полная
`custom:houseplan-card`, её Fit all/zoom/pan/outlier-hint, `title:""`
семантика #372, изменение модели/схемы/`view_box`, произвольный
пользовательский паддинг — всё явно исключено, что не даёт диффу
реализации расползтись за рамки одной карточки.
- **Данные/миграция/откат**: новое поле живёт только в конфиге карточки
Lovelace, не в House Plan config/layout — обоснованно не требует ни
backend-схемы, ни миграции, ни отдельного compatibility-поля по
`docs/CONFIG-COMPATIBILITY.md`. Откат («убрать проекцию/опцию редактора»)
безопасен и не требует очистки данных.
- **i18n-план реалистичен**: все четыре объявленных локали (`en/ru/de/fr`)
существуют в `src/i18n/`, паттерн добавления строк такой же, как для
существующих ключей (`editor.title`, `title.zoom_fit` и т.д.).
- **Производительность и touch/themes разделы формулируют проверяемые
ограничения** (без DOM-измерений/`getBBox()`, один `viewBox` на все слои,
без роста initial-бандла), согласованные с `docs/CANVAS.md` §6 (тот же
`iconUnit()`/канонический подход к рамке) и `docs/TOUCH-SUPPORT.md`
(View — release-blocking, конкретные ширины 320/900 px).
## Чего не проверял
- Реализуемость «zero-thickness room and independent wall axes» и «columns»
как voter'ов кадра проверена только чтением существующих функций
(`physicalBodyParts`, `resolveZeroWalls` — уже используются в
`space-render.ts`), не исполнением: код для нового `house`-режима ещё не
написан, поэтому не могло быть ни unit-, ни smoke-прогона.
- Golden/скриншоты, `bundle:budget`, полный Validate — не гонялись: этап
spec-review не производит diff по `src/**`; правки применимы к коду
ревью, не к этому этапу.
- Не оценивал трудозатраты/оценку сложности (5/10 в аналитике) — не входит
в мандат ревью ТЗ.
- Не проверял финальные тексты en/de/fr переводов (они появятся в
реализации) — только то, что файлы существуют и структура ключей
совместима.
## Вердикт
Только Low-находка, не блокирует. AC полны, продуктовые вопросы закрыты
переговорами до ТЗ (не додуманы), контракт однозначен и проверяем,
скоуп/не-скоуп корректно отсекают соседнее поведение, откат и i18n решены.
**Вердикт: зелёный · заход r1 · блокирующих циклов 0/4 · High: 0 · Medium: 0**