R-101 + F-DIAG: the restore dialog names the last SUCCESSFUL copy (v0.182.0)

Tier2LastRun is the attempt clock and was rendered as 'Legutóbbi másolat' in the restore
confirm dialog. New LastSuccess + SuccessTracked anchor; tier2Update makes the three
rebuild sites safe by construction. F-DIAG: six distinct causes, target-aware redaction.
This commit is contained in:
2026-07-28 16:36:47 +02:00
parent 3db8bfb953
commit 3f048e042b
12 changed files with 829 additions and 72 deletions
+17 -6
View File
@@ -232,12 +232,23 @@ type CrossDriveBackup struct {
Schedule string `json:"schedule"` // "daily", "weekly", "manual"
// Runtime state (updated by backup runner, persisted for display)
LastRun string `json:"last_run,omitempty"` // RFC3339
LastStatus string `json:"last_status,omitempty"` // "ok", "error", "running"
LastError string `json:"last_error,omitempty"`
LastWarning string `json:"last_warning,omitempty"` // Tier-2 3b: capture-gap / state-only notice (Hungarian)
LastDuration string `json:"last_duration,omitempty"` // "2m34s"
LastSizeHuman string `json:"last_size_human,omitempty"` // "1.2 GB"
LastRun string `json:"last_run,omitempty"` // RFC3339
LastStatus string `json:"last_status,omitempty"` // "ok", "error", "running"
LastError string `json:"last_error,omitempty"`
// LastSuccess (R-101) is the last COPY that actually succeeded — the only timestamp a customer may
// be shown as evidence that a copy exists. LastRun above is written on failure too
// (recordTier2Failure), so it records an ATTEMPT; presenting it as „Legutóbbi másolat" in the
// restore dialog told a customer a copy existed from last night when last night had failed.
// Same rule and shape as the offsite tier's anchor — see backup.offboxAnchorAfterRun.
LastSuccess string `json:"last_success,omitempty"` // RFC3339
// SuccessTracked distinguishes "this row predates the anchor" from "this row has an anchor and it
// is empty, i.e. nothing has succeeded". Without it the two are indistinguishable (both are
// LastSuccess=="") and every pre-existing row on the fleet would render as never-succeeded on the
// deploy — all 7 rows on the two demo boxes were in exactly that state. Set by every runner write.
SuccessTracked bool `json:"success_tracked,omitempty"`
LastWarning string `json:"last_warning,omitempty"` // Tier-2 3b: capture-gap / state-only notice (Hungarian)
LastDuration string `json:"last_duration,omitempty"` // "2m34s"
LastSizeHuman string `json:"last_size_human,omitempty"` // "1.2 GB"
// Customer preference (set from the per-app Tier-2 config panel; PRESERVED across the runner's
// status writes). UserDisabled turns Tier 2 off for this app; PreferredTarget pins a chosen