backup tile: unknown size shows a dash, not 0 B (R-517 follow-up, measured on 9201)
gates / gates (push) Successful in 14s

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-09-15 10:53:20 +02:00
parent 843b319f35
commit d3eacbb7cc
4 changed files with 37 additions and 1 deletions
@@ -114,6 +114,10 @@ type guestBackupView struct {
CanTrigger bool // a backup trigger (quiesce loop) is wired
// SizeUnknown (R-517): the shown success was read back from storage after an agent restart, so
// its size is not known. The tile prints „–", never „0 B" (measured live on 9201, 2026-09-15).
SizeUnknown bool
// Tiers (R-517, agent >= v0.131.0) is the per-tier truth. Empty on an older agent — the tile then
// renders the single latest record as before.
Tiers []guestTierView
@@ -182,6 +186,7 @@ func buildTierViews(v *guestBackupView, tiers []agentapi.TierBackupState, cadenc
if tv.HasSuccess && (t.Primary || !v.HasBackup) && (t.Primary || tv.SuccessAt.After(newestOK)) {
v.HasBackup, v.Success = true, true
v.StartedAt, v.SizeBytes, v.Target = tv.SuccessAt, tv.SizeBytes, tv.Label
v.SizeUnknown = !tv.SizeKnown
newestOK = tv.SuccessAt
}
v.Tiers = append(v.Tiers, tv)
@@ -1,6 +1,8 @@
package web
import (
"bytes"
"strings"
"testing"
"time"
@@ -74,4 +76,24 @@ func TestBuildTierViews_SuccessFromStorageAfterRestart(t *testing.T) {
if !v.HasBackup || v.Due || v.Tiers[0].SizeKnown {
t.Fatalf("after restart: want the local success shown, up to date, size unknown: %+v / due=%v", v.Tiers[0], v.Due)
}
// MEASURED LIVE 2026-09-15 on 9201: the top card printed „0 B" for this state.
// RED-PROOF (run 2026-09-15, recorded in REPORT.md): without `v.SizeUnknown = !tv.SizeKnown`
// this failed at "tile would print a size it does not know".
if !v.SizeUnknown {
t.Fatal("tile would print a size it does not know (0 B) for a success read back from storage")
}
}
// The rendered tile says „–", not „0 B", when the size is unknown.
func TestBackupTile_UnknownSizeRendersDash(t *testing.T) {
s := securityHarness(t)
s.loadTemplates()
v := &guestBackupView{Available: true, HasBackup: true, Success: true, SizeUnknown: true, Target: "Helyi tároló (local)"}
var buf bytes.Buffer
if err := s.tmpl.ExecuteTemplate(&buf, "backups", map[string]interface{}{"Page": "backups", "Title": "t", "GuestBackup": v, "Backup": map[string]interface{}{}}); err != nil {
t.Skipf("backups page needs more data than this harness gives: %v", err)
}
if strings.Contains(buf.String(), ">0 B<") {
t.Fatal("unknown size rendered as 0 B")
}
}
@@ -93,7 +93,7 @@
</div>
</div>
<div class="stat-card stat-total">
<div class="stat-value">{{if .HasBackup}}{{fmtBytes .SizeBytes}}{{else}}–{{end}}</div>
<div class="stat-value">{{if and .HasBackup (not .SizeUnknown)}}{{fmtBytes .SizeBytes}}{{else}}–{{end}}</div>
<div class="stat-label">{{if .HasBackup}}{{.Target}}{{else}}Méret / cél{{end}}</div>
</div>
<div class="stat-card">