mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
docs: specify space creation display defaults
Issue: #204 User-Visible: no
This commit is contained in:
committed by
claude[bot]
parent
ad8e7a50cc
commit
15dc8adc4f
@@ -0,0 +1,182 @@
|
||||
# Issue #204 — честные defaults границ и имён при создании пространства
|
||||
|
||||
- Дата: 2026-08-19
|
||||
- Тип: bug · приоритет P2
|
||||
- Оценка: пользовательская ценность 7/10 · ценность для разработки 6/10 · сложность 4/10 · риск 5/10
|
||||
- Issue: [#204](https://github.com/Matysh/houseplan-card/issues/204)
|
||||
- Ветка: `issue/204-space-create-display-defaults`
|
||||
|
||||
Канонические документы: `docs/SCOPE.md`, `docs/UX-MODES.md`,
|
||||
`docs/USER-GUIDE.ru.md`, `docs/TESTING.md`, `docs/specs/040-floor-area-onboarding.md`.
|
||||
|
||||
## 1. Сценарий и персона
|
||||
|
||||
Администратор создаёт пространство вручную либо последовательно заводит этажи
|
||||
через Floors/Areas onboarding. В диалоге он выбирает источник «Рисовать комнаты
|
||||
вручную», проверяет настройки отображения и сохраняет. Значения на экране должны
|
||||
быть теми значениями, которые попадут в config и будут показаны при повторном
|
||||
открытии.
|
||||
|
||||
## 2. До и после
|
||||
|
||||
**До:** оба переключателя — «Всегда отображать границы комнат» и «Отображать
|
||||
названия комнат» — видимо выключены. Для `create + draw` Save игнорирует их и
|
||||
принудительно записывает `true/true`. Повторное открытие показывает включённое
|
||||
состояние, которого пользователь не выбирал.
|
||||
|
||||
**После:** при выборе ручного пространства оба действующих product defaults
|
||||
сразу видимо включены и именно они сохраняются. Для пространства с файлом
|
||||
исходный default остаётся `false/false`. Если пользователь изменил хотя бы один
|
||||
из двух переключателей, дальнейшие File ↔ Draw в том же открытом диалоге не
|
||||
перезаписывают ни один из его выборов.
|
||||
|
||||
## 3. Подтверждённая причина
|
||||
|
||||
`_openSpaceDialog('create')` и `_openNextImport()` создают dialog state с
|
||||
`source:'file'`, `showBorders:false`, `showNames:false`. Радиокнопки источника
|
||||
меняют только `source`. `_saveSpaceDialog()` отдельно содержит скрытую ветку:
|
||||
|
||||
```ts
|
||||
show_borders: draw && d.mode === 'create' ? true : d.showBorders
|
||||
show_names: draw && d.mode === 'create' ? true : d.showNames
|
||||
```
|
||||
|
||||
Поэтому только `create + draw` нарушает round-trip. Create с файлом и Edit уже
|
||||
сохраняют показанные значения; backend принимает явные boolean без подмены.
|
||||
#203 исправляет runtime-смысл `show_names`, но не dialog defaults и не Save.
|
||||
|
||||
## 4. Scope
|
||||
|
||||
- сделать default-пару источника частью create-dialog state: File `false/false`,
|
||||
Draw `true/true`;
|
||||
- применять пару при переключении источника, пока пользователь не тронул ни
|
||||
один из этих двух controls;
|
||||
- после первого пользовательского изменения сохранять оба текущих значения при
|
||||
любых следующих File ↔ Draw;
|
||||
- сохранять в config ровно `d.showBorders` и `d.showNames` без скрытой ветки;
|
||||
- одинаково применить контракт в обычном Create и Floors/Areas onboarding;
|
||||
- проверить Save/reopen, Cancel и source-switch round-trip.
|
||||
|
||||
## 5. Non-scope
|
||||
|
||||
- изменение runtime resolver `spaceDisplayOf()` или render поведения #203;
|
||||
- миграция уже созданных spaces и переписывание explicit/implicit settings;
|
||||
- изменение defaults Edit, legacy spaces либо space с уже сохранёнными values;
|
||||
- изменение `hide_decor`, `hide_openings`, fill/Glow, background, масштаба или
|
||||
других полей диалога при source switch;
|
||||
- добавление предупреждения, текста, reset-кнопки или отдельных preferences на
|
||||
каждый source;
|
||||
- изменение HA Floors/Areas registry или backend schema/API.
|
||||
|
||||
## 6. Контракт dialog state
|
||||
|
||||
Create state получает внутренний ephemeral признак `displayTouched` (имя может
|
||||
быть другим). Он не сохраняется в config.
|
||||
|
||||
1. Новый обычный Create и каждый новый шаг onboarding открываются как File с
|
||||
видимой парой `false/false`, `displayTouched:false`.
|
||||
2. Пока `displayTouched:false`, переход на Draw атомарно ставит `true/true`, а
|
||||
переход на File — `false/false`. Повторные переходы воспроизводят default
|
||||
выбранного source и не влияют на прочие поля.
|
||||
3. Изменение любого из двух переключателей ставит `displayTouched:true`. Второй
|
||||
control не меняется автоматически.
|
||||
4. При `displayTouched:true` смена source меняет только `source`; текущая пара
|
||||
сохраняется целиком. Это даёт в том числе намеренные `true/false` и
|
||||
`false/true`.
|
||||
5. Save для Create и Edit всегда записывает текущие dialog booleans. Значение
|
||||
не выводится заново из наличия background.
|
||||
6. Cancel/close уничтожает ephemeral state. Следующий Create снова начинает с
|
||||
File `false/false`; следующий этаж onboarding получает собственный чистый
|
||||
state и не наследует touch предыдущего.
|
||||
|
||||
Выбор source и изменение control происходят синхронно в одном новом object
|
||||
state, поэтому Lit не может отрисовать промежуточную ложную пару.
|
||||
|
||||
## 7. Данные и совместимость
|
||||
|
||||
Persisted schema не меняется: `settings.show_borders` и `settings.show_names`
|
||||
уже boolean. Новые hand-drawn spaces по default по-прежнему получают
|
||||
`true/true`; меняется только честность UI и возможность до Save выбрать другое.
|
||||
Новые file spaces по default по-прежнему получают `false/false`.
|
||||
|
||||
Existing spaces и imports/backups не мигрируются. Edit читает effective values
|
||||
и сохраняет их как раньше; ephemeral touch нужен только create-mode. Downgrade
|
||||
читает те же booleans. Нет нового model/version marker.
|
||||
|
||||
## 8. UX, accessibility, touch и i18n
|
||||
|
||||
Состав, порядок и тексты controls не меняются. Обновляются checked states двух
|
||||
существующих HA switches. Keyboard, pointer и touch проходят один и тот же
|
||||
`change` handler; focus не переносится, live announcement не требуется. Цвет не
|
||||
является единственным сигналом — состояние остаётся нативно доступным через
|
||||
checked/ARIA контракт control. Новых locale keys нет.
|
||||
|
||||
## 9. Acceptance criteria
|
||||
|
||||
| AC | Критерий | Доказательство |
|
||||
|---|---|---|
|
||||
| AC1 | Новый Create открывается как File с `false/false`; первый переход Draw показывает `true/true`. | Targeted dialog smoke + state assertions. |
|
||||
| AC2 | Save сразу после выбора Draw сохраняет показанные `true/true`; reopen читает `true/true`. | Production-bundle smoke. |
|
||||
| AC3 | Пользовательские `false/false`, `true/false` и `false/true` для Draw сохраняются без подмены и совпадают после reopen. | Table-driven smoke/unit seam. |
|
||||
| AC4 | До touch File ↔ Draw переключает `false/false` ↔ `true/true`; после touch source меняется, а оба booleans остаются. | Source-switch matrix. |
|
||||
| AC5 | Новый этап Floors/Areas onboarding следует той же матрице и не наследует touch/values предыдущего этажа. | Extended onboarding smoke. |
|
||||
| AC6 | Create с файлом по default сохраняет `false/false`; Edit существующего пространства не меняет values при open/save. | Regression smoke. |
|
||||
| AC7 | Cancel не пишет config; новый Create возвращает чистый default. | Save-call/config snapshot assertions. |
|
||||
| AC8 | Остальные dialog fields побайтно сохраняются при source transitions; runtime #203 остаётся зелёным. | Focused state regression + existing smoke. |
|
||||
| AC9 | Старый hidden Save override ловится мутантом. | Mutation gate. |
|
||||
| AC10 | Рабочие gates зелёные. | typecheck, unit, build, targeted smokes; bundle copies identical. |
|
||||
|
||||
## 10. План реализации и тестов
|
||||
|
||||
Создание начального state и source transition следует вынести в маленький pure
|
||||
helper либо эквивалентную общую функцию, чтобы обычный Create и `_openNextImport`
|
||||
не расходились. Handlers двух переключателей помечают pair touched. Save удаляет
|
||||
ветку `draw && create ? true : ...`.
|
||||
|
||||
Основной targeted browser сценарий может расширить `demo/smoke_space_settings.mjs`
|
||||
или быть выделен как `smoke_space_create_display_defaults.mjs`. Он проходит
|
||||
default, source matrix, mixed values, Save/reopen, Cancel и onboarding. Unit
|
||||
допустим для pure state helper; DOM/Save round-trip остаётся обязательным.
|
||||
|
||||
Mutation entry восстанавливает принудительные `true` в Save либо отключает
|
||||
touched guard и обязан падать на mixed-value/source-switch проверке. Golden не
|
||||
нужен: checked и persisted booleans являются точным доказательством. Полный
|
||||
smoke/golden/performance остаётся предрелизным gate.
|
||||
|
||||
## 11. Риски и меры
|
||||
|
||||
| Риск | Мера |
|
||||
|---|---|
|
||||
| Source switch затирает осознанный mixed choice | Один touched guard на пару, AC3/AC4. |
|
||||
| Onboarding расходится с обычным Create | Общий initializer/transition и AC5. |
|
||||
| Touch предыдущего этажа протекает дальше | Новый state на каждый `_openNextImport()`. |
|
||||
| Исправление меняет существующий product default | Persisted default pairs остаются прежними. |
|
||||
| Edit получает create-only reset | Mode matrix и AC6. |
|
||||
|
||||
Производительность и security/privacy boundary не меняются: локальные boolean
|
||||
transitions не добавляют I/O, registry access или HA service calls.
|
||||
|
||||
## 12. Release-артефакты и rollback
|
||||
|
||||
Изменение пользовательское. Implementation-коммит имеет `User-Visible: yes` и
|
||||
включает:
|
||||
|
||||
- `docs/CHANGELOG.md` и `docs/CHANGELOG.ru.md` со ссылкой на #204;
|
||||
- `docs/USER-GUIDE.ru.md` — defaults File/Draw и сохранение выбора;
|
||||
- `docs/TESTING.md` — source/touch/onboarding matrix;
|
||||
- `docs/STATUS.md` — фактическую release-линию;
|
||||
- targeted smoke, mutation entry и три синхронные bundle copies.
|
||||
|
||||
Отдельные backend, schema/migration, i18n, screenshot/golden, security и
|
||||
performance artifacts не нужны. Rollback — revert implementation-коммита;
|
||||
данные остаются валидными, но вернётся скрытая Save-подмена для create+draw.
|
||||
|
||||
## 13. Принятые предположения
|
||||
|
||||
1. Один touched flag намеренно защищает пару: изменение одного control означает,
|
||||
что dialog больше не вправе автоматически сбрасывать и второй.
|
||||
2. Пока пользователь не менял controls, каждый source switch показывает default
|
||||
текущего source; отдельная память values по источникам не требуется.
|
||||
3. Internal helper/field names и выбор smoke-файла являются техническими
|
||||
решениями при сохранении §6.
|
||||
4. Продуктовых вопросов больше нет: Q1–Q2 приняты владельцем по defaults.
|
||||
@@ -100,6 +100,7 @@ GitHub Issues и GitHub Projects (v2) остаются единственным
|
||||
| [#174](https://github.com/Matysh/houseplan-card/issues/174) Связанный виртуальный источник следует реальному контроллеру | [174-linked-virtual-light-controller.md](174-linked-virtual-light-controller.md) |
|
||||
| [#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) |
|
||||
| [#204](https://github.com/Matysh/houseplan-card/issues/204) Честные defaults границ и имён при создании пространства | [204-space-create-display-defaults.md](204-space-create-display-defaults.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) |
|
||||
|
||||
Reference in New Issue
Block a user