controller v0.121.0: backups page truth pass — remove dead Részletek card, real Tier-3 off-box state, SQLite-honest DB messaging

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.
This commit is contained in:
2026-07-12 12:26:30 +02:00
parent 92d670e8a6
commit 9d05fa5c35
9 changed files with 604 additions and 174 deletions
@@ -0,0 +1,49 @@
package web
// backup_page_state holds the small pure state-pick helpers that drive the honest
// per-app / whole-page messaging on the /backups page. They are pure (no *Server,
// no I/O) so the truth-table can be unit-tested directly without a fixture Server.
// dbSectionState decides how the "Adatbázisok" section (and the "Adatbázis mentve"
// stat card) should read, given how many databases were discovered live at render
// time and how many dump files exist on disk:
// - "dumps" — dump files exist → show the real dump table / count.
// - "pending" — a database was discovered but no dump written yet → "first run tonight".
// - "embedded" — neither: the deployed apps carry embedded DBs (e.g. SQLite) that ride
// the file/volume backup; no separate dump is expected, so a bare "0" would lie.
//
// dumps wins over discovered: stale dumps from a since-removed DB app are still a real,
// restorable artifact and must be shown normally (see the §8 edge-case table).
func dbSectionState(discovered, dumps int) string {
switch {
case dumps > 0:
return "dumps"
case discovered > 0:
return "pending"
default:
return "embedded"
}
}
// tier3State decides the per-app "3. mentés" (off-box / off-site) row state:
// - "unconfigured" — no off-box target set (configured wins over a stale per-app toggle).
// - "off" — target set but this app is not toggled for off-box backup.
// - "escrow_pending" — toggled, but the repo password is not yet escrowed (fork-4 gate):
// runs are paused, so we must NOT imply a successful run.
// - "active" — toggled and escrowed: the app is included in the off-box runs.
//
// Precedence is strict: configured → toggle → escrow. Anything other than "escrowed"
// while toggled is treated as escrow-pending (never "active"), so a pre-pending LastStatus
// of "ok" can never surface a false "Sikeres".
func tier3State(configured, toggled bool, escrowState string) string {
switch {
case !configured:
return "unconfigured"
case !toggled:
return "off"
case escrowState != "escrowed":
return "escrow_pending"
default:
return "active"
}
}