mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-28 19:01:34 +00:00
docs: specify removal of isometric overlay plates
Issue: #471 User-Visible: no
This commit is contained in:
@@ -0,0 +1,394 @@
|
||||
# #471 — Убрать видимые raised plates вокруг элементов изометрического View
|
||||
|
||||
- **Issue:** https://github.com/Matysh/houseplan-card/issues/471
|
||||
- **Тип / приоритет:** bug + polish / P1
|
||||
- **Трек:** полный; задача отменяет явно принятый UX-контракт Stage 3 из #160,
|
||||
поэтому не проходит критерий лёгкого трека «нет нового или изменённого
|
||||
UX-контракта»
|
||||
- **Оценка:** пользовательская ценность 8/10; ценность для архитектуры 7/10;
|
||||
сложность 4/10; риск 4/10
|
||||
- **Связано:** #89, #122, #160; `docs/ISOMETRIC.md`,
|
||||
`docs/adr/160-isometric-stage3-overlays.md`
|
||||
|
||||
## 1. Сценарий
|
||||
|
||||
Персона — Home admin из `docs/SCOPE.md`, который тестирует скрытый
|
||||
изометрический режим в полном House Plan View на desktop, wall tablet либо
|
||||
телефоне. Момент — план со множеством устройств и подписей комнат целиком
|
||||
вписан в доступную область, поэтому белые подложки поднятых элементов занимают
|
||||
заметную долю изображения и перекрывают архитектуру.
|
||||
|
||||
## 2. Что человек увидит до и после
|
||||
|
||||
**До:** вокруг маркеров видны дополнительные белые квадраты, а под длинными
|
||||
названиями комнат — широкие белые полосы, пересекающие пол и стены.
|
||||
|
||||
**После:** остаются сами маркеры с их штатными компактными подложками и обычный
|
||||
текст комнаты; дополнительного прямоугольного фона вокруг полного габарита
|
||||
элемента нет.
|
||||
|
||||
## 3. Подтверждённая причина и заменяемый контракт
|
||||
|
||||
Артефакт является намеренной частью Stage 3, а не браузерной ошибкой:
|
||||
|
||||
- `ISO_RAISED_FOOTPRINT` и `isoRaisedOverlayHalfSize()` в
|
||||
`src/iso-scene-render.ts` вычисляют консервативный габарит для device,
|
||||
room-label и opening-lock;
|
||||
- `resolveIsoOverlayPlacement()` в `src/iso-overlays.ts` проецирует этот габарит
|
||||
и использует его для wall collision, nudge и tether policy;
|
||||
- `renderIsoRaisedOverlays()` рисует тот же габарит как SVG polygon;
|
||||
- `.iso-overlay-plate` в `src/styles/plan.styles.ts` имеет почти непрозрачную
|
||||
светлую заливку `rgba(248, 249, 247, 0.9)`;
|
||||
- room footprint резервирует worst-case ширину всех включённых метрик, а device
|
||||
footprint — auxiliary extent, даже если фактическое содержимое короче;
|
||||
- golden `demo/golden/baselines/isometric-stage3-overlays-light.png` и
|
||||
contract/smoke тесты сейчас закрепляют наличие видимого polygon.
|
||||
|
||||
Первый коммит с поведением — `ee7d4869` из #160. D3 и AC4 исходного ТЗ #160,
|
||||
ADR и текущий `docs/ISOMETRIC.md` называют эту поверхность raised plate.
|
||||
|
||||
#471 заменяет только визуальную часть этого решения: консервативная геометрия
|
||||
остаётся невидимым collision/fit footprint, но больше не является декоративной
|
||||
поверхностью. Сам raised plane, координаты и интерактивность не отменяются.
|
||||
|
||||
## 4. Решение владельца
|
||||
|
||||
В изометрическом View ни у одного поднятого overlay нет отдельной видимой
|
||||
floor-parallel подложки по его общему прямоугольному габариту.
|
||||
|
||||
Единое правило применяется к:
|
||||
|
||||
1. device marker целиком;
|
||||
2. room name и room metrics card;
|
||||
3. opening lock marker.
|
||||
|
||||
Штатные собственные поверхности содержимого не относятся к удаляемой plate:
|
||||
|
||||
- shell/core маркера устройства;
|
||||
- value badge, LQI и прочие satellite badges;
|
||||
- компактная поверхность lock marker;
|
||||
- focus/selection/hover affordance, определённые самим интерактивным root.
|
||||
|
||||
Grounding shadow и tether остаются. Консервативный footprint остаётся
|
||||
невидимой расчётной геометрией для collision, nudge, fit/home и room fit.
|
||||
|
||||
## 5. Скоуп
|
||||
|
||||
1. Прекратить вывод видимых SVG plate и plate texture для всех трёх raised
|
||||
overlay kinds.
|
||||
2. Сохранить footprint и все потребляющие его placement/bounds алгоритмы без
|
||||
числового изменения результата.
|
||||
3. Развести в именовании и документации невидимый footprint и удалённую
|
||||
декоративную plate, чтобы safety envelope нельзя было снова принять за
|
||||
пользовательскую поверхность.
|
||||
4. Удалить ставшие неиспользуемыми plate styles и overlay texture definition;
|
||||
grounding shadow definition сохранить.
|
||||
5. Переписать contract/unit/browser доказательства, которые сейчас требуют
|
||||
видимый polygon.
|
||||
6. Переснять затронутые изометрические golden только через независимое Linux
|
||||
acceptance по общему процессу.
|
||||
7. Актуализировать текущие внутренние документы Stage 3.
|
||||
|
||||
## 6. Не входит
|
||||
|
||||
- изменение высоты raised plane, камеры `4°/20°`, wall height или visual offset;
|
||||
- изменение размеров консервативного footprint;
|
||||
- новое измерение фактического DOM, `ResizeObserver` либо layout read-loop;
|
||||
- изменение wall collision, owner selection, nudge direction/cap или tether
|
||||
visibility rules;
|
||||
- удаление grounding shadow либо tether;
|
||||
- новый фон, text shadow, blur, outline или другая замена белой plate;
|
||||
- редизайн shell/core, badge, room typography либо opening lock;
|
||||
- изменение z-order, Zigbee topology, Glow, sunlight, vacuum и opening volume;
|
||||
- новые настройки, schema/config/layout/storage поля, миграция либо i18n;
|
||||
- публичное включение изометрического режима;
|
||||
- изменение Flat, редакторов или `houseplan-space-card`.
|
||||
|
||||
Если читаемость конкретного текста без общей подложки окажется недостаточной,
|
||||
альтернативный локальный text treatment требует отдельного продуктового
|
||||
решения и не добавляется в #471 попутно.
|
||||
|
||||
## 7. Контракт невидимого footprint
|
||||
|
||||
Для каждого raised overlay по-прежнему вычисляются:
|
||||
|
||||
1. неизменная логическая floor-точка;
|
||||
2. projected floor point;
|
||||
3. raised point до nudge;
|
||||
4. консервативный screen-facing footprint на raised plane;
|
||||
5. конечный visual point и тот же footprint после nudge;
|
||||
6. grounding и tether geometry.
|
||||
|
||||
Footprint не попадает в SVG/HTML как закрашенная или обведённая поверхность и
|
||||
не создаёт собственный stacking/paint artifact. Он остаётся входом для:
|
||||
|
||||
- пересечения с canonical wall silhouettes и safety gap;
|
||||
- bounded inward nudge;
|
||||
- `nearWallBefore` / `nearWallAfter` и tether visibility;
|
||||
- `isoOverlaySceneBounds()`;
|
||||
- стабильного `resolveIsoOverlayFitEnvelope()` для fit/home и room fit.
|
||||
|
||||
Удаление декора не должно менять ни одну координату либо boolean/status
|
||||
placement result на одинаковом входе. Переименование внутренних полей
|
||||
`plate*` в `footprint*` предпочтительно и не является изменением модели данных.
|
||||
|
||||
## 8. Контракт рендера и композиции
|
||||
|
||||
`iso-overlays-svg` сохраняется как inert слой для grounding и tether. В нём не
|
||||
должно быть `.iso-overlay-plate`, `.iso-overlay-plate-texture` либо эквивалентной
|
||||
залитой/обведённой геометрии footprint.
|
||||
|
||||
Порядок остаётся прежним:
|
||||
|
||||
1. floor/live content;
|
||||
2. structural walls/openings;
|
||||
3. grounding/tether cues;
|
||||
4. screen-facing HTML markers/labels/locks;
|
||||
5. системные tooltip/dialog/chrome.
|
||||
|
||||
HTML roots продолжают получать один и тот же `visualScene`. Их role, tabindex,
|
||||
accessible name, pointer/keyboard handlers, hit target и CSS собственных
|
||||
элементов не меняются.
|
||||
|
||||
`layers.materialNuance` больше не создаёт overlay texture pattern, потому что
|
||||
допустимой поверхности для него нет. `layers.shadows` продолжает управлять
|
||||
только grounding shadow. Ошибка decorative capability не должна переводить
|
||||
сцену в Flat.
|
||||
|
||||
## 9. Режимы, состояния и graceful degradation
|
||||
|
||||
- Light/dark theme используют одно правило «без plate».
|
||||
- Forced colors не возвращает `fill: Canvas` вокруг overlay; собственные
|
||||
нативные поверхности marker/lock продолжают существующий forced-colors
|
||||
контракт.
|
||||
- No-filter скрывает grounding nuance как раньше, но не меняет наличие
|
||||
содержимого.
|
||||
- Reduced motion ничего не меняет в конечном кадре; новой анимации нет.
|
||||
- Kiosk и coarse pointer показывают тот же результат, сохраняя минимум 44×44 px
|
||||
у интерактивного HTML root.
|
||||
- `show_borders:false` по-прежнему полностью отключает raised placement,
|
||||
grounding и tether и возвращает overlays к floor anchor.
|
||||
- Flat, Plan/Devices/Background editors и static card не получают изменений DOM
|
||||
либо CSS.
|
||||
|
||||
## 10. UX и доступность
|
||||
|
||||
Новых контролов, жестов, подсказок и текстов нет. Изменение только убирает
|
||||
визуальный шум. Room fit/Area link, device click/context action и opening-lock
|
||||
semantics остаются действующими.
|
||||
|
||||
Invisible footprint, grounding и tether не получают role, accessible name,
|
||||
tab stop или pointer events. Focus ring принадлежит исходному HTML root и не
|
||||
зависит от удалённой plate.
|
||||
|
||||
## 11. Модель данных, совместимость и i18n
|
||||
|
||||
Config, layout, backend stores, schema version, export/import и localStorage не
|
||||
меняются. Миграции и downgrade converter отсутствуют.
|
||||
|
||||
Внутреннее переименование поля placement не сериализуется и не является
|
||||
compatibility surface. Старый frontend после downgrade прочитает те же данные
|
||||
и снова покажет прежнюю plate.
|
||||
|
||||
Новых или изменённых строк нет; словари EN/RU/DE/FR не меняются.
|
||||
|
||||
## 12. Производительность и lifecycle
|
||||
|
||||
- Structural fingerprint, LRU cap 8 и cache invalidation остаются прежними.
|
||||
- HA state, hover/focus, pan/zoom и opening update не начинают перестраивать
|
||||
structural scene либо читать layout.
|
||||
- Удаляются до двух SVG polygon на raised overlay и один неиспользуемый shared
|
||||
texture pattern; DOM/paint объём может только уменьшиться.
|
||||
- Footprint/nudge computation сохраняет прежнюю сложность и кэширование.
|
||||
- Initial Flat graph и alpha lazy boundary не меняются.
|
||||
- Новый performance profile не нужен; существующие Stage 3 counts,
|
||||
`bundle:budget` и точечный isometric smoke не должны регрессировать.
|
||||
|
||||
## 13. Security и privacy
|
||||
|
||||
Новых API, URL, persistence, HA service call или пользовательского HTML нет.
|
||||
Удаляемая геометрия уже pointer/ARIA-inert; после исправления существующие
|
||||
interactive roots остаются единственными владельцами действий.
|
||||
|
||||
## 14. Критерии приёмки
|
||||
|
||||
### AC1 — видимый результат (browser raster + reviewed golden)
|
||||
|
||||
В light и dark изометрическом View отсутствует дополнительный прямоугольный
|
||||
или квадратный фон вокруг device, room label/card и opening lock. Длинное имя
|
||||
комнаты при fit/home и минимальном масштабе не создаёт белую полосу через стены.
|
||||
Штатные shell/core/badges/lock surfaces остаются.
|
||||
|
||||
### AC2 — отсутствие скрытых визуальных fallback (contract + smoke)
|
||||
|
||||
Raised SVG не содержит `.iso-overlay-plate`, plate texture либо эквивалентной
|
||||
painted footprint geometry при material nuance on/off, forced colors и
|
||||
unsupported filter. Возврат одного непрозрачного polygon делает защитный тест
|
||||
красным.
|
||||
|
||||
### AC3 — placement parity (unit exact matrix)
|
||||
|
||||
На одинаковых fixtures до/после исправления совпадают floor/raised/visual
|
||||
anchors, footprint points, nudge vector/distance, near-wall flags, status,
|
||||
reason, tether и grounding для device, room-label и opening-lock.
|
||||
|
||||
### AC4 — fit и границы (unit + browser smoke)
|
||||
|
||||
`isoOverlaySceneBounds`, fit/home и room fit продолжают учитывать невидимый
|
||||
footprint и полный screen-facing root. Конечный viewBox и позиция элементов не
|
||||
меняются только из-за удаления декора; длинные/короткие имена и 0/часть/все
|
||||
room metrics не клипуются.
|
||||
|
||||
### AC5 — interaction и touch (browser smoke)
|
||||
|
||||
Device hover/focus/click/context action, room click/Area link, lock action и
|
||||
44×44 px target работают по прежним roots. Ground/tether/footprint не
|
||||
перехватывают pointer. Kiosk/coarse pointer сохраняют View safety floor.
|
||||
|
||||
### AC6 — режимы и соседние слои (contract + browser smoke)
|
||||
|
||||
`show_borders:false` возвращает floor placement без raised subtree; Flat,
|
||||
редакторы и static card не меняются. Zigbee topology endpoints продолжают
|
||||
совпадать с фактическими поднятыми marker positions.
|
||||
|
||||
### AC7 — data/performance contract (unit + source contract)
|
||||
|
||||
Нет новых config/layout/storage/i18n/network/service полей. Structural
|
||||
fingerprint/build count и LRU не меняются; overlay material definition count и
|
||||
polygon count уменьшаются, а bundle остаётся в действующем бюджете.
|
||||
|
||||
### AC8 — документация и артефакты (review)
|
||||
|
||||
`docs/ISOMETRIC.md`, ADR #160 и исходное ТЗ #160 явно отмечают superseding
|
||||
решение #471: plate как видимая поверхность удалена, footprint как расчётная
|
||||
геометрия сохранён. Затронутые golden приняты независимым reviewer из полного
|
||||
Linux artifact.
|
||||
|
||||
## 15. План автотестов и red witnesses
|
||||
|
||||
### Unit/contract
|
||||
|
||||
1. Обновить `test/iso-overlays.test.mjs`: footprint остаётся четырёхугольником,
|
||||
а все placement outputs для free/near-wall/nudged/degraded/no-borders
|
||||
fixtures сохраняются.
|
||||
2. Обновить `test/iso-scene-render.test.mjs`: footprint по-прежнему учитывает
|
||||
device auxiliaries и room metrics; scene/fit bounds используют его без
|
||||
видимого renderer.
|
||||
3. Обновить `test/isometric-contract.test.mjs`: запретить plate selectors,
|
||||
polygons и overlay texture definition; сохранить raised root, grounding,
|
||||
tether, forced-colors и 44 px contracts.
|
||||
4. Проверить material definition count без orphan `hp-iso-overlay-texture`.
|
||||
|
||||
### Browser smoke
|
||||
|
||||
Расширить `demo/smoke_isometric_contract.mjs` и при необходимости
|
||||
`demo/smoke_isometric_live_touch.mjs`:
|
||||
|
||||
- dense device set и room label с 0/частью/всеми метриками;
|
||||
- отсутствие painted footprint в обычном, dark, forced-colors и no-filter;
|
||||
- неизменные centres/nudge/tether/bounds;
|
||||
- fit/home и room fit без клиппинга;
|
||||
- pointer/keyboard/coarse-pointer actions и 44 px target;
|
||||
- topology endpoint следует фактическому marker root.
|
||||
|
||||
### Golden
|
||||
|
||||
Переснять только действительно изменённые Iso Stage 3 кадры. Flat baselines
|
||||
должны остаться byte/pixel unchanged. Обязателен плотный общий кадр с длинными
|
||||
названиями и несколькими типами marker; возвращённая непрозрачная plate должна
|
||||
создавать заметный diff.
|
||||
|
||||
Golden acceptance выполняет только независимый reviewer через
|
||||
`npm run golden:accept -- --reviewed` на полном Linux CI artifact с provenance.
|
||||
|
||||
### Red witnesses
|
||||
|
||||
| Witness | Искусственная поломка | Обязательный красный тест |
|
||||
|---|---|---|
|
||||
| W1 | Вернуть один painted footprint polygon | DOM/raster smoke и Iso golden |
|
||||
| W2 | Удалить footprint из wall collision | near-wall/nudge unit |
|
||||
| W3 | Удалить footprint из fit bounds | long-room-label fit smoke |
|
||||
| W4 | Удалить 44 px target вместе с plate | coarse-pointer smoke |
|
||||
| W5 | Вернуть `fill: Canvas` plate в forced colors | forced-colors contract/smoke |
|
||||
| W6 | Оставить orphan overlay texture pattern | definition-count contract |
|
||||
|
||||
Каждый witness запускается на минимальном тесте и полностью откатывается до
|
||||
финального зелёного состояния.
|
||||
|
||||
## 16. Ожидаемые файлы реализации
|
||||
|
||||
Продукт и тесты:
|
||||
|
||||
- `src/iso-overlays.ts`;
|
||||
- `src/iso-scene-render.ts`;
|
||||
- `src/styles/plan.styles.ts`;
|
||||
- `test/iso-overlays.test.mjs`;
|
||||
- `test/iso-scene-render.test.mjs`;
|
||||
- `test/isometric-contract.test.mjs`;
|
||||
- `demo/smoke_isometric_contract.mjs`;
|
||||
- при необходимости `demo/smoke_isometric_live_touch.mjs`;
|
||||
- затронутые Iso golden после независимого принятия.
|
||||
|
||||
Документация:
|
||||
|
||||
- `docs/ISOMETRIC.md`;
|
||||
- `docs/ARCHITECTURE.md`;
|
||||
- `docs/adr/160-isometric-stage3-overlays.md`;
|
||||
- `docs/specs/160-isometric-stage3.md`;
|
||||
- `docs/TESTING.md` и `docs/STATUS.md` только в части действующего Stage 3
|
||||
контракта/доказательств;
|
||||
- этот документ и индекс `docs/specs/README.md`.
|
||||
|
||||
Backend, schema, translations и `src/space-card.ts` не меняются.
|
||||
|
||||
## 17. Release-артефакты
|
||||
|
||||
Изометрический Stage 3 остаётся скрытым за `hp_alpha`, поэтому по действующему
|
||||
решению #160 реализация имеет `User-Visible: no` и не получает публичную запись
|
||||
в `docs/CHANGELOG.md`, `docs/CHANGELOG.ru.md`, README, User Guide, HACS или
|
||||
release body.
|
||||
|
||||
Обязательны:
|
||||
|
||||
- синхронные manifest-driven bundles через `npm run bundle:sync`;
|
||||
- адресные unit/contract/browser tests;
|
||||
- `golden:verify` с ожидаемым Iso diff и отсутствием Flat diff;
|
||||
- independently reviewed Linux golden acceptance;
|
||||
- `check-docs` и штатные exact-SHA beta gates;
|
||||
- обновление внутренних Stage 3 документов в том же product commit.
|
||||
|
||||
## 18. Риски и меры
|
||||
|
||||
| Риск | Мера |
|
||||
|---|---|
|
||||
| Вместе с декором удаляется collision geometry | Отдельное имя footprint и exact placement unit matrix |
|
||||
| Fit начинает клиповать длинные подписи | Footprint остаётся в scene/fit bounds; browser fit smoke |
|
||||
| Исчезает штатная shell маркера | AC1 отдельно различает native surface и raised plate |
|
||||
| Forced colors возвращает белые квадраты | Negative selector + forced-colors smoke |
|
||||
| Tether/grounding исчезают из-за удаления всего subtree | Отдельные DOM assertions и golden |
|
||||
| Golden снова закрепляет случайный фон | W1 и обязательный dense reviewed frame |
|
||||
| Переименование внутреннего поля задевает cache | Structural fingerprint/build-count assertions |
|
||||
| Улучшение скрытой alpha попадает в публичные notes | Явный `User-Visible: no` и отрицательный список артефактов |
|
||||
|
||||
## 19. Откат
|
||||
|
||||
Кодовый откат одного product commit возвращает декоративные polygons и styles.
|
||||
Config/layout/store не меняются, поэтому миграция, восстановление данных и
|
||||
действия пользователя не нужны. Немедленный пользовательский workaround —
|
||||
переключиться в Flat либо отключить `hp_alpha`.
|
||||
|
||||
## 20. Принятые технические предположения — можно менять на ревью
|
||||
|
||||
1. Внутренние `plate`, `plateHalfSize`, `buildIsoPlatePolygon` и
|
||||
`plateNearSilhouette` переименовываются в `footprint*`; это снижает риск снова
|
||||
отрисовать safety envelope. Допустимо сохранить старые имена, если tests/docs
|
||||
столь же однозначно запрещают видимую поверхность.
|
||||
2. `renderIsoRaisedOverlays()` может сохранить имя и выводить только tethers;
|
||||
DOM topology функции не является публичным контрактом.
|
||||
3. Fit/home намеренно сохраняет прежний envelope, даже если после удаления
|
||||
plate визуально можно было бы вписать план плотнее. Изменение framing — другая
|
||||
UX-задача.
|
||||
4. Opening-lock включён в единое правило, потому использует тот же общий
|
||||
renderer; оставшийся квадрат был бы тем же артефактом.
|
||||
5. Grounding shadow остаётся допустимой непрямоугольной подсказкой связи с
|
||||
floor anchor и не считается заменой plate.
|
||||
@@ -28,6 +28,7 @@ GitHub Issues и GitHub Projects (v2) остаются единственным
|
||||
|
||||
| Issue | ТЗ |
|
||||
|---|---|
|
||||
| [#471](https://github.com/Matysh/houseplan-card/issues/471) Убрать белые raised plates вокруг маркеров и названий комнат | [471-isometric-overlay-white-plates.md](471-isometric-overlay-white-plates.md) |
|
||||
| [#6](https://github.com/Matysh/houseplan-card/issues/6) Vacuum XCME path segments | [006-vacuum-xcme-path.md](006-vacuum-xcme-path.md) |
|
||||
| [#7](https://github.com/Matysh/houseplan-card/issues/7) Valetudo room outlines | [007-vacuum-valetudo-room-outlines.md](007-vacuum-valetudo-room-outlines.md) |
|
||||
| [#8](https://github.com/Matysh/houseplan-card/issues/8) Vacuum support docs and XCME hint | [008-vacuum-support-docs-xcme-hint.md](008-vacuum-support-docs-xcme-hint.md) |
|
||||
|
||||
Reference in New Issue
Block a user