From 009fed9bc0969e5384354501e13657dd15248c7a Mon Sep 17 00:00:00 2001 From: Sergey Matyunin Date: Wed, 19 Aug 2026 18:17:05 +0300 Subject: [PATCH] docs: specify hidden room names Issue: #203 User-Visible: no --- docs/specs/203-hide-room-names.md | 248 ++++++++++++++++++++++++++++++ docs/specs/README.md | 1 + 2 files changed, 249 insertions(+) create mode 100644 docs/specs/203-hide-room-names.md diff --git a/docs/specs/203-hide-room-names.md b/docs/specs/203-hide-room-names.md new file mode 100644 index 00000000..a5f85633 --- /dev/null +++ b/docs/specs/203-hide-room-names.md @@ -0,0 +1,248 @@ +# Issue #203 — выключение названий скрывает все подписи комнат + +- Дата: 2026-08-19 +- Тип: bug · приоритет P2 · ценность 7/10 · сложность 3/10 +- Issue: [#203](https://github.com/Matysh/houseplan-card/issues/203) +- Ветка: `issue/203-hide-room-names` + +Канонические документы: `docs/SCOPE.md`, `docs/UX-MODES.md`, +`docs/STYLING-HOOKS.md`, `docs/USER-GUIDE.ru.md`, `docs/TESTING.md`. + +## 1. Сценарий и персона + +Администратор дома открывает настройки пространства, выключает «Отображать +названия комнат (перетаскиваются)» и сохраняет. Он ожидает чистый View без +постоянных подписей, например для маленького экрана, фонового чертежа с уже +нанесёнными названиями или плана, где достаточно интерактивных устройств. + +Это штатная часть J4/J6: явно выключенный визуальный слой должен исчезнуть на +всех пользовательских представлениях одного пространства. + +## 2. Что человек увидит до и после + +**До:** draggable HTML-карточка исчезает вместе с температурой, влажностью, +LQI и состоянием света, но на нарисованном плане без фонового изображения +возникает другая SVG-подпись. Имя остаётся, перемещается в геометрический центр +комнаты и меняет стиль. Компактная карточка пространства повторяет дефект. + +**После:** при выключенной настройке в View, Devices editor и компактной +карточке нет постоянной подписи комнаты ни в HTML, ни в SVG. В Plan editor имя +по-прежнему временно показывается как редактируемый объект. При повторном +включении возвращается прежняя draggable карточка с сохранённой позицией, +масштабом, HA Area icon и разрешёнными метриками. + +## 3. Подтверждённая проблема и причина + +Persisted значение и основной resolver исправны: + +- `spaceDisplayOf()` возвращает `showNames: false` для явного + `settings.show_names: false`; +- `_saveSpaceDialog()` записывает `show_names: d.showNames` для существующего + пространства; +- основной `.devlayer` перестаёт рендерить `_renderRoomLabel()`, поэтому + HTML-карточка и её `.rlmetrics` действительно исчезают. + +Ошибка находится в двух fallback-ветках. `_renderSvgRoomLabels()` полного +renderer при `!space.bg && !disp.showNames` создаёт ``. +`renderSpaceCard()` независимо делает то же через `staticSvgLabels`. Они +инвертируют смысл настройки. Скрытая изометрическая ветка дополнительно +форсирует HTML-карточки при `iso && !space.bg`, даже если `showNames === false`. + +Именно смена HTML-карточки на SVG-текст объясняет все детали репорта: имя +остаётся, метрики пропадают, сохранённая layout-позиция не используется, цвет и +типографика становятся другими. На пространстве с `bg` дефект маскируется, +потому что SVG-fallback уже запрещён условием `space.bg`. + +## 4. Scope + +- сделать `show_names: false` единым запретом постоянных room-labels в полном + flat/iso View, Devices editor и компактной карточке пространства; +- сохранить принудительную видимость редактируемой HTML-подписи в Plan editor; +- сохранить live-preview значения в открытом диалоге настроек пространства; +- при `show_names: true` не менять состав, позицию, масштаб, цвет, метрики, + HA Area icon, drag/resize и навигацию комнатной карточки; +- удалить или обезвредить ошибочные SVG-fallback renderer и актуализировать + больше не существующий `.rlabel` styling-hook; +- добавить browser regression, mutation gate, визуальное доказательство и + пользовательскую/тестовую документацию. + +## 5. Non-scope + +- изменение текста/назначения переключателя или добавление второго режима + «статические названия»; +- скрытие названия комнаты внутри tooltip, диалога настроек, HA Area или + accessibility-описания самой комнаты: настройка управляет подписями на плане; +- удаление либо сброс `layout.rl_`, масштаба подписи или room metrics; +- изменение `show_borders`, room fill, Glow, openings, devices и room hover; +- изменение дефолта `show_names` для новых/legacy пространств — это отдельная + проблема #204; +- schema/backend/API, migration, импорт/экспорт и Optimize; +- публичное включение изометрии или изменение её геометрии; +- редизайн комнатной карточки, Plan gear/handles или compact space card. + +## 6. Контракт поведения + +### 6.1. Матрица видимости + +| Поверхность | `show_names: true` | `show_names: false` | +|---|---|---| +| Full View, flat | Одна HTML `.roomlabel` на именованную комнату | Нет HTML/SVG room-label | +| Full View, hidden iso | Та же HTML `.roomlabel`, спроецированная существующей iso-логикой | Нет HTML/SVG room-label | +| Devices editor | Одна HTML `.roomlabel` | Нет HTML/SVG room-label | +| Plan editor | Одна редактируемая HTML `.roomlabel` | Та же editor-only `.roomlabel` | +| Compact space card | Одна HTML `.roomlabel` | Нет HTML/SVG room-label | + +Условие `!space.bg` больше не создаёт альтернативный способ показать имя. +Наличие или отсутствие фонового изображения не влияет на матрицу. + +### 6.2. Повторное включение + +Выключение не удаляет `layout.rl_` и room settings. После повторного +включения карточка возвращается в сохранённую позицию и с сохранёнными +`k/name_scale/label_scale`. Разрешённые `label_temp`, `label_hum`, `label_lqi` +и `label_light` снова отображаются по существующим правилам и данным. + +### 6.3. Plan editor + +Plan editor сохраняет исключение `_markup`: подпись нужна для drag, resize и +доступа к редактируемому имени. Это исключение не должно протекать в View после +выхода из редактора. Room gear и placeholder безымянной комнаты сохраняются. + +### 6.4. Диалог настроек + +При переключении `showNames` в edit-диалоге `_spaceDisplayForRender()` сразу +проецирует новое значение в затемнённый пользовательский View. Cancel возвращает +persisted значение, Save записывает boolean. Результат после повторного открытия +совпадает с сохранённым состоянием. + +## 7. Данные, совместимость и styling hooks + +Persisted-формат не меняется: `settings.show_names` уже валидируется и хранит +boolean. Миграция не нужна, конфигурация не переписывается при чтении. + +`div.roomlabel[data-hp="room-label"]` остаётся каноническим hook видимой +подписи. `text.rlabel` существовал только в противоречащей настройке fallback- +ветке и после исправления не является доступным runtime hook; строка о нём в +`docs/STYLING-HOOKS.md` удаляется или заменяется честным описанием отсутствия +подписи. `data-hp`, `data-id` и `data-area` HTML-карточки не меняются. + +Downgrade возвращает старый SVG-fallback, но не теряет данные. Пользовательский +CSS, намеренно показывавший `text.rlabel` при выключенных названиях, перестаёт +иметь target — это необходимое следствие исправления ложного поведения, а не +новая точка расширения. + +## 8. UX, i18n, accessibility и touch + +Новых строк и элементов управления нет. Существующий русский и английский +текст становится честным. Выключенная подпись не оставляет пустого DOM-узла, +focus target или невидимой pointer-зоны. Tooltip комнаты и room hover остаются +доступны по геометрии комнаты, поэтому получить сведения по комнате можно. + +Touch/keyboard policy и события Plan editor не меняются. При включённых именах +существующие drag, resize handles, Area navigation и accessibility-описания +сохраняются. + +## 9. Acceptance criteria и доказательства + +| AC | Критерий | Обязательное доказательство | +|---|---|---| +| AC1 | На нарисованном пространстве без `bg`, при `show_names:false`, в flat View нет ни `.roomlabel`, ни `.room-svg-labels text`, ни `[data-hp="room-label"]`. | Targeted Playwright smoke через реальный space setting. | +| AC2 | AC1 выполняется в компактной карточке пространства. | Тот же smoke на `houseplan-space-card`. | +| AC3 | Hidden iso при `show_names:false` не форсирует подписи; при `true` сохраняет существующую projected HTML-карточку. | Расширенный isometric contract/live smoke. | +| AC4 | Plan editor показывает редактируемую подпись при `show_names:false`; после выхода View снова пуст. | Browser mode-transition smoke с DOM assertions. | +| AC5 | При `true` HTML-карточки, метрики, HA Area icon, сохранённая позиция/scale и текущие события не меняются. | Существующие room-card/link/parity smokes + focused regression. | +| AC6 | Toggle в edit-диалоге даёт live-preview, Save переживает повторное открытие, Cancel не пишет config. | Расширенный `smoke_space_settings.mjs` либо отдельный targeted smoke. | +| AC7 | `show_borders`, fills, Glow, devices, openings и room tooltip не меняются при выключении имён. | DOM snapshot/assertions targeted smoke + reviewed golden. | +| AC8 | Документация больше не обещает доступный `text.rlabel` hook и однозначно описывает переключатель. | Diff `STYLING-HOOKS`, user guide и `TESTING`. | +| AC9 | Ошибочный fallback доказан исполняемым мутантом. | `mutation-gate --check`, clean green / mutant red. | +| AC10 | Рабочие gates зелёные. | typecheck, unit, build и все затронутые targeted smokes. | + +## 10. План автотестов + +### 10.1. Unit/source contract + +Новая pure-логика не требуется. Существующие unit `spaceDisplayOf` уже +доказывают чтение явного `false`. Если итоговая реализация вынесет общую функцию +матрицы видимости, добавить table-driven unit; иначе не дублировать Lit-template +в искусственном source test. + +### 10.2. Browser smoke + +Расширить `demo/smoke_space_settings.mjs` или создать небольшой именной smoke: + +1. взять пространство без `plan_url/bg`, включить имена и зафиксировать одну + HTML-карточку с метрикой и сохранённой layout-позицией; +2. открыть edit-диалог и выключить имена, проверить live-preview; +3. Save и повторное открытие подтверждают `false` и отсутствие любых labels; +4. перейти в Plan — подпись и editor affordance видимы; вернуться в View — + снова скрыты; +5. повторить ключевую проверку в hidden iso и compact space card; +6. включить имена обратно и проверить восстановление карточки, позиции/scale и + метрики; +7. отдельно проверить Cancel и отсутствие `pageerror`/console error. + +`demo/smoke_styling_hooks.mjs` меняет прежнее утверждение «SVG-label существует +при false» на честное отсутствие любого label; HTML hook при true остаётся. +Смежные `smoke_room_cards.mjs`, `smoke_room_link.mjs`, room-label parity и iso +smokes прогоняются до code review. + +### 10.3. Golden и mutation gate + +Добавить/переиспользовать focused light/dark golden для нарисованного +пространства: reviewed baseline при `false` не содержит имён, при `true` +содержит существующие HTML-карточки. Общий `golden:verify` и полный smoke идут +перед бетой, но затронутые focused кадры обязательны при реализации. + +Mutation entry `hidden-room-names-svg-fallback` возвращает хотя бы одну +ошибочную full/compact fallback-ветку. Targeted guard обязан быть зелёным на +чистом коде и non-zero на мутанте. Если full и compact исправляются разными +необщими ветками, нужны два mutants, чтобы каждый renderer умел независимо +покраснеть. + +## 11. Риски и меры + +| Риск | Мера | +|---|---| +| Скрытие протечёт в Plan и лишит пользователя редактируемого имени. | Отдельная строка матрицы, AC4 и реальный переход режимов. | +| Исправится full card, но останется compact или iso override. | Независимые AC2/AC3 и mutants по renderer. | +| Повторное включение сбросит позицию/scale/metrics. | Запрет записи layout и round-trip AC5/AC6. | +| Вместе с label исчезнет tooltip/room pointer geometry. | Label DOM меняется отдельно от room shape; AC7. | +| Удалится документированный styling hook без объяснения. | Актуализация `STYLING-HOOKS` и compatibility note §7. | + +Performance улучшается либо нейтрален: удаляются DOM/SVG nodes и map по комнатам +при выключенном слое, новых проходов/таймеров/network calls нет. Security/privacy +boundary не меняется; настройка не становится механизмом сокрытия данных. + +## 12. Rollback + +Frontend-изменение откатывается вместе с тестами и документацией одним +коммитом. Данные и schema не меняются. Откат возвращает только ошибочный +SVG-fallback/iso override и не требует восстановления config или layout. + +## 13. Release-артефакты + +- пользовательские записи в `docs/CHANGELOG.md` и `docs/CHANGELOG.ru.md` в + implementation-коммите с `User-Visible: yes`; +- обновления `docs/USER-GUIDE.ru.md`, `docs/STYLING-HOOKS.md` и + `docs/TESTING.md`; +- targeted full/compact/Plan/iso browser evidence, styling-hook regression и + executable mutation gate; +- focused reviewed light/dark golden и синхронные bundle snapshots; +- отдельные backend, schema, migration, performance и security artifacts не + нужны; +- полные golden/smoke/performance остаются предрелизным гейтом. + +## 14. Принятые предположения + +Принято предположительно, поменять свободно при ревью: + +1. «Скрыть названия» управляет постоянными labels на плане, но не удаляет имя + из tooltip/диалогов и не является privacy-функцией. +2. Plan editor сохраняет текущую принудительную видимость независимо от + persisted `show_names`, потому что там имя является редактируемым объектом. +3. Hidden iso обязан соблюдать тот же user setting, несмотря на прежний + технический override `iso && !space.bg`. +4. Канонический styling hook видимой подписи — существующий HTML + `div.roomlabel`; отдельный статический режим и новый hook не добавляются. +5. Если удаление мёртвого `.rlabel` CSS увеличит визуальный diff только за счёт + отсутствующих nodes, это входит в задачу; прочая типографика не меняется. diff --git a/docs/specs/README.md b/docs/specs/README.md index 66c4b03d..d4e28aa1 100644 --- a/docs/specs/README.md +++ b/docs/specs/README.md @@ -101,6 +101,7 @@ GitHub Issues и GitHub Projects (v2) остаются единственным | [#178](https://github.com/Matysh/houseplan-card/issues/178) Выбор сущности для действия «Переключить состояние» | [178-toggle-entity.md](178-toggle-entity.md) | | [#197](https://github.com/Matysh/houseplan-card/issues/197) Один junction-патч не гасит кладку всего плана | [197-junction-patch-fail-dark.md](197-junction-patch-fail-dark.md) | | [#201](https://github.com/Matysh/houseplan-card/issues/201) Наследование толщины для атомарного участка стены | [201-atomic-thickness-lookup.md](201-atomic-thickness-lookup.md) | +| [#203](https://github.com/Matysh/houseplan-card/issues/203) Выключение названий скрывает все подписи комнат | [203-hide-room-names.md](203-hide-room-names.md) | | [#186](https://github.com/Matysh/houseplan-card/issues/186) Безопасный остаток стены у торцов партиционного проёма | [186-partition-opening-jamb-margin.md](186-partition-opening-jamb-margin.md) | ## P3