mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
@@ -0,0 +1,168 @@
|
||||
# Ревью ТЗ — issue #210, цикл r2
|
||||
|
||||
- **Issue:** https://github.com/Matysh/houseplan-card/issues/210
|
||||
- **ТЗ:** `docs/specs/210-fixed-floor-card.md` (коммит `6c3d376`, ветка
|
||||
`issue/210-fixed-floor`)
|
||||
- **Предыдущий цикл:** `docs/reviews/SPEC-REVIEW-210-r1.md` — жёлтый,
|
||||
High: 0, Medium: 1 (M1, в скоупе), Low: 1 (L1)
|
||||
- **Трек:** обычный (аналитика явно исключила `small`/`trivial`; сложность
|
||||
6/10, риск 6/10, метка `small` на issue отсутствует) — лимит циклов 4
|
||||
- **Вердикт:** зелёный · цикл r2/4 · High: 0 · Medium: 0
|
||||
|
||||
## Скоуп ревью
|
||||
|
||||
Проверялось ТЗ `docs/specs/210-fixed-floor-card.md` в редакции коммита
|
||||
`6c3d376` как артефакт этапа `S4-spec-review`, второй цикл. Задача — не
|
||||
переповторить r1 целиком, а (1) убедиться, что правки по M1 и L1 сделаны так,
|
||||
как обещано в комментарии автора, (2) не подтвердить это на слово, а
|
||||
независимо перечитать документ целиком и код, к которому апеллирует новый
|
||||
текст, и (3) заново пройти обязательные разделы §7.1 PROCESS.md и AC1…AC12
|
||||
свежим взглядом, а не только смотреть на диф — чтобы не унаследовать слепое
|
||||
пятно предыдущего цикла. Продуктового кода по #210 всё ещё не существует
|
||||
(диапазон коммитов ветки — только документация), поэтому гейты §8 PROCESS.md
|
||||
к этому циклу неприменимы, как и в r1.
|
||||
|
||||
## Как проверялось
|
||||
|
||||
1. Прочитаны `docs/SCOPE.md`, `AGENTS.md`, `PROCESS.md` целиком (в этой
|
||||
сессии, без переноса контекста из r1 — ревью ТЗ и код-ревью обязаны идти
|
||||
в разных сессиях по §6 PROCESS.md; здесь то же требование соблюдено для
|
||||
независимости повторного цикла ТЗ).
|
||||
2. Прочитано тело issue #210 и все шесть комментариев, включая аналитику,
|
||||
вердикт r1 и комментарий автора о правках (`6c3d376`, «M1: … L1: …»).
|
||||
3. Получен точный диф правки: `git diff 0bd6094 6c3d376 --
|
||||
docs/specs/210-fixed-floor-card.md` — 12 добавленных строк, ни одной
|
||||
удалённой; сверен построчно с тем, что обещано в комментарии автора и с
|
||||
тем, что требовало M1/L1.
|
||||
4. Прочитан файл ТЗ `210-fixed-floor-card.md` целиком заново, в текущей
|
||||
редакции (337 строк), а не только изменённые фрагменты.
|
||||
5. Перечитаны `docs/CONFIG-COMPATIBILITY.md` целиком и профильные разделы
|
||||
`docs/UX-MODES.md` (header/tabs, строка 81: «Header in View: space tabs,
|
||||
device count, zoom cluster. Nothing else.») и `docs/TOUCH-SUPPORT.md`
|
||||
(canonical-tag правило) — те же документы, что и в r1, чтобы проверить,
|
||||
не создал ли новый текст противоречие, которого не было в r1.
|
||||
6. Прочитан `docs/USER-GUIDE.ru.md` в местах, которые ТЗ обязуется
|
||||
обновить в release-артефактах: карточка card-options (строка 54, 125 —
|
||||
`default_floor` уже называется «Стартовое пространство» в действующем
|
||||
guide, то есть новый термин ТЗ **Initial space / Стартовое пространство**
|
||||
не изобретён, а взят из текущего интерфейса) и раздел «Несколько карточек
|
||||
и стартовые пространства» (строки 1327-1341) — подтверждает, что именно
|
||||
это описание (`default_floor` как единственная защита) ТЗ обязано
|
||||
уточнить в §15, и это уже учтено (не новая находка, ещё в r1).
|
||||
7. Проверено соответствие нового текста коду:
|
||||
- `src/editor.ts` (`_valueChanged`, объединение через `{ ...this._config,
|
||||
...ev.detail.value }`) — подтверждён паттерн, на который ссылается M1
|
||||
r1 («никакого существующего прецедента явной зачистки пустого поля
|
||||
нет»). Новый текст §6.2 закрывает именно этот пробел явным требованием
|
||||
«удалить собственный ключ `floor` из выдаваемого card config целиком»,
|
||||
а не полагаться на то, что пустая строка сама попадёт в уже описанный
|
||||
invalid-путь.
|
||||
- Существующие смоки `demo/smoke_nav_persist.mjs`, `demo/smoke_kiosk.mjs`
|
||||
присутствуют в репозитории; `demo/smoke_fixed_floor.mjs` — нет, как и
|
||||
ожидается по плану тестирования (§13): новый смок создаётся в
|
||||
реализации, а не сейчас.
|
||||
8. Проверено, что новый §9.1 «i18n» не дублирует и не противоречит
|
||||
существующим требованиям §9 (invalid-state accessibility) и §6.2 (GUI
|
||||
labels) — он их резюмирует под отдельным заголовком, не вводя новых
|
||||
требований к продукту.
|
||||
9. Код не запускался, гейты не прогонялись — на этапе ревью ТЗ продуктового
|
||||
кода нет, как и в r1 (PROCESS.md §8 относит гейты к код-ревью).
|
||||
|
||||
## Проверка правок по M1 и L1
|
||||
|
||||
### M1 (было Medium, в скоупе) — закрыто
|
||||
|
||||
Ровно в заявленном месте (§6.2, после абзаца про dropdown/textbox fallback)
|
||||
добавлено:
|
||||
|
||||
> Выбор «не закреплять» обязан удалить собственный ключ `floor` из выдаваемого
|
||||
> card config целиком. GUI не записывает `floor: ''` или `floor: null`: эти
|
||||
> значения намеренно остаются невалидными для явно заданного YAML, а
|
||||
> отсутствие свойства возвращает legacy navigation согласно §6.1.
|
||||
|
||||
Это прямо снимает найденное в r1 противоречие: пустой выбор GUI теперь
|
||||
однозначно ведёт к обычной (legacy) навигации, а не к невалидному `floor: ''`
|
||||
и, как следствие, к error state. Зеркальный пункт добавлен и в §16
|
||||
(«Принятые предположения», п.8) той же формулировкой, как и просил r1. Оба
|
||||
места непротиворечивы друг другу и §6.1 п.3 (`''`/`null` остаются невалидными
|
||||
для **явного** YAML, что осталось неизменным и корректным — M1 просил
|
||||
разграничить «GUI никогда не пишет эти значения» и «явный YAML с этими
|
||||
значениями всё ещё невалиден», а не менять §6.1). AC8 («GUI … умеет очистить
|
||||
`floor`») теперь однозначно проверяем: тест должен убедиться, что после
|
||||
очистки ключ отсутствует в объекте конфигурации, а не равен `''`/`null`.
|
||||
|
||||
Находка полностью устранена, без побочных противоречий с остальным текстом.
|
||||
|
||||
### L1 (было Low, на решение автора) — закрыто
|
||||
|
||||
Добавлен отдельный подраздел **§9.1. i18n** сразу после §9 (invalid-state
|
||||
контракт), формально выполняющий требование §7.1 PROCESS.md об отдельном
|
||||
разделе i18n. Содержание не вводит новых по существу требований — оно
|
||||
называет два конкретных файла (`en.json`/`ru.json`), явно запрещает зашитые
|
||||
рантайм-строки и привязывает термин к уже принятому «space / пространство» —
|
||||
то есть закрывает найденный формальный пробел, не расширяя скоуп.
|
||||
|
||||
## Заново проверенные разделы (не только диф)
|
||||
|
||||
- **Обязательные разделы §7.1 PROCESS.md** — по-прежнему все присутствуют, с
|
||||
добавлением отдельного i18n-подраздела структура стала полнее, чем в r1.
|
||||
- **AC1…AC12** — перечитаны заново; ни один не изменился текстом со времени
|
||||
r1, добавление в §6.2/§16 делает AC8 более однозначным (см. M1 выше), не
|
||||
ослабляя и не меняя ни один AC.
|
||||
- **Непротиворечивость нового текста остальному документу** — §6.1 (типы и
|
||||
invalid-список), §9 (когда рендерится error state), §10 (fixed instance не
|
||||
очищает и не мигрирует nav record) и §16 п.6 (invalid `floor` не
|
||||
откатывается к `default_floor`) не пересекаются и не конфликтуют с новым
|
||||
текстом об удалении ключа при очистке GUI: очистка через GUI — это
|
||||
отсутствие `floor`, а не невалидное значение, поэтому она не проходит через
|
||||
invalid-ветку вовсе, что и было целью правки.
|
||||
- **SCOPE.md** — правка не меняет ни персону, ни поверхность, ни объём
|
||||
видимого изменения по сравнению с r1; продуктовая часть контракта
|
||||
по-прежнему исходит от владельца («Технические детали решаются свободно на
|
||||
ревью»), а не является догадкой автора, выданной за факт.
|
||||
- **Открытые продуктовые вопросы** — отсутствуют, как и в r1; оба
|
||||
устранённых пункта были техническими уточнениями формулировки, не
|
||||
продуктовыми развилками, и не требовали обращения к владельцу.
|
||||
|
||||
Новых находок — ни High, ни Medium, ни Low — при независимом перечтении
|
||||
целиком не появилось.
|
||||
|
||||
## Проверено и признано корректным
|
||||
|
||||
Всё, что было проверено и признано корректным в r1 (причинная цепочка §3/§7,
|
||||
структура документа, соответствие `docs/UX-MODES.md`, `docs/TOUCH-SUPPORT.md`,
|
||||
`docs/CONFIG-COMPATIBILITY.md`, AC1…AC12, план тестирования, риски и откат),
|
||||
остаётся в силе — правка `6c3d376` его не затронула ни одной строкой (диф
|
||||
только добавляет текст, ничего не удаляет и не переформулирует). Дополнительно
|
||||
в этом цикле подтверждено:
|
||||
|
||||
- точное соответствие внесённых правок тому, что было обещано в комментарии
|
||||
автора (ничего не забыто, ничего лишнего не изменено походя);
|
||||
- отсутствие побочных противоречий между новым текстом и остальными
|
||||
разделами документа;
|
||||
- термин **Initial space / Стартовое пространство** не изобретён — совпадает
|
||||
с уже используемым в `docs/USER-GUIDE.ru.md:54,125` названием поля
|
||||
`default_floor`.
|
||||
|
||||
## Чего не проверял
|
||||
|
||||
- **Фактическая работоспособность будущей реализации** — на этапе ревью ТЗ
|
||||
продуктового кода не существует.
|
||||
- **`ha-form`/`ha-selector` поведение при очистке optional select** —
|
||||
по-прежнему не тестировалось эмпирически; текст ТЗ теперь однозначен
|
||||
(«удалить ключ целиком»), но соответствие итоговой реализации этому
|
||||
контракту — предмет код-ревью, не этого цикла.
|
||||
- **`demo/smoke_fixed_floor.mjs`, `smoke_nav_persist.mjs`, `smoke_kiosk.mjs`**
|
||||
не запускались — нового смока ещё нет, существующие два не относятся к
|
||||
этому циклу (нет кода, который они могли бы проверить).
|
||||
- Гейты `typecheck`/`test`/`build`/smoke/golden не прогонялись — раздел
|
||||
неприменим на этапе ревью ТЗ (PROCESS.md §8 относит их к код-ревью).
|
||||
|
||||
## Итог
|
||||
|
||||
Оба цикла r1 (M1, L1) закрыты именно так, как было обещано, без побочных
|
||||
противоречий и без сужения/расширения скоупа. Независимое повторное чтение
|
||||
всего документа не выявило новых блокирующих или Medium-находок. Открытых
|
||||
продуктовых вопросов нет. ТЗ готово к «Готово к разработке».
|
||||
|
||||
**Вердикт: зелёный · цикл r2/4 · High: 0 · Medium: 0**
|
||||
Reference in New Issue
Block a user