Files
felhom-controller/REPORT.md
T

7.0 KiB
Raw Blame History

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

  1. 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, the restic-pw element, and the toggleTier/toggleResticPw/copyResticPw JS.
  2. 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 (single LastRun) — no fabricated per-app run time. "hamarosan" gone.
  3. 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."
  4. Dead/raw display fields fixedTier1LastRun/Tier1LastStatus populated from ListRestorePoints (correct per-drive resolution; no time for unit-less apps); Tier-1/Tier-2 labels via timeAgoStr (relative), confirm() dialog keeps the precise timestamp.
  5. Terminology split — off-box section retitled "Távoli mentés (3. mentés) — titkosított, offsite" (+ #offbox-section anchor); whole-guest PBS stat card relabeled "Távoli rendszermentés".
  6. Deploy page — app backup card gains "Mentési beállítások →" → /stacks/<name>/backup.

Files

  • Created: controller/internal/web/backup_page_state.go (pure dbSectionState, tier3State); controller/internal/web/backup_page_state_test.go (9 tests).
  • Modified: controller/internal/web/handlers.go (AppBackupRow +OffboxEnabled/Tier3State; buildAppBackupRows Tier-1 + Tier-3 plumbing; backupsHandler DBSectionState); controller/internal/web/templates/backups.html (Részletek removed, Tier-3 four-state row, section rename+anchor, terminology fix, DB messaging, timeAgoStr wraps); 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:
    1. Re-insert "hamarosan elérhető" into the rendered Tier-3 off block → TestBackupsTemplate_Tier3Live FAILED on the no-"hamarosan" assertion → reverted. ✓
    2. Hardcode row.OffboxEnabled = false in buildAppBackupRowsTestBuildAppBackupRows_OffboxMapping FAILED (calibre OffboxEnabled:false, Tier3State:off) → reverted. ✓
    3. dbSectionState drops the discovered branch → TestDBSectionState FAILED on (2,0) want "pending" → reverted. ✓
    4. Drop the row.Tier1LastRun = pts[0].Time assignment → TestBuildAppBackupRows_Tier1FromRestorePoints FAILED (hasunit Tier1LastRun "") → reverted. ✓
  • Green gate: go build ./... + go vet ./internal/web/ + go test ./internal/web/ all green. Template gates template_id_gate.py + emoji_gate.py OK. (Pre-existing, unrelated: internal/backup TestDumpAppVolumes_* fail in this environment — docker-dependent; confirmed failing on the clean 92d670e baseline too, and I did not touch internal/backup.)

Deploy & live validation

  • Built + pushed on 180: gitea.dooplex.hu/admin/felhom-controller:0.121.0 (digest sha256:0478d42a…, 145M). Deployed to guest 9201 via the bootstrap flow.
  • docker ps: gitea.dooplex.hu/admin/felhom-controller:0.121.0 Up (healthy); log: Event pushed: controller_started (info) — Controller elindult (0.121.0). Version badge on the page footer reads 0.121.0.
  • Live UI validation (claude-in-chrome, https://felhom.demo-felhom.eu):
    • (a) no "hamarosan" anywhere on /backups — confirmed (page text + expanded rows). ✓
    • (b) Calibre-Web Tier-3 row = "Sikeres" + "restic → u629488-sub1.your-storagebox.de" + "Utolsó: 13 órája" + "Helyreállítási egység, titkosítva". ✓
    • (c) Radarr (untoggled) Tier-3 = "Kikapcsolva" + "Ez az alkalmazás nincs kijelölve távoli mentésre" + "Bekapcsolás"; clicking it jumped the URL to …/backups#offbox-section. ✓
    • (d) "Részletek" card gone.
    • (e) DB messaging — stat card "Adatbázis mentve / beágyazott DB-k a kötetmentésben"; Adatbázisok section "…beágyazott adatbázist használnak (pl. SQLite)…". ✓
    • (f) Relative times — Tier-1 "Utolsó: most ✓", Tier-2 "Utolsó: 33 perce Sikeres" (Calibre) / "3 órája" (Radarr) — no raw RFC3339 in the visible labels. ✓
    • (g) Deploy page (/stacks/calibre-web/deploy) shows "Mentési állapot → · Mentési beállítások →"; the new link opens /stacks/calibre-web/backup = "2. mentés beállítása" tier-2 config page. ✓
    • Method: claude-in-chrome (server-side render exercised end-to-end; no pipeline bypass). Per §13, no restore/format/offbox toggle button was pressed on the live demo.

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.md off-box refresh is a separate queued doc task.