mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
Ревью #682 r1, Medium: перенос добавляет документу уровень вложенности (`docs/reviews/X.md` → `legacy/reviews/<тег>/X.md`, `docs/specs/` → `legacy/specs/`), а относительные ссылки внутри перенесённых документов и в соседях, ссылавшихся на них, никто не пересчитывал — на `97d19268` 53 битые ссылки в 46 файлах (заявление «все 26 резолвятся» в `7feb6177` было верно только до переноса документов ревью). Гейты архив не смотрят. `reviews-archive.mjs`: `repairLinks` пересчитывает ссылку, если она не резолвится от нового места, а цель находится от нового или старого места через карту переносов; битая и до переноса ссылка не трогается. `--apply` делает это само, `--repair-links=<rev>` — для всех переименований `<rev>..HEAD`, `--check-links` печатает битые. Этим коммитом `--repair-links=origin/dev` переписал ровно 53 ссылки в 46 файлах; остались две прежние «...»-заглушки в CODE-REVIEW-448-r2 (битые и на dev). Тесты: перенесённый документ, сосед со ссылкой в архив, ТЗ со ссылкой на позже перенесённое ревью, битая-до-переноса не трогается, в `legacy/` битых нет; мутант `reviews-archive-links-from-new-place-only`. PROCESS §2.10 и DEVELOPMENT › Release называют переписывание и `--check-links`. Issue: #682 User-Visible: no Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
161 lines
14 KiB
Markdown
161 lines
14 KiB
Markdown
# Ревью ТЗ — issue #200, цикл r1
|
||
|
||
- Этап: `S4-spec-review` (PROCESS.md §2.4)
|
||
- Артефакт ТЗ: [`docs/specs/200-room-label-parity.md`](../../specs/200-room-label-parity.md),
|
||
коммит `4089c91` на ветке `issue/200-room-label-parity`
|
||
- Issue: [#200](https://github.com/Matysh/houseplan-card/issues/200)
|
||
- Ревьюер: Claude (роль «ревьюер ТЗ», отдельная сессия от аналитика/автора)
|
||
- Трек: обычный (не `small`) — верно, т.к. меняется явный UX-контракт кнопки
|
||
между View и Plan editor (§5 PROCESS.md исключает small при новом UX-контракте)
|
||
|
||
## Скоуп ревью
|
||
|
||
Оценивалось ТЗ `docs/specs/200-room-label-parity.md` целиком: наличие
|
||
обязательных разделов §7.1 PROCESS.md, однозначность и доказуемость AC1–AC9,
|
||
отсутствие догадок, выданных за решённый факт, соответствие
|
||
`docs/SCOPE.md` (job J4/J6), `docs/UX-MODES.md`, `docs/TESTING.md`,
|
||
`docs/USER-GUIDE.ru.md`, `docs/STYLING-HOOKS.md` и текущему коду
|
||
(`src/houseplan-card.ts`, `src/styles.ts`, `demo/smoke_room_link.mjs`).
|
||
Продуктовый код не менялся и не мог быть изменён (задача на этапе ТЗ).
|
||
|
||
## Как проверялось
|
||
|
||
1. Прочитаны `docs/SCOPE.md`, `AGENTS.md`, `PROCESS.md` целиком.
|
||
2. Прочитано тело issue #200 и все 4 комментария: аналитика, вопросы владельцу
|
||
Q1–Q3, принятые дефолты, хендофф автора ТЗ.
|
||
3. Прочитан весь текст ТЗ построчно, сверен с §7.1 (обязательные разделы) и
|
||
§2.5 (DoR-чеклист).
|
||
4. Проверена заявленная причина дефекта чтением продуктового кода:
|
||
`src/houseplan-card.ts:17144-17150` (`_renderRoomLabel`, условие
|
||
`!this._markup && r.area`), `src/houseplan-card.ts:1203-1205` (геттер
|
||
`_markup`, true только для `mode === 'plan'`), `src/houseplan-card.ts:15807-15808`
|
||
(условие рендера самого room-label). Проверен существующий смок
|
||
`demo/smoke_room_link.mjs` (текущий инвариант `out.noneInPlan`) и запись
|
||
контракта в `docs/TESTING.md:932-935`.
|
||
5. Проверен CSS `.rlgo`/`.roomlabel`/`.rlname`/`.rlmetrics` в `src/styles.ts:872-989`,
|
||
включая комментарий в коде («the name renders in exactly the same place in
|
||
view mode and in the plan editor (owner's request)») — он подтверждает, что
|
||
геометрический инвариант уже задумывался раньше и сейчас нарушен именно тем
|
||
местом, которое называет ТЗ.
|
||
6. Проверено соответствие терминологии: `src/i18n/ru.json:526` (`room.open_area`
|
||
→ «Открыть зону в HA»), `docs/USER-GUIDE.ru.md` (упоминаний `.rlgo`/значка
|
||
перехода нет — новый пользовательский сценарий действительно не появляется).
|
||
7. Проверено, что файл ТЗ и запись в `docs/specs/README.md` добавлены одним
|
||
коммитом `4089c91` с трейлерами `Issue: #200` / `User-Visible: no` —
|
||
корректно для чистой документации без изменения поведения.
|
||
8. Сверено сравнение "лёгкий трек не подходит" с критериями §5 PROCESS.md.
|
||
|
||
Код не менялся, чтения было достаточно: вопрос ревью ТЗ — «выполнимо и
|
||
проверяемо ли», а не «работает ли реализация».
|
||
|
||
## Проверено и корректно
|
||
|
||
- **Все обязательные разделы §7.1 присутствуют**: сценарий и персона (§1),
|
||
что человек увидит до/после без терминов реализации (§2), проблема и
|
||
подтверждённая причина (§3), scope/non-scope (§4–5), контракт поведения (§6),
|
||
данные/миграция (§7), UX/i18n/touch (§8), AC1–AC9 с доказательством (§9),
|
||
план автотестов (§10), риски (§11), rollback (§12), release-артефакты (§13).
|
||
- **Причина дефекта подтверждена чтением кода, а не заявлена на веру.** Условие
|
||
`!this._markup && r.area` в `_renderRoomLabel` (houseplan-card.ts:17144)
|
||
действительно единственное место, отличающее `.rlname` между View и Plan;
|
||
`.rlmetrics` вынесен из centering math и одинаков — ровно то, что говорит ТЗ.
|
||
- **Продуктовые вопросы владельцу заданы по существу, не подменены техническими.**
|
||
Q1 («что делает иконка в Plan») и Q3 («что сохраняется поверх карточки») — то,
|
||
что видит и делает человек; Q2 («в какой системе координат мерить
|
||
„не сдвигается ни на пиксель“») пограничен, но корректно сведён к
|
||
наблюдаемому факту (anchor vs viewport), а не к технической реализации —
|
||
ответ владельца определяет ожидаемое пользовательское поведение теста, а не
|
||
структуру кода. Владелец принял все три дефолта, вопросы закрыты до начала
|
||
написания ТЗ.
|
||
- **Все AC пронумерованы, однозначны и несут явный способ доказательства**
|
||
(`smoke`/`golden`/`gates`/mutation gate) — выполняется требование DoR
|
||
(§2.5 PROCESS.md). AC4/AC5 задают числовой допуск (≤0,5 CSS px, DPR 1 и 2,
|
||
light/dark) — не оценочная формулировка, а измеримый критерий.
|
||
- **AC9 (mutation gate) — сильная часть ТЗ.** Оба мутанта воспроизводят ровно
|
||
те регрессии, которых боится сценарий (иконка исчезла в Plan; иконка
|
||
появилась, но стала кликабельной и ломает drag) и соответствуют
|
||
установленному в проекте формату `scripts/mutation-gate.mjs` (issue #85).
|
||
- **Не-скоуп сформулирован точно** и предотвращает соблазн заодно поправить
|
||
соседнее: абсолютные координаты страницы, миграцию слоя `layout`, unnamed
|
||
placeholder, resize handles, кнопку настроек, touch policy, isometric,
|
||
performance pipeline — всё явно исключено с объяснением почему.
|
||
- **Технические решения корректно помечены как предположения, а не факты**
|
||
(§14 «принято предположительно, поменять свободно при ревью»): отсутствие
|
||
title/role/tab stop у иконки в Plan, переиспользование существующих
|
||
`.roomlabel`/styling hooks без нового wrapper, приоритет числового smoke над
|
||
golden. Ревьюер эти предположения не оспаривает — они разумны и не влияют на
|
||
AC.
|
||
- **`docs/TESTING.md` и user-facing changelog корректно учтены** как
|
||
release-артефакты (AC7, §13); существующая запись в `docs/TESTING.md:932-935`
|
||
(«no icon in editors... [auto: smoke_room_link]») действительно требует
|
||
правки, и ТЗ это называет прямо.
|
||
- **`docs/USER-GUIDE.ru.md` не требует нового сценария** — проверено: гайд
|
||
вообще не описывает иконку перехода к зоне отдельно (только общую фразу про
|
||
карточки/названия комнат, docs/USER-GUIDE.ru.md:271), значит добавить
|
||
противоречащую формулировку неоткуда; проверка "при реализации перепроверить
|
||
формулировки" в ТЗ достаточна.
|
||
- **Откат и миграция:** корректно — persisted-формат и API не меняются,
|
||
downgrade возвращает старый визуальный сдвиг без порчи данных.
|
||
- **Оценка "лёгкий трек не подходит" верна**: критерий §5 «нет нового
|
||
UX-контракта» нарушается (кнопка получает новую видимую форму в Plan), значит
|
||
обычный трек — правильный выбор, а не подстраховка.
|
||
|
||
## Находки
|
||
|
||
### Low — неточная формулировка причины дефекта в §3 ТЗ
|
||
|
||
**Файл:** `docs/specs/200-room-label-parity.md`, раздел 3 («Проблема и
|
||
подтверждённая причина»).
|
||
|
||
**Суть:** ТЗ утверждает: «условие `!this._markup && r.area` рендерит `.rlgo`
|
||
только в View». Это неточно: `_markup` (`houseplan-card.ts:1203`) истинен
|
||
только при `mode === 'plan'`, то есть `.rlgo` при выполнении условия рендерится
|
||
не только в View, но и в редакторах Devices/Background — там, где включена
|
||
настройка «Показывать названия» (`houseplan-card.ts:15807`,
|
||
`disp.showNames || ... || this._markup`). Иконка сегодня отсутствует только в
|
||
Plan editor, а не «только присутствует в View».
|
||
|
||
**Проверено, что это не влияет на корректность AC.** Единственное изменение,
|
||
которое требуют AC1–AC9, — снять условие `!this._markup` для Plan; поведение
|
||
Devices/Background editors не меняется и не тестируется в этом ТЗ (что и
|
||
верно — они вне заявленного scope «Plan editor ↔ View»). Наивная реализация
|
||
(рендерить `.rlgo` при `r.area` независимо от режима, событийный контракт
|
||
регулировать отдельно только для Plan) не пострадает от этой неточности.
|
||
|
||
**Почему не блокирует:** это неточность в описании диагноза, а не в контракте
|
||
поведения (раздел 6) или в AC (раздел 9), которые сформулированы верно и не
|
||
опираются на слово «только в View». Реализация и код-ревью будут сверяться с
|
||
разделами 6 и 9, а не с формулировкой раздела 3.
|
||
|
||
**Решение ревьюера:** снимается без правки, с записью в этом документе
|
||
(разрешено §2.4/§3 PROCESS.md: «Low либо правится, либо снимается решением
|
||
ревьюера с записью»). Если автор всё же правит ТЗ по другой находке в будущем
|
||
цикле, желательно заодно уточнить формулировку («рендерится везде, кроме Plan
|
||
editor»), но отдельного цикла ревью это не требует.
|
||
|
||
Других находок — Low, Medium или High — не выявлено.
|
||
|
||
## Чего не проверял
|
||
|
||
- Не проверялась реализация — на этапе ТЗ её не существует; код-ревью будет
|
||
отдельным циклом (`S7-code-review`) после написания кода.
|
||
- Не запускались `npm test`/`npm run build`/смоки: код не менялся, гейты ТЗ не
|
||
требуют их прогона на этом этапе (документация — класс C, продуктовый код не
|
||
тронут).
|
||
- Не проверялась визуальная точность будущих golden-скриншотов — они появятся
|
||
только в реализации; ТЗ описывает их корректно (focused, light/dark), этого
|
||
достаточно для стадии ревью ТЗ.
|
||
- Не оценивалась производительность на реальном большом плане — ТЗ обоснованно
|
||
сводит риск к «пренебрежимо мал» (один существующий DOM-узел в ещё одном
|
||
режиме), и это утверждение проверяется кодом-ревью, а не спецификацией.
|
||
|
||
## Вердикт
|
||
|
||
Все обязательные разделы на месте, все AC однозначны и снабжены способом
|
||
доказательства, причина дефекта подтверждена чтением кода, продуктовые вопросы
|
||
владельцу закрыты до написания ТЗ, non-scope точен, mutation-gate усиливает
|
||
доказуемость AC1/AC3. Единственная находка — Low, не влияющая на корректность
|
||
контракта, снята с записью.
|
||
|
||
**Вердикт: зелёный · цикл r1/4 · High: 0 · Medium: 0 → в задаче**
|