package agentapi // DiskVerdict is the customer-facing disk-health verdict derived from a SmartSummary (v0.169.0). // It is the SHARED source of truth for both the "Lemezek állapota" dashboard card and the 6-hourly // degradation check — one pure function so the chip and the alert can never disagree. type DiskVerdict int const ( // DiskVerdictUnknown — no SMART data (nil / UNKNOWN / old agent). Renders "Nincs adat"; NEVER // alarms and NEVER participates in degradation transitions (excluded both directions). DiskVerdictUnknown DiskVerdict = iota DiskVerdictOK // "Rendben" — PASSED, all counters clean DiskVerdictWarn // "Figyelmeztetés" — PASSED but a wear/relocation counter is non-zero (or NVMe ≥90%) DiskVerdictFail // "Hiba" — FAILING ) // percentageUsedWarn is the NVMe wear threshold (inclusive) at which a still-PASSED disk warns. const percentageUsedWarn = 90 // DiskVerdictFor maps a SmartSummary to a verdict per the v0.169.0 rules: // // FAILING → Hiba // PASSED + any(reallocated>0, pending>0, offline_unc>0, // critical_warning>0, media_errors>0, // percentage_used >= 90) → Figyelmeztetés // PASSED otherwise → Rendben // nil / UNKNOWN / empty → Nincs adat func DiskVerdictFor(s *SmartSummary) DiskVerdict { if s == nil || s.Health == "" || s.Health == SmartUnknown { return DiskVerdictUnknown } if s.Health == SmartFailing { return DiskVerdictFail } // Health == PASSED (or any non-empty non-FAILING value we treat as passing): inspect the counters. if positive(s.ReallocatedSectors) || positive(s.PendingSectors) || positive(s.OfflineUncorrectable) || positive(s.CriticalWarning) || positive(s.MediaErrors) || atLeast(s.PercentageUsed, percentageUsedWarn) { return DiskVerdictWarn } return DiskVerdictOK } // Label is the exact Hungarian customer copy for the verdict (shared by the card chip and the email). func (v DiskVerdict) Label() string { switch v { case DiskVerdictOK: return "Rendben" case DiskVerdictWarn: return "Figyelmeztetés" case DiskVerdictFail: return "Hiba" default: return "Nincs adat" } } // DegradedAttributes returns the human-readable Hungarian names of the attribute(s) that pushed a // PASSED disk to Figyelmeztetés (empty for OK/Fail/Unknown) — for the alert body. FAILING is a // whole-disk verdict with no single triggering counter, so it returns nil there. func DegradedAttributes(s *SmartSummary) []string { if s == nil { return nil } var out []string if positive(s.ReallocatedSectors) { out = append(out, "áthelyezett szektorok") } if positive(s.PendingSectors) { out = append(out, "függőben lévő szektorok") } if positive(s.OfflineUncorrectable) { out = append(out, "javíthatatlan szektorok") } if positive(s.CriticalWarning) { out = append(out, "kritikus figyelmeztetés") } if positive(s.MediaErrors) { out = append(out, "adathordozó-hibák") } if atLeast(s.PercentageUsed, percentageUsedWarn) { out = append(out, "elhasználódás") } return out } func positive(p *int) bool { return p != nil && *p > 0 } func atLeast(p *int, n int) bool { return p != nil && *p >= n }