mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-28 19:01:34 +00:00
@@ -0,0 +1,174 @@
|
||||
# SPEC-REVIEW-640-r1
|
||||
|
||||
## Скоуп ревью
|
||||
|
||||
Этап: ревью ТЗ (PROCESS.md §2.4), трек `small`. Заход r1, блокирующих циклов
|
||||
израсходовано 0 из 2 (лимит цикла ревью ТЗ на лёгком треке — 2, §5).
|
||||
|
||||
Предмет: раздел `## ТЗ` в теле issue #640 — точечная замена menu-иконки
|
||||
категории `dishwasher` («Посудомоечная машина», группа «Техника») в палитре
|
||||
мебели на рисунок из приложенного архива `dishwasher.zip`, без изменения
|
||||
планового символа, публичного ID, размеров (60×60 см) и любых сохранённых
|
||||
данных.
|
||||
|
||||
Материал ревью: тело issue #640 (раздел `## ТЗ`) и оба комментария
|
||||
(`Оценка: ...`, `ТЗ добавлено ...`) на момент чтения, working tree на
|
||||
`f234855e` (HEAD detached), продуктовый код не менялся — подтверждено `git
|
||||
status` (clean) и текстом комментария автора.
|
||||
|
||||
## Как проверялось
|
||||
|
||||
Продуктового диффа нет (только текст ТЗ в issue), поэтому дешёвые гейты
|
||||
(`typecheck`/`test`/`build`) не запускались — репозиторий не тронут этой
|
||||
задачей на этапе спецификации. Вместо гонки гейтов каждое фактическое
|
||||
утверждение ТЗ сверено с текущим состоянием репозитория:
|
||||
|
||||
| Утверждение ТЗ | Проверка | Результат |
|
||||
|---|---|---|
|
||||
| «остальные 32 menu-иконки» | `ls assets/furniture/houseplan-0.4.1/svg/menu` | 33 файла всего, 33−1=32 — совпадает |
|
||||
| viewBox 110×110, безопасный menu-контракт (только `svg/g/path`, `svg` только `viewBox,xmlns`, `path` только `d/fill/stroke/stroke-width/stroke-linecap/stroke-linejoin`, `fill=none`, `stroke=currentColor`, круглые `linecap/linejoin`) | прочитан `scripts/generate-furniture-assets.mjs` (`svgArt()`, парсер атрибутов) и текущий `dishwasher.svg` | контракт существует буквально в описанном виде и уже применён к текущему файлу — ТЗ не изобретает требование |
|
||||
| группа «Техника», названия ru/en, размеры 60×60, `menu_icon: dishwasher` | прочитан `assets/furniture/houseplan-0.4.1/pack.json` | `group: "appliance"`, `name_ru: "Посудомоечная машина"`, `width_cm/depth_cm: 60` — совпадает |
|
||||
| «иконки редактора остаются в ленивом editor-графе» | прослежен путь `decor-image-editor.ts` → `houseplan-editor-runtime.ts` → `houseplan-card.ts:720 await import(...)` | подтверждено: путь до `GENERATED_FURNITURE_MENU` целиком за динамическим `import()`, в стартовый граф не входит |
|
||||
| golden-сцена `furniture-categories-light` существует и показывает категории (не единственную) | `demo/golden/matrix.mjs:619` | сцена есть, `furniturePalette: 'categories'` — показывает плитки категорий, а не один вариант |
|
||||
| «новые скриншоты документации не нужны» | `grep furniture demo/docs/screenshots.mjs` — 0 совпадений; единственный сценарий с `decor` (`07-background-editor.png`) использует `editorTray: 'decor-selection'`, а это трей выбора объекта декора (`_decorSel`), не палитра мебели | подтверждено — палитра мебели ни в одном сценарии документации не фигурирует |
|
||||
| `npm run furniture:generate` / `npm run furniture:check` существуют | `package.json:46-47` | оба скрипта определены как заявлено |
|
||||
| существующий unit ленивой загрузки для AC3 | `demo/smoke_furniture_lazy_art.mjs` найден | подтверждает наличие свидетеля, хотя ТЗ называет его «unit», а по факту это browser-smoke; см. находку Low ниже |
|
||||
| нет других мест в `src/**`, где рисуется/дублируется menu-иконка `dishwasher` (проверка «одно число — один источник» применительно к арту) | `grep -r dishwasher src/` | только генерированные файлы и i18n-строки (названия, не геометрия); единственный потребитель generated menu-art — `decor-image-editor.ts` | подтверждено, второго источника рисунка нет |
|
||||
|
||||
Дешёвые гейты `typecheck`/`test`/`build` **не гонялись** — на этапе ТЗ нет
|
||||
продуктового диффа, гонять их не по чему. Ссылка на зелёный Validate из
|
||||
контекста задачи (`f234855e`) относится к предыдущей задаче (#614) и здесь
|
||||
не переиспользуется как доказательство: доказывать было нечего.
|
||||
|
||||
## Проверка обязательных разделов (PROCESS.md §7.1)
|
||||
|
||||
Все обязательные разделы присутствуют и в правильном порядке (сценарий и
|
||||
«что человек увидит» — первыми):
|
||||
|
||||
- Сценарий — есть, называет персону (администратор, `docs/SCOPE.md`),
|
||||
поверхность (редактор подложки, палитра мебели) и момент (перед
|
||||
добавлением предмета);
|
||||
- Что человек увидит до/после — есть, без терминов реализации;
|
||||
- Проблема/скоуп/не-скоуп — есть, скоуп точен (один файл), не-скоуп явно
|
||||
перечисляет плановый SVG, ID, названия, размеры, сохранённые данные,
|
||||
остальные иконки, backend, i18n;
|
||||
- Контракт и UX — есть, технически точен (сверено с кодом, см. таблицу выше);
|
||||
- Данные/миграция/i18n/perf/touch — есть, единым абзацем, все пункты
|
||||
закрыты явным «не меняется»/«не нужна»;
|
||||
- AC1…AC3 с указанием доказательства — есть, см. разбор ниже;
|
||||
- План автотестов — есть;
|
||||
- Риски и откат — есть;
|
||||
- Release-артефакты — есть, требует правки обоих changelog;
|
||||
- Блок принятых предположений — есть, оба пункта в границах технических
|
||||
решений автора, не продуктовых.
|
||||
|
||||
Дополнительно ТЗ содержит незаявленный процессом, но уместный раздел
|
||||
«Происхождение и право использования» — фиксирует provenance приложенного
|
||||
архива (сотрудник JustBusiness, право MIT-использования, ранее подтверждено
|
||||
владельцем). Это не догадка: аналитический комментарий тем же автором
|
||||
детализирует содержимое архива (SHA-256, `viewBox`, отсутствие активного
|
||||
XML) — похоже на результат реального осмотра вложения владельцем, а не
|
||||
предположение, выданное за факт.
|
||||
|
||||
## Разбор критериев приёмки
|
||||
|
||||
- **AC1** («новая menu-иконка», доказательство: unit + golden
|
||||
`furniture-categories-light` + ревью diff) — однозначен и проверяем:
|
||||
число «32» подтверждено подсчётом файлов, golden-сцена существует и
|
||||
показывает категории. Байтовое сравнение прочих 32 файлов — за автором
|
||||
на этапе кода, тестируемо unit-тестом (сравнение содержимого файлов).
|
||||
- **AC2** («плановый контракт неизменен») — однозначен, перечисляет
|
||||
конкретные инварианты (файл, ID, группа/категория, ru/en названия,
|
||||
60×60 см, рендер размещённых объектов), доказательство unit + diff —
|
||||
проверяемо чтением изменённых файлов на код-ревью.
|
||||
- **AC3** («генерация и загрузка корректны») — перечисляет команды
|
||||
гейтов, существующие в `package.json` (проверено), и «существующий unit
|
||||
ленивой загрузки» — по факту это browser-smoke
|
||||
`demo/smoke_furniture_lazy_art.mjs`, не unit-тест. Терминологическая
|
||||
неточность (см. находку Low), не блокирует проверяемость критерия.
|
||||
|
||||
Ни один AC не описывает поведение, зафиксированное только предположением
|
||||
автора: каждое числовое или структурное утверждение сверяется с реальным
|
||||
файлом кода или манифеста (см. таблицу выше), а не изобретается.
|
||||
|
||||
## Находки
|
||||
|
||||
### Low — AC3 называет browser-smoke «unit»-тестом
|
||||
|
||||
**Файл:** тело issue #640, раздел «Критерии приёмки», AC3.
|
||||
**Суть:** «Доказательство: команды гейтов + существующий unit ленивой
|
||||
загрузки» — свидетель, на который ссылается формулировка
|
||||
(`demo/smoke_furniture_lazy_art.mjs`), является browser-smoke из
|
||||
`demo/smoke_*.mjs`, а не `test/*.test.mjs` unit-тестом. Не искажает
|
||||
проверяемость критерия (свидетель существует и годен), но при код-ревью
|
||||
формулировка может увести к поиску несуществующего unit-теста.
|
||||
**Решение ревьюера:** не блокирует, оставляю без правки автору — на
|
||||
код-ревью проверяющий сверится с фактическим файлом, а не с текстом ТЗ;
|
||||
исправление слова стоит дешевле, чем цикл ревью ради него.
|
||||
|
||||
Других находок нет. High- и Medium-находок в скоупе задачи — 0. Medium вне
|
||||
скоупа — 0, отдельный issue не заводится.
|
||||
|
||||
## Что проверено и корректно
|
||||
|
||||
- Число прочих menu-иконок (32) и точный `viewBox`/безопасный контракт SVG,
|
||||
включая цвет и толщину линии, — сверены с реальным генератором и текущим
|
||||
файлом, а не приняты на слово;
|
||||
- Соответствие группы/названий/размеров манифесту `pack.json`;
|
||||
- Утверждение о ленивой загрузке menu-арта — прослежено по цепочке
|
||||
импортов до динамического `import()` в `houseplan-card.ts`;
|
||||
- Существование golden-сцены и её охват (все категории, не одна плитка);
|
||||
- Отсутствие влияния на скриншоты документации — палитра мебели не
|
||||
фигурирует ни в одном сценарии `demo/docs/screenshots.mjs`;
|
||||
- Отсутствие второго источника рисунка иконки в `src/**` (единственный
|
||||
потребитель — `decor-image-editor.ts` через `GENERATED_FURNITURE_MENU`);
|
||||
- Существование обоих npm-скриптов (`furniture:generate`,
|
||||
`furniture:check`), на которые ссылается AC3;
|
||||
- Полнота обязательных разделов ТЗ по §7.1 и корректность их порядка;
|
||||
- Согласованность аналитического комментария (`Оценка: ...`) с
|
||||
выбранным треком `small` — все критерии §5 выполнены одновременно
|
||||
(сложность 2/10, одна поверхность, нет миграции/нового UX-контракта/
|
||||
влияния на perf или touch), отказ от `trivial` обоснован верно (тип —
|
||||
enhancement, не bug).
|
||||
|
||||
## Чего не проверял
|
||||
|
||||
- Подлинность SVG-геометрии внутри приложенного `dishwasher.zip` (не
|
||||
скачивал архив по внешней ссылке — это дело код-ревью: сверить итоговый
|
||||
path в `svg/menu/dishwasher.svg` с содержимым архива по заявленному
|
||||
SHA-256, а не задача спек-ревью проверять содержимое ещё не
|
||||
реализованного изменения);
|
||||
- Юридический статус provenance (принадлежность аккаунта `nikitaevfz-commits`
|
||||
компании JustBusiness) — зафиксировано как решение владельца вне этого
|
||||
ревью, продуктовым вопросом не является;
|
||||
- Дешёвые гейты (`typecheck`/`test`/`build`) — не гонялись, продуктового
|
||||
диффа для них нет на этапе ТЗ.
|
||||
|
||||
## Материал раунда
|
||||
|
||||
- Issue: #640, заход r1.
|
||||
- Тело issue (раздел `## ТЗ`) прочитано целиком через `gh issue view 640
|
||||
--json body`.
|
||||
- Working tree: HEAD detached на `f234855e66ee7baba528b7c856c5ab79e9491156`,
|
||||
`git status` — чисто, продуктовый код этой задачей не менялся.
|
||||
|
||||
## Вердикт
|
||||
|
||||
Зелёный. ТЗ полно, каждый AC проверяем и подкреплён проверкой по реальному
|
||||
коду/манифесту/скриптам, продуктовых вопросов владельцу нет, единственная
|
||||
находка — Low (терминологическая неточность в AC3), не требует правки для
|
||||
перехода в «Готово к разработке».
|
||||
|
||||
---
|
||||
|
||||
<!-- material-anchors: сгенерировано конвейером (#414) -->
|
||||
|
||||
## Материал раунда
|
||||
|
||||
- Ветка: `issue/640-dishwasher-menu-icon`, коммит `f234855e66ee` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
|
||||
- Дерево материала: `703233aee85cb3c3cbf101b84e288ec9dba3ce34`
|
||||
```
|
||||
git log --all --format='%H %T' | grep 703233aee85c
|
||||
```
|
||||
- Тело issue: `1336c4649192ea657779f92aeaf1daff7c7f23c2b85316d89d401bcd9f06101f`
|
||||
- Вердикт конвейера: `green` · High 0
|
||||
Reference in New Issue
Block a user