mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-01 12:18:51 +00:00
@@ -0,0 +1,116 @@
|
||||
# CODE-REVIEW-741-r1
|
||||
|
||||
**Issue:** #741 «2.5D: неиспользуемое поле stageSize в IsoOverlayFitEnvelopeInput»
|
||||
**Материал раунда:** `a8c8f1d68aa7b42a51b67630a0adb69188213459` (ветка `issue/741-drop-stage-size`, поверх `dev@76558bf2`)
|
||||
**Трек:** `track:show` (поднят с `track:ship` владельцем — риск по участку `iso-scene-render`, #707)
|
||||
**Заход:** r1 · блокирующих циклов 0/2
|
||||
|
||||
## Скоуп
|
||||
|
||||
ТЗ (тело issue): удалить неиспользуемое необязательное поле `stageSize` из
|
||||
`IsoOverlayFitEnvelopeInput` (`src/iso-scene-render.ts`) вместе с обоими местами
|
||||
передачи (`_isoScene` и обработчик фокуса комнаты, `src/houseplan-card.ts`);
|
||||
переписать юнит `#725 AC3`, который сравнивал `bounds` при `stageSize: null` и
|
||||
`{1000, 500}` — после удаления поля сравнение теряет предмет.
|
||||
|
||||
Диф: `src/houseplan-card.ts` (−2 строки), `src/iso-scene-render.ts` (−1 строка
|
||||
типа), `test/iso-scene-render.test.mjs` (тест переписан). Класс A (`src/**`) +
|
||||
класс B (тест). Один коммит, трейлеры `Issue: #741` / `User-Visible: no` —
|
||||
верно: изменение не видимо пользователю, changelog не тронут и не должен быть.
|
||||
|
||||
## Как проверялось
|
||||
|
||||
| Гейт | Статус | Как |
|
||||
|---|---|---|
|
||||
| `tsc --noEmit` | ✅ подтверждён | Validate на `a8c8f1d6`: https://github.com/Matysh/houseplan-card/actions/runs/36821143516 — не перегонял отдельно |
|
||||
| `npm test` (3410 тестов) | ✅ сам перегнал | `npm test` → `pass 3431, fail 0, skipped 1`; дополнительно `node --test test/iso-scene-render.test.mjs` отдельно → `31/31 pass` |
|
||||
| `npm run build` + сверка бандла | ✅ подтверждён Validate | не перегонял — дешёвый гейт уже зелёный на этом SHA |
|
||||
| «Тест умеет падать» (`#725 AC3/#741`) | ✅ проверено исполнением | временно мутировал `resolveIsoOverlayFitEnvelope` (внёс в `base` зависимость от `targetView`/aspect, имитируя регрессию «stage просочился в bounds»); пересобрал `test-build`, прогнал файл — упало 2 из 31 (`the overlay fit bounds depend only on scene.frame…`, `the view fits the bounds`); откатил файл, пересобрал, снова 31/31. Тест чувствителен к ровно тому регрессу, который он называет |
|
||||
| `node scripts/smoke-select.mjs --base 76558bf2 --head a8c8f1d6` | выполнено | **НЕОПРЕДЕЛЁННОСТЬ**: 0 символов проекта на изменённых строках (чистое удаление мёртвого поля типа), ни один смок не связан доказуемо. Автор дополнительно прогнал `smoke_room_fit`, `smoke_isometric_contract`, `smoke_iso_flat_parity` (все три существуют в `demo/`, по названию относятся к затронутой функции) — разумный выбор поверх визуального минимума; браузерные смоки сам не перегонял (AC их не называет, Chromium не поднимал) |
|
||||
| `npm run golden:verify` | не требуется | метки `ci:golden` нет, рендер пикселей не меняется (ниже) |
|
||||
| `pytest tests_backend` | не требуется | Python не тронут |
|
||||
| `npm run invariants` | не требуется | геометрия и ссылки на неё не меняются — меняется только форма входного объекта функции разметки, не геометрическая модель |
|
||||
|
||||
## Риск по изменённым участкам (#707)
|
||||
|
||||
- **perf — `src/iso-scene-render.ts:651` (удалена), участок `iso-scene-render`.**
|
||||
Поведение уже зафиксировано: читал тело `resolveIsoOverlayFitEnvelope`
|
||||
(`src/iso-scene-render.ts:658-668`) и в версии до диффа, и после — `input.stageSize`
|
||||
нигде не читается, функция использует только `baseBounds`, `entries`,
|
||||
`ownerId`, `targetView`. Удаление поля из интерфейса и обоих мест передачи —
|
||||
изменение только по типам, ни одного пути исполнения не задевает. Документ
|
||||
`docs/ISOMETRIC.md` (раздел «Fit», строки ~245-263) фиксирует контракт прямо:
|
||||
«Neither zoom nor a stage resize is a layout event… the fit envelope reserves
|
||||
no nudge budget» — т.е. stage/aspect и до этой задачи не должны были влиять на
|
||||
раскладку. route: `fix` (критерий не нарушен — `perf-touch`: изменения
|
||||
производительности нет, т.к. убираемый путь не исполнялся).
|
||||
- **visual (render) — `src/iso-scene-render.ts:651` (удалена), участок `iso-*` (render).**
|
||||
То же: поле не читалось, значит удаление не может изменить картинку. Плюс
|
||||
переписанный юнит `#725 AC3/#741` это утверждает явно и проверяемо: `bounds`
|
||||
идентичны для пяти разных aspect (0.5, 1, 1000/500, 320/180, собственный aspect
|
||||
кадра), различается только `view`; я подтвердил мутационным прогоном (таблица
|
||||
выше), что тест ловит регресс, где это переставало бы быть так. Визуальный
|
||||
минимум прогоняется `gate:small` (автор) — отдельного `ci:golden` для
|
||||
переноса/удаления неиспользуемого поля типа не требуется: рендер-путь не
|
||||
меняется ни на один пиксель, доказательство — отсутствие чтения поля в коде
|
||||
плюс тест. route: `fix`.
|
||||
|
||||
## Находки
|
||||
|
||||
Нет. Диф — корректное удаление мёртвого поля, оба места передачи вычищены
|
||||
полностью (`grep -rn stageSize src/` — пусто), заменяющий тест по существу
|
||||
эквивалентен старому AC и доказуемо чувствителен к регрессу (проверено
|
||||
мутацией, не только чтением). Якорь мутационного реестра `#725 AC5`
|
||||
(`scripts/mutation-registry.mjs:13846-13857`, строка
|
||||
`const aspect = scene.frame.w / scene.frame.h; // #713/#725: …`) не тронут
|
||||
диффом — заявление автора «якорь #725 на месте» подтверждено чтением.
|
||||
|
||||
Побочный файл `test/iso-overlay-fixture-types.test.mjs` тоже содержит
|
||||
`DEAD_SCENE_FIELDS` со строкой `'stageSize'` — проверил: это другой тип,
|
||||
`OverlaySceneFixture` входа `buildIsoOverlayRenderScene`/`overlayScene`
|
||||
(#714/#724/#732), не `IsoOverlayFitEnvelopeInput`. Задача #741 его не задевает
|
||||
и трогать не должна была.
|
||||
|
||||
## Что проверено и корректно
|
||||
|
||||
- Оба места передачи `stageSize` удалены полностью, без мёртвых остатков
|
||||
(переменная `stage` в обработчике фокуса комнаты продолжает использоваться
|
||||
для `baseFit`/`targetOf` — не осиротела).
|
||||
- Трейлеры коммита корректны: `Issue: #741`, `User-Visible: no`, changelog не
|
||||
тронут — согласуется (невидимое изменение).
|
||||
- Диф в пределах заявленных ship-лимитов по `src/**` (+2/−4), новых файлов,
|
||||
i18n, полей конфига нет — но ревью идёт по треку `show`, как и требует метка.
|
||||
- `npm test` зелёный целиком (3431 pass / 0 fail / 1 skip), не только
|
||||
затронутый файл.
|
||||
|
||||
## Чего не проверял
|
||||
|
||||
- Полный `tsc --noEmit` и `npm run build` с сверкой трёх копий бандла —
|
||||
перегонять не стал, взял зелёный Validate на этом же SHA (дешёвые гейты
|
||||
параграф §8).
|
||||
- Браузерные смоки (`smoke_room_fit`, `smoke_isometric_contract`,
|
||||
`smoke_iso_flat_parity`) сам не выполнял — `smoke-select` вернул
|
||||
НЕОПРЕДЕЛЁННОСТЬ (связь не доказана), AC их не называет, Chromium не
|
||||
поднимал; полагаюсь на заявленный автором зелёный прогон.
|
||||
- `npm run golden:verify`, `pytest tests_backend`, `npm run invariants` —
|
||||
не запускал, т.к. не применимы к этому диффу (см. таблицу гейтов).
|
||||
|
||||
## Вердикт
|
||||
|
||||
Зелёный. AC выполнены полностью, класс риска `perf`/`visual` закрыт документом
|
||||
`docs/ISOMETRIC.md` и подтверждён чтением кода и мутационной проверкой теста;
|
||||
находок нет.
|
||||
|
||||
---
|
||||
|
||||
<!-- material-anchors: сгенерировано конвейером (#414) -->
|
||||
|
||||
## Материал раунда
|
||||
|
||||
- Ветка: `issue/741-drop-stage-size`, коммит `a8c8f1d68aa7` — ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет.
|
||||
- Дерево материала: `84476d1a976435349921933a39178f4d2989d75f`
|
||||
```
|
||||
git log --all --format='%H %T' | grep 84476d1a9764
|
||||
```
|
||||
- Тело issue: `2ca2e0ad99b76c735fed07cd61d7ee08f1a58d6a9a6365322540273eb3d0c794`
|
||||
- Вердикт конвейера: `green` · High 0 · маршрут `fix`
|
||||
Reference in New Issue
Block a user