kept data: the choice at reinstall, the list, the read-only view, the load (09 decision 36); R-690 fixed
gates / gates (push) Successful in 26s

An install over an app's kept drive folder (appdata/<app> non-empty) asks the household:
"use my kept data" (a load from the newest copy of THIS drive's install, own unit or
second-drive mirror, then the template's after_load) or "start fresh" (the folder is
renamed into <drive>/kept/<app>/<date>/ with the removed app's unit; nothing deleted).
The install API answers 409 kept_data_choice until one is chosen; DeployStack refuses
too. New page Megorzott adatok / Kept data (/kept-data): Load / Look / Delete (typed
confirmation, the only deletion of kept data). FileBrowser gets a read-only source.
The drive-full warning names the kept folders. <drive>/kept is protected and outside
every backup leg.

R-690: the removed-app restore (R-487) never found a unit on a DATA drive — it asked
GetStackComposePath (true for every catalog app) and restored nextcloud with no env.
Now isStackDeployed; pinned with a production-shaped provider.

Red-proofs: audits/night-2026-09-26/E/redproofs/.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-09-25 13:32:30 +02:00
parent 5a731b45b9
commit 43e99d160c
44 changed files with 3311 additions and 37 deletions
@@ -36,6 +36,23 @@ func i18nCasesC() []i18nCase {
{"storage_empty", "storage", func() map[string]interface{} {
return i18nLayoutData("storage", "Tárhely")
}},
// `09` §3 decision 36 — the kept-data list, one dated and one leftover row, and the empty page.
{"kept_data_full", "kept_data", func() map[string]interface{} {
d := i18nLayoutData("kept-data", "Megőrzött adatok")
d["KeptRows"] = []keptRow{
{DisplayName: "Nextcloud", App: "nextcloud", Path: "/mnt/felhom-drives/hdd_1/kept/nextcloud/2026-09-14_031200", Date: "2026-09-14 05:12", Size: "126.0 MB",
Backup: "unit 2026-09-14 04:44", CanLoad: true, LookURL: "https://files.example.hu/files/x/y",
DeleteText: "delete-text Nextcloud 126.0 MB", TypePrompt: "type-prompt Nextcloud"},
{DisplayName: "Paperless-ngx", App: "paperless-ngx", Path: "/mnt/felhom-drives/hdd_1/appdata/paperless", Date: "2026-09-13 10:00", Size: "71.0 MB",
Backup: "none", Installed: true, LookURL: "https://files.example.hu/files/x/z",
DeleteText: "x", TypePrompt: "y"},
}
d["KeptFlash"], d["KeptError"] = "flash-ok", "flash-error"
return d
}},
{"kept_data_empty", "kept_data", func() map[string]interface{} {
return i18nLayoutData("kept-data", "Megőrzött adatok")
}},
{"storage_network_full", "storage_network", func() map[string]interface{} {
d := i18nLayoutData("storage-network", "Hálózati tárhely")
base := func(name, health string, orphan bool) m {