v0.259.0 — the claim page and the backup warnings answer in the reader's language (R-596, R-598)
gates / gates (push) Successful in 28s
gates / gates (push) Successful in 28s
The 2026-09-20 English drill ended one screen short: the claim page was English and its answers were Hungarian, so a household who mistyped the code from their e-mail could not tell a typo from a dead code. Fourteen call sites carrying nine messages now go through s.msg; the backup page's two protection warnings — which are promises about whether the customer's files are safe — follow the same route. Hungarian is byte-identical, proved structurally by the go-parity gate against the frozen base capture and red-proofed on a single added full stop. data["Title"] was DEAD (claim.html is standalone; .Title is layout.html's) and is deleted rather than translated — a translated dead field is a permanent false signal about where the page's title comes from. Six existing copy-contract tests were kept, not weakened: each now resolves its key through the real bundle, so it still convicts on a reworded Hungarian sentence. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -151,16 +151,16 @@ func tierWindow(cadenceSecs int64) time.Duration {
|
||||
// buildTierViews turns the agent's per-tier state into page rows and derives the three legacy tile
|
||||
// fields from SUCCESSES only: HasBackup/Success/Size/Target/StartedAt from the primary tier's newest
|
||||
// success; Due when any set-up tier has no current success; Offsite only on a current PBS success.
|
||||
func buildTierViews(v *guestBackupView, tiers []agentapi.TierBackupState, cadence map[string]int64, now time.Time) {
|
||||
func buildTierViews(v *guestBackupView, tiers []agentapi.TierBackupState, cadence map[string]int64, now time.Time, msg func(key string, a ...interface{}) string) {
|
||||
v.Tiers = nil
|
||||
v.Due, v.Offsite, v.HasBackup = false, false, false
|
||||
var newestOK time.Time
|
||||
for _, t := range tiers {
|
||||
tv := guestTierView{Target: t.Target, IsPBS: strings.Contains(strings.ToLower(t.Target), "pbs")}
|
||||
if tv.IsPBS {
|
||||
tv.Label = "Biztonsági szerver – külön hardver (PBS)"
|
||||
tv.Label = msg("backup.tier.pbs")
|
||||
} else {
|
||||
tv.Label = "Helyi tároló (" + t.Target + ")"
|
||||
tv.Label = msg("backup.tier.local", t.Target)
|
||||
}
|
||||
tv.NotSetUp = t.Storage == "absent"
|
||||
if t.LastSuccess != nil {
|
||||
@@ -200,16 +200,17 @@ func buildTierViews(v *guestBackupView, tiers []agentapi.TierBackupState, cadenc
|
||||
|
||||
// loadGuestBackup fetches the agent's whole-guest backup view (best-effort). Returns a view with
|
||||
// Available=false (+ a note) when the agent isn't configured/reachable — the page still renders.
|
||||
func (s *Server) loadGuestBackup(ctx context.Context) *guestBackupView {
|
||||
func (s *Server) loadGuestBackup(ctx context.Context, lang string) *guestBackupView {
|
||||
msg := func(key string, a ...interface{}) string { return s.msgLang(lang, key, a...) }
|
||||
v := &guestBackupView{CanTrigger: s.backupTrigger != nil}
|
||||
client, err := s.agentClient()
|
||||
if err != nil {
|
||||
v.Note = "A host-ügynök nincs konfigurálva ezen a gépen."
|
||||
v.Note = msg("backup.guest.agent_unconfigured")
|
||||
return v
|
||||
}
|
||||
st, err := client.BackupStatus(ctx)
|
||||
if err != nil {
|
||||
v.Note = "A host-ügynök jelenleg nem elérhető."
|
||||
v.Note = msg("backup.guest.agent_unreachable")
|
||||
return v
|
||||
}
|
||||
v.Available = true
|
||||
@@ -222,7 +223,7 @@ func (s *Server) loadGuestBackup(ctx context.Context) *guestBackupView {
|
||||
v.Archive = st.Backup.Archive
|
||||
v.Mode = st.Backup.Mode
|
||||
v.StopMode = st.Backup.Mode == "stop"
|
||||
v.Target = backupTargetLabel(st.Backup)
|
||||
v.Target = backupTargetLabel(st.Backup, msg)
|
||||
v.Offsite = backupIsPBS(st.Backup)
|
||||
if t, perr := time.Parse(time.RFC3339, st.Backup.StartedAt); perr == nil {
|
||||
v.StartedAt = t
|
||||
@@ -245,7 +246,7 @@ func (s *Server) loadGuestBackup(ctx context.Context) *guestBackupView {
|
||||
cadence[t.Target] = t.CadenceSeconds
|
||||
}
|
||||
}
|
||||
buildTierViews(v, st.Tiers, cadence, time.Now())
|
||||
buildTierViews(v, st.Tiers, cadence, time.Now(), msg)
|
||||
}
|
||||
// Restore-test (the "verified restorable" trust signal; nil until one runs).
|
||||
if rt, rerr := client.RestoreTestStatus(ctx); rerr == nil && rt != nil {
|
||||
@@ -270,14 +271,14 @@ func backupIsPBS(b *agentapi.BackupRecord) bool {
|
||||
// backupTargetLabel maps the agent's backup target to a customer-facing Hungarian label. The PBS
|
||||
// case calls out that the backup is on SEPARATE HARDWARE (real disaster recovery — survives a host
|
||||
// disk/hardware failure), which is the whole point of re-pointing the backup offsite.
|
||||
func backupTargetLabel(b *agentapi.BackupRecord) string {
|
||||
func backupTargetLabel(b *agentapi.BackupRecord, msg func(key string, a ...interface{}) string) string {
|
||||
if backupIsPBS(b) {
|
||||
return "Biztonsági szerver – külön hardver (PBS)"
|
||||
return msg("backup.tier.pbs")
|
||||
}
|
||||
if b.TargetID != "" {
|
||||
return "Helyi tároló (" + b.TargetID + ")"
|
||||
return msg("backup.tier.local", b.TargetID)
|
||||
}
|
||||
return "Helyi tároló"
|
||||
return msg("backup.tier.local_plain")
|
||||
}
|
||||
|
||||
// ServeBackupAPI dispatches /api/guest-backup/* (whole-guest manual trigger + status poll). A
|
||||
@@ -298,12 +299,12 @@ func (s *Server) ServeBackupAPI(w http.ResponseWriter, r *http.Request) {
|
||||
// returns immediately (the backup runs async, minutes); the page polls /api/backup/status.
|
||||
func (s *Server) handleBackupTriggerAPI(w http.ResponseWriter, r *http.Request) {
|
||||
if s.backupTrigger == nil {
|
||||
writeDiskJSON(w, http.StatusServiceUnavailable, false, "a rendszermentés nem érhető el ezen a gépen", nil)
|
||||
writeDiskJSON(w, http.StatusServiceUnavailable, false, s.msg(r, "backup.guest.err.unavailable"), nil)
|
||||
return
|
||||
}
|
||||
if err := s.backupTrigger.TriggerNow(); err != nil {
|
||||
if errors.Is(err, quiesce.ErrBackupInProgress) {
|
||||
writeDiskJSON(w, http.StatusConflict, false, "mentés már folyamatban van", nil)
|
||||
writeDiskJSON(w, http.StatusConflict, false, s.msg(r, "backup.guest.err.in_progress"), nil)
|
||||
return
|
||||
}
|
||||
s.logger.Printf("[ERROR] [web] backup trigger failed: %v", err)
|
||||
|
||||
Reference in New Issue
Block a user