v0.12.0 — Backup page overhaul: unified app rows, bug fixes, sequential chaining

Bug fixes:
- GetFullStatus() returns deep copy; CrossDriveSummary/UnconfiguredApps/CrossDriveWarnings
  are always nil in the copy so the handler builds them fresh (fixes duplicate-apps bug)
- Replace binary IsMountPoint check with tiered CheckBackupDestination() — path-not-exist,
  not-writable, system-drive (warning), disk >90-95% full; shown as warning vs critical
- Remove dead settingsAppBackupHandler / POST /settings/app-backup route (toggle wrote
  to settings.json but nothing consumed the flag)

Architecture:
- Unified per-app backup rows: new AppBackupRow struct + buildAppBackupRows() replaces
  the two old sections with expandable rows showing all 3 layers per app
- Sequential backup chaining: cross-drive runs immediately after restic (removed
  independent cross-drive-daily/cross-drive-weekly scheduler jobs)
- Deploy page: remove "Csak kézi indítás" schedule option; add weekly consistency note

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-17 17:56:28 +01:00
parent e002d712cf
commit 1de244646b
10 changed files with 637 additions and 154 deletions
+12 -12
View File
@@ -192,6 +192,18 @@ func main() {
if err != nil {
notifier.NotifyBackupFailed("Biztonsági mentés sikertelen", err.Error())
}
// Phase 3: Chain cross-drive backups immediately after restic (regardless of restic success)
// Daily jobs run every night; weekly jobs only on Sunday
if crossDriveRunner != nil {
if cdErr := crossDriveRunner.RunAllScheduled(ctx, "daily"); cdErr != nil {
logger.Printf("[WARN] Cross-drive daily backup had errors: %v", cdErr)
}
if time.Now().Weekday() == time.Sunday {
if cdErr := crossDriveRunner.RunAllScheduled(ctx, "weekly"); cdErr != nil {
logger.Printf("[WARN] Cross-drive weekly backup had errors: %v", cdErr)
}
}
}
return err
})
@@ -216,18 +228,6 @@ func main() {
})
}
// Cross-drive backup — daily at 03:30 (after main backup at 03:00)
sched.Daily("cross-drive-daily", "03:30", func(ctx context.Context) error {
return crossDriveRunner.RunAllScheduled(ctx, "daily")
})
// Cross-drive weekly — Sunday 04:30 (after integrity check at 04:00)
sched.Daily("cross-drive-weekly", "04:30", func(ctx context.Context) error {
if time.Now().Weekday() != time.Sunday {
return nil
}
return crossDriveRunner.RunAllScheduled(ctx, "weekly")
})
// Metrics prune — daily at 04:00
if metricsStore != nil {
sched.Daily("metrics-prune", "04:00", func(ctx context.Context) error {