Files
houseplan-card/docs/specs/050-config-export-import.md
T
Matysh 112c260314
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
Release v1.61.0-beta.1
2026-08-09 21:51:33 +03:00

81 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ТЗ #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.