mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-04 13:48:57 +00:00
Validate / hacs (push) Failing after 12s
Validate / hassfest (push) Failing after 13s
Validate / frontend (push) Successful in 3m2s
Validate / golden (push) Failing after 51s
Validate / backend (push) Failing after 6m50s
Validate / smoke (push) Failing after 13m44s
Validate / performance (push) Failing after 24m13s
81 lines
4.4 KiB
Markdown
81 lines
4.4 KiB
Markdown
# ТЗ #50 — Экспорт/импорт конфигурации и пространства
|
||
|
||
- Issue: https://github.com/Matysh/houseplan-card/issues/50
|
||
- Приоритет: P1
|
||
- Статус ТЗ: ready for review
|
||
- Security scope: только владелец/admin согласно существующей write policy
|
||
|
||
## Цель
|
||
|
||
Дать переносимую резервную копию модели House Plan и безопасный перенос одного
|
||
пространства между собственными HA instances без silent overwrite.
|
||
|
||
## Формат v1
|
||
|
||
Один UTF-8 JSON с envelope:
|
||
|
||
```json
|
||
{
|
||
"format": "houseplan-export",
|
||
"export_version": 1,
|
||
"kind": "full|space",
|
||
"created_at": "ISO-8601",
|
||
"card_version": "…",
|
||
"integration_version": "…",
|
||
"model_version": 0,
|
||
"payload": { "config": {}, "layout": {} },
|
||
"content_manifest": []
|
||
}
|
||
```
|
||
|
||
Trails, optimizer undo/pending snapshots, revisions, signed URL tokens и
|
||
runtime caches не экспортируются. Config и layout экспортируются вместе:
|
||
backup без positions неполон.
|
||
|
||
`content_manifest` описывает ссылки, но v1 JSON не содержит бинарные файлы.
|
||
На той же instance существующие content refs продолжают работать. При
|
||
cross-instance import локальная `/api/houseplan/content/...` ссылка помечается
|
||
missing и пропускается/очищается только после явного подтверждения preview;
|
||
external safe URLs сохраняются. Portable ZIP с assets — отдельный будущий этап.
|
||
|
||
## Full export/import
|
||
|
||
- Export содержит полные `spaces`, `markers`, `settings` и live layout records.
|
||
- Import проходит envelope limits, JSON parse, migration/read compatibility,
|
||
`CONFIG_SCHEMA` и `LAYOUT_SCHEMA`, затем dry-run preview.
|
||
- Preview: counts current→incoming, spaces replaced, markers/layout, orphaned
|
||
bindings, missing content, unknown future fields, incompatible version.
|
||
- Apply — один admin-only backend command под `write_lock`: recheck expected
|
||
config/layout revisions, atomic two-store transaction/rollback, затем events.
|
||
- Full import заменяет модель полностью; Cancel не пишет ничего.
|
||
|
||
## Space export/import
|
||
|
||
- Payload содержит один space целиком и только относящиеся к нему markers и
|
||
layout ids: marker ids, `rl_<roomId>` и другие документированные owners.
|
||
- Import всегда добавляет новое пространство. Новый safe id генерируется;
|
||
title conflict получает ` (2)`, ` (3)`.
|
||
- Все внутренние room/opening/decor/draft ids remap при collision; references
|
||
(`open_to`, room_id, layout keys) переписываются по одной map.
|
||
- HA binding/entity ids сохраняются. Не существующие на target становятся
|
||
orphaned через текущий lifecycle, import не угадывает замену.
|
||
- Binding, уже занятая live marker target config, не дублируется молча: preview
|
||
предлагает импортировать marker как unbound virtual copy либо пропустить;
|
||
default — пропустить marker, geometry пространства сохранить.
|
||
|
||
## Ограничения и безопасность
|
||
|
||
Размер файла и collection caps не выше backend schema; prototype pollution
|
||
keys и non-finite JSON невозможны. Export скачивается локально, без внешней
|
||
телеметрии. Никакие HA services не вызываются при preview.
|
||
|
||
## Проверки и приёмка
|
||
|
||
- full roundtrip сохраняет normalized config+layout и unknown future fields;
|
||
- atomic rollback при второй store failure и revision race;
|
||
- remap всех space-owned ids/references, name/id collisions;
|
||
- orphan/disabled/removed/virtual/vacuum calibration cases;
|
||
- invalid/oversize/newer export не меняет stores и даёт stable error code;
|
||
- mobile/desktop preview, explicit confirmation и локализованные итоги;
|
||
- документация прямо говорит, что v1 JSON не переносит бинарные assets/trails.
|