mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-04 05:41:34 +00:00
155 lines
13 KiB
Markdown
155 lines
13 KiB
Markdown
# 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**
|