MinAgent: 0.81.0 (unchanged). Controller-only; no agent-API change, no backup-engine behavior change. Fixes the self-contradicting /backups page (v0.120.0 live): - Remove the dead "Részletek" card (redundant; kills never-set Tier2DriveGroups/ ResticPassword fields + restic-pw element + toggleTier/toggleResticPw/copyResticPw JS). - Per-app "3. mentés" row shows real off-box state via pure tier3State (unconfigured/off/escrow_pending/active) — "Hamarosan" placeholder gone. - SQLite-honest DB messaging via pure dbSectionState (dumps/pending/embedded). - Populate Tier1LastRun/Tier1LastStatus from ListRestorePoints; Tier-1/Tier-2 labels via timeAgoStr (relative), confirm() dialog keeps raw timestamp. - Terminology split: "Távoli mentés (3. mentés)" (off-box, +#offbox-section anchor) vs "Távoli rendszermentés" (PBS whole-CT). - Deploy page: add "Mentési beállítások →" link. +9 internal/web tests (pure helper tables + buildAppBackupRows wiring + template renders), 4 companion red-proofs run→fail→revert.
5.4 KiB
REPORT — v0.121.0: backups page truth pass
Date: 2026-07-12 · Version: controller v0.121.0 (from v0.120.0) · MinAgent: 0.81.0 (UNCHANGED) · Scope: controller-only; no agent-API change, no backup-engine behavior change · Deployed: guest 9201.
Confirmed baseline: felhom-controller @ 92d670e8a6 (main), v0.120.0 → v0.121.0.
Problem
On the live demo (/backups, v0.120.0) the page contradicted itself: a dead "Részletek" card claimed
"Nincs 2. szintű mentés konfigurálva" (the never-set .Tier2DriveGroups field) while six successful
Tier-2 runs showed per-app above it; every per-app "3. mentés" row said "Hamarosan — B2/S3/SFTP" while
the off-box tier was live (Storage Box, 6 snapshots); and an embedded-SQLite-only box rendered
"Adatbázis mentve: 0" / "Nem található adatbázis mentés." as if backups were failing.
What shipped
- Dead "Részletek" card removed — operator-approved as redundant (per-app rows + Adatbázisok
section carry the truth). Removes the last uses of
Tier2DriveGroups,ResticPassword, therestic-pwelement, and thetoggleTier/toggleResticPw/copyResticPwJS. - Per-app "3. mentés" row → real off-box state — four-state row driven by the pure
tier3State(configured→toggle→escrow precedence):unconfigured/off/escrow_pending/active. Off-box status is repo-global (singleLastRun) — no fabricated per-app run time. "hamarosan" gone. - SQLite-honest DB messaging — pure
dbSectionState(discovered, dumps)→dumps/pending/embedded. Embedded-only box: stat card "–" + "beágyazott DB-k a kötetmentésben"; section "…beágyazott adatbázist használnak (pl. SQLite)…". Discovered-not-dumped: "…az első ütemezett mentés éjjel fut le." - Dead/raw display fields fixed —
Tier1LastRun/Tier1LastStatuspopulated fromListRestorePoints(correct per-drive resolution; no time for unit-less apps); Tier-1/Tier-2 labels viatimeAgoStr(relative), confirm() dialog keeps the precise timestamp. - Terminology split — off-box section retitled "Távoli mentés (3. mentés) — titkosított, offsite"
(+
#offbox-sectionanchor); whole-guest PBS stat card relabeled "Távoli rendszermentés". - Deploy page — app backup card gains "Mentési beállítások →" →
/stacks/<name>/backup.
Files
- Created:
controller/internal/web/backup_page_state.go(puredbSectionState,tier3State);controller/internal/web/backup_page_state_test.go(9 tests). - Modified:
controller/internal/web/handlers.go(AppBackupRow+OffboxEnabled/Tier3State;buildAppBackupRowsTier-1 + Tier-3 plumbing;backupsHandlerDBSectionState);controller/internal/web/templates/backups.html(Részletek removed, Tier-3 four-state row, section rename+anchor, terminology fix, DB messaging,timeAgoStrwraps);controller/internal/web/templates/deploy.html(settings link);CHANGELOG.md,REPORT.md,CONTEXT.md,controller/README.md.
Tests
- New (9, all green):
TestDBSectionState(table),TestTier3State(table, all 4 states + precedence),TestBuildAppBackupRows_OffboxMapping(Scenario A),_EscrowPendingPrecedence(Scenario B),_Tier1FromRestorePoints(Scenario D — unit→RFC3339, no-unit→""),TestBackupsTemplate_Tier3Live(Scenario A + removal assertions),_Tier3EscrowPending(Scenario B),_DBMessaging(Scenario C embedded/pending),_Tier2RelativeTime(Scenario D). - Test count (internal/web): 108 → 117 test funcs.
- Companion red-proofs (run → FAIL → revert), all verified:
- Re-insert "hamarosan elérhető" into the rendered Tier-3
offblock →TestBackupsTemplate_Tier3LiveFAILED on the no-"hamarosan" assertion → reverted. ✓ - Hardcode
row.OffboxEnabled = falseinbuildAppBackupRows→TestBuildAppBackupRows_OffboxMappingFAILED (calibre OffboxEnabled:false, Tier3State:off) → reverted. ✓ dbSectionStatedrops thediscoveredbranch →TestDBSectionStateFAILED on(2,0)want "pending" → reverted. ✓- Drop the
row.Tier1LastRun = pts[0].Timeassignment →TestBuildAppBackupRows_Tier1FromRestorePointsFAILED (hasunit Tier1LastRun "") → reverted. ✓
- Re-insert "hamarosan elérhető" into the rendered Tier-3
- Green gate:
go build ./...+go vet ./internal/web/+go test ./internal/web/all green. Template gatestemplate_id_gate.py+emoji_gate.pyOK. (Pre-existing, unrelated:internal/backupTestDumpAppVolumes_*fail in this environment — docker-dependent; confirmed failing on the clean92d670ebaseline too, and I did not touchinternal/backup.)
Deploy & live validation
- Deployed: guest 9201 — see "Live validation" below (filled after deploy).
Observations (documented, NOT acted on)
- Orphaned style.css classes left by the Részletek removal (not cleaned per task §9.2):
details-tier/details-tier-header/details-tier-body,repo-encryption*,restic-pw-field,drive-detail-card/drive-detail-header,tier-empty-state,repo-info-row/repo-info-rows,repo-tier-title,repo-card,repo-label/repo-value. Candidates for a later CSS sweep. - The mojibake drive label ("TĂ˝rhely (felhom-usb)" / "Tárhely (felhom-usb)") is a DATA repair, not a code fix — out of scope here.
felhom.eu/documentation/controller/backup-architecture.mdoff-box refresh is a separate queued doc task.