docs: review document for #377
Проверка (CI) / Классификация изменённых файлов (push) Successful in 22s
Проверка (CI) / Предполётные проверки: документация, провенанс, процесс (push) Failing after 40s
Проверка (CI) / Переиспользование: это дерево уже проверено (push) Successful in 1m40s
Проверка (CI) / HACS: валидация репозитория (push) Failing after 24s
Проверка (CI) / Hassfest: манифест интеграции (push) Failing after 22s
Проверка (CI) / Фронтенд: типы, юниты, мутанты, синхрон бандла (push) Failing after 13m8s
Проверка (CI) / Смоки в браузере (шард 1 из 3) (push) Skipped
Проверка (CI) / Смоки в браузере (шард 2 из 3) (push) Skipped
Проверка (CI) / Смоки в браузере (шард 3 из 3) (push) Skipped
Проверка (CI) / Смоки: все шарды зелёные (push) Skipped
Проверка (CI) / Golden-кадры против принятых эталонов (push) Skipped
Проверка (CI) / Перф-смок: бюджет времени кадра (push) Skipped
Проверка (CI) / Бэкенд: pytest в Home Assistant (push) Failing after 6m38s

Issue: #377
User-Visible: no
This commit is contained in:
claude[bot]
2026-08-29 18:03:04 +00:00
parent 6a21727177
commit 92f1d3cbbf
+125
View File
@@ -0,0 +1,125 @@
# SPEC-REVIEW-377-r2
- Issue: https://github.com/Matysh/houseplan-card/issues/377 — «Персист цвета
декора по умолчанию в серверный конфиг»
- Этап: ТЗ на ревью (PROCESS.md §2.4), полный трек (унаследовано из r1)
- ТЗ: `docs/specs/377-decor-default-persist.md`, ревизия 2, зафиксирована
комментарием автора на dev `6a217271`
- Предыдущий вердикт: SPEC-REVIEW-377-r1 (`docs/reviews/SPEC-REVIEW-377-r1.md`),
жёлтый, получен на SHA `e2e4cec1` (SHA в тексте r1 не назван явно — найдено
сопоставлением: `docs/specs/377-decor-default-persist.md` появился именно в
этом коммите, а r1 описывает файл как «зафиксирована ... ревизии 1»)
- Заход: r2 · блокирующих циклов израсходовано 1 из 4
## Дельта раунда
`git diff e2e4cec1..6a217271 -- docs/specs/377-decor-default-persist.md` —
13 строк (9 добавлено, 4 удалено), правка исключительно пункта 7 «Контракта
поведения» (формат ключа) и строки ревизии в шапке. Остальной текст файла
байт-в-байт не менялся. Полный `git diff --stat e2e4cec1..6a217271` по
репозиторию затрагивает только `docs/**` (два review-документа других задач,
review-документ r1 и сам файл ТЗ) — `src/**` и `custom_components/**` не
тронуты.
Разбор этого раунда — по дельте: заново проверен только пункт 7 и его
согласованность с AC2 (единственное место, которое дельта задевает). Остальные
разделы ТЗ дельта не касается — унаследованы из r1 без повторной построчной
сверки с кодом (код не менялся между раундами, см. ниже).
## Закрытие раунда r1
| Находка (r1) | Чем закрыта | Где это видно |
|---|---|---|
| M1 — контракт (п.7) утверждал, что `DecorStyle` snake_case, со ссылкой на `types.ts:78`, которая на деле показывает camelCase; поле не помечено как предположение | Пункт 7 переписан: явно разведены snake_case ключа настроек и camelCase `DecorStyle`, дан маппинг по каждому из 6 полей, снабжён пометкой «принято предположительно» и ссылкой на аналогичную существующую конвертацию `geometry.ts:144` | `docs/specs/377-decor-default-persist.md:63-70` |
Проверено построчно, не на слово автора:
- `src/editors/decor/types.ts:78-85` — `DecorStyle` объявлен camelCase
(`color, opacity, widthCm, fill, fillColor, fillOpacity`) — новая
формулировка п.7 корректно называет это camelCase (в r1 было названо
ошибочно snake_case).
- `src/editors/decor/geometry.ts:144-148` (`decorStylePatch`) — существующая
ручная конвертация `widthCm → width_cm`, `fillColor → fill_color`,
`fillOpacity → fill_opacity` — аналогия, на которую ссылается п.7, подтверждена
дословно на HEAD (код не менялся между раундами).
- Маппинг в новом тексте (`color↔color`, `opacity↔opacity`,
`width_cm↔widthCm`, `fill↔fill`, `fill_color↔fillColor`,
`fill_opacity↔fillOpacity`) покрывает все 6 полей `DecorStyle` без пропусков.
- Формулировка снабжена явной пометкой неопределённости («принято
предположительно») — ровно то, чего не хватало в r1, и по тому же образцу,
что уже был у предшественника #376 (SPEC-REVIEW-376-r1, «Принятые
предположения»).
M1 закрыта полностью, новой правки не требует.
## Проверено в этом раунде (кроме закрытия M1)
- Согласованность п.7 с AC2 (`docs/specs/377-decor-default-persist.md:100-102`,
не изменён дельтой, но на него ссылается новая фраза «чтобы AC2 доказывал
мердж всех шести полей»). AC2 остался тем же генеральным текстом («конфиг с
ключом → мердж поверх `DEFAULT_DECOR_STYLE`; частичный ключ (только `color`)
наследует остальные поля дефолта»). Формулировка не называет явно
разноимённые поля (`width_cm`, `fill_color`, `fill_opacity`), но и не
ограничивает тестовые данные одним полем `color` — «конфиг с ключом» без
уточнения естественно читается как полный набор из 6 полей, что при
добросовестной реализации теста покрывает именно тот риск, ради которого
заведена M1 (не замержить переименованные поля). Формулировка на грани
строгости, но не ложна и не резервирует новый цикл — граница между
«доказано» и «недосказано технически, решает автор кода» здесь не
превышена (см. критерий §7.1 out of scope для технических деталей теста).
Не поднимаю как находку.
- Пересчёт классификации: пункт «Приоритет» (полный трек, критерий §5) не
затронут дельтой и не оспаривается — унаследовано из r1.
- Проверено, что дельта не меняет контракт поведения по существу (записи,
чтения, дебаунс, откат, riски, i18n, release-артефакты) — правка чисто
терминологическая/уточняющая для одного пункта, продуктовый сценарий и
видимое поведение не меняются.
## Унаследовано из r1
Без повторной проверки в этом раунде принято из `docs/reviews/SPEC-REVIEW-377-r1.md`
(документ на SHA `e2e4cec1`, код между `e2e4cec1` и `6a217271` не менялся —
подтверждено `git diff --stat`, различия только в `docs/**`):
- Классификация полного трека (критерий §5, «нет новых compatibility-полей»
не проходит) — унаследована из SPEC-REVIEW-376-r1 H1, ещё раз подтверждена
в r1.
- Соответствие `docs/SCOPE.md` (polish уже принятой фичи #360, Background-
редактор, admin-only поверхность, View не получает новых путей записи).
- Наличие и полнота всех обязательных разделов §7.1 (сценарий, до/после,
проблема, скоуп/не-скоуп, контракт п.1-6, UX, модель данных, i18n, AC1-AC7,
план автотестов, риски, откат, release-артефакты) — их текст дельта не
трогала.
- Построчная сверка пунктов контракта 1-6 с кодом (`_decorStyle` in-memory
поле, `_writeConfig`/`expected_rev`/#340, паттерн `bg_color`/`fill_colors`
для удаления ключа при дефолте, ограничение записи editor-runtime,
холодный View #357 не задет).
- Диапазоны валидации в наброске схемы (opacity 0..1, width_cm 0.1..100,
fill_opacity 0..1) — совпадают с уже принятыми диапазонами для
decor-фигур, не придуманы заново.
- AC6 корректно ограничен по объёму (полный экспорт/импорт, не
пространственный `build_space_merge`).
- Отсутствие открытых продуктовых вопросов владельцу — решение «персистить в
серверный конфиг» уже принято 29.08 и зафиксировано в теле issue.
- Низкая находка r1 (нет явной строки «touch: нет» для DoR §2.5) — оставлена
снятой с записью, как и в r1; правки в r2 её не касаются, новой строки не
требую.
## Гейты
Диапазон правки этого раунда и всей ветки #377 на сегодня — только
`docs/**` (см. «Дельта раунда» выше). `src/**` и `custom_components/**` не
тронуты продуктовым кодом ни разу с начала работы над #377. Гейтам, завязанным
на код (`npx tsc --noEmit`, `npm test`, `npm run build`, `check-docs.mjs`,
инварианты модели, browser-смоки, `pytest`), на стадии ТЗ нечего доказывать —
не прогонял, тот же вывод, что и в r1, для того же диапазона правки.
Зелёного Validate на `6a217271` не требовалось искать по этой же причине.
## Вердикт
Единственная находка r1 (M1) закрыта точным попаданием в предложенную правку:
пункт 7 теперь корректно разводит snake_case ключа настроек и camelCase
`DecorStyle`, даёт маппинг по всем 6 полям и явно маркирует решение как
предположение. Новых High- или Medium-находок в дельте не найдено. ТЗ готово
к передаче в код.
`Вердикт: зелёный · заход r2 · блокирующих циклов 1/4 · High: 0 · Medium: 0`