Files
felhom-controller/REPORT.md
T
admin 9d05fa5c35 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.
2026-07-12 12:26:30 +02:00

80 lines
5.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.
# 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 fixed**`Tier1LastRun`/`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 `buildAppBackupRows``TestBuildAppBackupRows_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
- **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.md` off-box refresh is a separate queued doc task.