From 0985339e6c8c7bc57dc8026c05df367d2251e2ab Mon Sep 17 00:00:00 2001 From: kisfenyo Date: Mon, 16 Feb 2026 07:35:23 +0100 Subject: [PATCH] =?UTF-8?q?TASK.md=20=E2=80=94=20v0.4.5:=20Dedicated=20Bac?= =?UTF-8?q?kup=20Page=20("Biztons=C3=A1gi=20ment=C3=A9s")?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TASK.md | 834 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 534 insertions(+), 300 deletions(-) diff --git a/TASK.md b/TASK.md index 70dd85d..62113af 100644 --- a/TASK.md +++ b/TASK.md @@ -1,382 +1,616 @@ -# TASK.md — v0.4.1: App Filtering + Bugfixes +# TASK.md — v0.4.5: Dedicated Backup Page ("Biztonsági mentés") -> Version bump: **v0.4.1** -> Scope: UI feature + configuration fixes +> Version bump: **v0.4.5** +> Scope: New page + backend extensions for detailed backup visibility --- ## Overview -Three items: +Add a third page to the controller dashboard: **Biztonsági mentés** (Backup), accessible from the sidebar navigation alongside Vezérlőpult and Alkalmazások. -1. **Feature**: App filtering on the Alkalmazások (Stacks) page with clickable stat cards on the Vezérlőpult (Dashboard) page -2. **Bugfix**: felhom.demo-felhom.eu returns 404 — docker-compose.yml on demo node needs syncing -3. **Config**: Enable backup on demo node so the backup UI section appears +The page gives full visibility into the backup system — what's being backed up, when, where, and whether it's healthy. Designed so a non-technical customer can see "everything is green" at a glance, while Viktor (or a future admin panel) gets the details needed for troubleshooting. --- -## Task 1: App Filtering +## Page Layout -### Concept +### Section 1: Status Overview (top of page) -**Alkalmazások page** gets filter tabs at the top: +A row of stat cards (same style as dashboard), showing at-a-glance backup health: ``` -[ Mind (51) ] [ Futó (4) ] [ Leállítva (0) ] [ Telepíthető (47) ] +┌────────────────┐ ┌────────────────┐ ┌─────────────────┐ ┌───────────────┐ +│ ✅ Helyi │ │ ⬜ Távoli │ │ 3 │ │ 87.5 MB │ +│ mentés aktív │ │ nincs beállítva │ │ adatbázis mentve│ │ tároló méret │ +└────────────────┘ └────────────────┘ └─────────────────┘ └───────────────┘ ``` -**Vezérlőpult page** stat cards become clickable — clicking navigates to the Alkalmazások page with the corresponding filter pre-selected: +- **Helyi mentés** (Local backup): green if last backup < 36h old and successful, yellow if > 36h, red if failed, gray if disabled +- **Távoli mentés** (Remote backup): gray "nincs beállítva" for now (Phase 3 v1 is local-only). Placeholder for future B2/S3/SFTP offsite. When implemented: green/red status like local. +- **Adatbázis mentve** (Databases backed up): count of successfully dumped DBs from last run +- **Tároló méret** (Repository size): total restic repo size with snapshot count -- Click "4 Futó alkalmazás" → `/stacks?filter=running` -- Click "0 Leállítva" → `/stacks?filter=stopped` -- Click "51 Összes alkalmazás" → `/stacks` (no filter = show all) +### Section 2: Ütemezés (Schedule) -### Implementation: 100% client-side +A compact info card showing backup timing: -No server/handler changes needed. All filtering is done via JavaScript show/hide on existing DOM elements. - -### Changes to `stacks.html` - -Add filter bar between the page header and the stack grid: - -```html -
- - - - -
+``` +╔══════════════════════════════════════════════════════╗ +║ Ütemezés ║ +╠══════════════════════════════════════════════════════╣ +║ ║ +║ Adatbázis mentés 02:30 Következő: ma 02:30 ║ +║ Restic pillanatkép 03:00 Következő: ma 03:00 ║ +║ Karbantartás vasárnap Következő: 2026-02-22 ║ +║ ║ +║ Utolsó sikeres mentés: 2026-02-16 03:01 (15 órája) ║ +║ Mentés időtartam: 12s ║ +║ ║ +║ Megőrzés: 7 napi · 4 heti · 6 havi ║ +║ ║ +║ [Mentés most] ║ +╚══════════════════════════════════════════════════════╝ ``` -Add `data-filter-state` attribute to each stack card in the `{{range .Stacks}}` loop: +Hungarian labels: +- "Ütemezés" = Schedule +- "Adatbázis mentés" = Database backup +- "Restic pillanatkép" = Restic snapshot +- "Karbantartás" = Maintenance (prune) +- "Következő" = Next +- "ma" = today, "holnap" = tomorrow +- "Utolsó sikeres mentés" = Last successful backup +- "órája" = hours ago +- "Mentés időtartam" = Backup duration +- "Megőrzés" = Retention +- "napi" = daily, "heti" = weekly, "havi" = monthly +- "Mentés most" = Backup now -```html -
+The "Mentés most" button triggers `POST /api/backup/run` (same as dashboard card). Show spinner/loading state while running. The button should be disabled if a backup is already in progress. + +### Section 3: Adatbázisok (Databases) + +A table listing every discovered database container and its dump status: + +``` +╔══════════════════════════════════════════════════════════════════════╗ +║ Adatbázisok ║ +╠══════════════════════════════════════════════════════════════════════╣ +║ ║ +║ Alkalmazás Típus Méret Utolsó Állapot ║ +║ ─────────────────────────────────────────────────────────────────── ║ +║ paperless-ngx PostgreSQL 4.2 MB 03:01 ✅ OK ║ +║ immich PostgreSQL 82.1 MB 03:01 ✅ OK ║ +║ romm MariaDB 1.2 MB 03:01 ✅ OK ║ +║ ║ +╚══════════════════════════════════════════════════════════════════════╝ ``` -Where `filterCategory` is a new template function that maps states to filter categories: -- `running` → states: running, starting, unhealthy, restarting (has containers, is "up") -- `stopped` → states: stopped, exited (deployed but not running) -- `available` → state: not_deployed (never deployed) +Table columns: +- **Alkalmazás** (Application): stack name (derived from container name) +- **Típus** (Type): PostgreSQL or MariaDB, with a small icon/badge +- **Méret** (Size): dump file size from last run +- **Utolsó** (Last): time of last dump (HH:MM format if today, date if older) +- **Állapot** (Status): ✅ OK / ❌ Hiba (error) / ⏳ Folyamatban (in progress) / ➖ Nem futott (never run) -### New template function: `filterCategory` +If a dump failed, show the error message in a tooltip or expandable row detail. -Add to `funcmap.go`: +**Érvényesítés (Validation) column** — NEW FEATURE (see Section 6 below for backend details): + +Add a column showing whether the dump file passed basic structural validation: + +``` +║ Érvényesítés ║ +║ ✅ 47 tábla ║ ← "47 tables" found in the dump +║ ✅ 123 tábla ║ +║ ✅ 12 tábla ║ +``` + +### Section 4: Pillanatképek (Snapshots) + +A table showing restic snapshot history (last 10-20 snapshots): + +``` +╔══════════════════════════════════════════════════════════════════════╗ +║ Pillanatképek ║ +╠══════════════════════════════════════════════════════════════════════╣ +║ ║ +║ Azonosító Időpont Méret Új fájl Változott ║ +║ ─────────────────────────────────────────────────────────────────── ║ +║ a3f2c91e 2026-02-16 03:01 +1.2 MB 3 2 ║ +║ 8bc4d312 2026-02-15 03:01 +82.5 MB 156 0 ║ ← first snapshot +║ ║ +║ Összesen: 2 pillanatkép · 87.5 MB ║ +╚══════════════════════════════════════════════════════════════════════╝ +``` + +Table columns: +- **Azonosító** (ID): short snapshot ID (8 chars) +- **Időpont** (Time): snapshot timestamp +- **Méret** (Size): data added in this snapshot ("+1.2 MB") +- **Új fájl** (New files): files_new count +- **Változott** (Changed): files_changed count + +Footer: total snapshot count and total repo size. + +### Section 5: Tároló (Repository) + +A compact info card about the restic repository: + +``` +╔══════════════════════════════════════════════════════╗ +║ Tároló ║ +╠══════════════════════════════════════════════════════╣ +║ ║ +║ Helyszín: /srv/backups/restic-repo (helyi) ║ +║ Méret: 87.5 MB ║ +║ Pillanatképek: 2 ║ +║ Integritás: ✅ Rendben (utolsó: 2026-02-16) ║ +║ ║ +║ Mentett útvonalak: ║ +║ • /opt/docker/stacks/ ║ +║ • /srv/backups/db-dumps/ ║ +║ • /opt/docker/felhom-controller/controller.yaml ║ +║ ║ +║ Távoli másolat: ║ +║ ⬜ Nincs beállítva ║ +║ (B2/S3/SFTP támogatás hamarosan) ║ +║ ║ +╚══════════════════════════════════════════════════════╝ +``` + +Hungarian labels: +- "Tároló" = Repository/Storage +- "Helyszín" = Location +- "helyi" = local +- "Integritás" = Integrity +- "Rendben" = OK +- "Mentett útvonalak" = Backed up paths +- "Távoli másolat" = Remote copy +- "Nincs beállítva" = Not configured +- "hamarosan" = coming soon + +### Section 6: Backup Not Configured State + +If `backup.enabled` is `false`, the entire page shows a friendly empty state: + +``` +╔══════════════════════════════════════════════════════╗ +║ ║ +║ 🛡️ Biztonsági mentés nincs beállítva ║ +║ ║ +║ A biztonsági mentés funkció nem aktív. ║ +║ Kérjük, vegye fel a kapcsolatot a Felhom ║ +║ csapattal a beállításhoz. ║ +║ ║ +╚══════════════════════════════════════════════════════╝ +``` + +--- + +## Backend Changes + +### New: Snapshot History (`ResticManager`) + +Add method to list all snapshots (not just latest): ```go -"filterCategory": func(state stacks.ContainerState, deployed bool) string { - switch state { - case stacks.StateRunning, stacks.StateStarting, stacks.StateUnhealthy, stacks.StateRestarting: - return "running" - case stacks.StateStopped, stacks.StateExited, stacks.StatePaused: - return "stopped" - default: - if deployed { - return "stopped" // deployed but unknown state → treat as stopped - } - return "available" - } -}, +// ListSnapshots returns all snapshots, newest first. +func (r *ResticManager) ListSnapshots(limit int) ([]SnapshotInfo, error) { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + defer cancel() + + cmd := r.command(ctx, "snapshots", "--json") + out, err := cmd.Output() + // ... parse JSON array, reverse for newest-first, limit to N +} ``` -### JavaScript for stacks.html +Extend `SnapshotInfo` with data-added fields if possible (restic's `snapshots --json` includes some stats). -Add a `