refactor(models): typed Status constants with IsBroken() predicate
Replace ~150 bare status string comparisons with typed models.Status constants (StatusUp, StatusDown, StatusPending, StatusLate, StatusStale, StatusSSLExp). Single IsBroken() method replaces the duplicated isBroken lambda in monitor.go and isDown function in sla.go. Adding a new status value (e.g. DEGRADED) now requires one constant definition instead of grep-and-pray across 16 files. CheckResult.Status stays string — the checker is the boundary between raw protocol results and typed status. Cast happens at the edge in handleStatusChange.
This commit is contained in:
@@ -143,16 +143,16 @@ func (m Model) fmtRetries(site models.Site) string {
|
||||
dispCount = site.MaxRetries
|
||||
}
|
||||
s := fmt.Sprintf("%d/%d", dispCount, site.MaxRetries)
|
||||
if site.Status == "DOWN" {
|
||||
if site.Status == models.StatusDown {
|
||||
return m.st.dangerStyle.Render(s)
|
||||
}
|
||||
if site.Status == "UP" && site.FailureCount > 0 {
|
||||
if site.Status == models.StatusUp && site.FailureCount > 0 {
|
||||
return m.st.warnStyle.Render(s)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func (m Model) fmtStatus(status string, paused bool, inMaint bool) string {
|
||||
func (m Model) fmtStatus(status models.Status, paused bool, inMaint bool) string {
|
||||
if paused {
|
||||
return m.st.warnStyle.Render("◇ PAUSED")
|
||||
}
|
||||
@@ -160,18 +160,18 @@ func (m Model) fmtStatus(status string, paused bool, inMaint bool) string {
|
||||
return m.st.maintStyle.Render("◼ MAINT")
|
||||
}
|
||||
switch status {
|
||||
case "DOWN":
|
||||
case models.StatusDown:
|
||||
return m.st.dangerStyle.Render("▼ DOWN")
|
||||
case "SSL EXP":
|
||||
case models.StatusSSLExp:
|
||||
return m.st.dangerStyle.Render("▼ SSL EXP")
|
||||
case "LATE":
|
||||
case models.StatusLate:
|
||||
return m.st.warnStyle.Render("◆ LATE")
|
||||
case "STALE":
|
||||
case models.StatusStale:
|
||||
return m.st.staleStyle.Render("◆ STALE")
|
||||
case "PENDING":
|
||||
case models.StatusPending:
|
||||
return m.st.subtleStyle.Render("○ PENDING")
|
||||
default:
|
||||
return m.st.specialStyle.Render("▲ " + status)
|
||||
return m.st.specialStyle.Render("▲ " + string(status))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,19 +56,19 @@ func TestSiteOrder(t *testing.T) {
|
||||
|
||||
func TestFmtStatus(t *testing.T) {
|
||||
tests := []struct {
|
||||
status string
|
||||
status models.Status
|
||||
paused bool
|
||||
inMaint bool
|
||||
wantSub string
|
||||
}{
|
||||
{"DOWN", false, false, "▼ DOWN"},
|
||||
{"UP", false, false, "▲ UP"},
|
||||
{"SSL EXP", false, false, "▼ SSL EXP"},
|
||||
{"LATE", false, false, "◆ LATE"},
|
||||
{"STALE", false, false, "◆ STALE"},
|
||||
{"PENDING", false, false, "○ PENDING"},
|
||||
{"DOWN", true, false, "◇ PAUSED"},
|
||||
{"DOWN", false, true, "◼ MAINT"},
|
||||
{models.StatusDown, false, false, "▼ DOWN"},
|
||||
{models.StatusUp, false, false, "▲ UP"},
|
||||
{models.StatusSSLExp, false, false, "▼ SSL EXP"},
|
||||
{models.StatusLate, false, false, "◆ LATE"},
|
||||
{models.StatusStale, false, false, "◆ STALE"},
|
||||
{models.StatusPending, false, false, "○ PENDING"},
|
||||
{models.StatusDown, true, false, "◇ PAUSED"},
|
||||
{models.StatusDown, false, true, "◼ MAINT"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
got := styledModel.fmtStatus(tt.status, tt.paused, tt.inMaint)
|
||||
|
||||
@@ -240,7 +240,7 @@ func (m Model) viewSitesTab() string {
|
||||
name = limitStr(name, nameW-2)
|
||||
}
|
||||
|
||||
if (site.Status == "DOWN" || site.Status == "SSL EXP" || site.Status == "LATE" || site.Status == "STALE") && site.LastError != "" {
|
||||
if (site.Status == models.StatusDown || site.Status == models.StatusSSLExp || site.Status == models.StatusLate || site.Status == models.StatusStale) && site.LastError != "" {
|
||||
nameLen := len([]rune(name))
|
||||
errSpace := nameW - nameLen - 3
|
||||
if errSpace > 10 {
|
||||
|
||||
@@ -455,7 +455,7 @@ func (m *Model) handleSLAData(msg slaDataMsg) (tea.Model, tea.Cmd) {
|
||||
}
|
||||
period := slaPeriods[msg.periodIdx]
|
||||
|
||||
var currentStatus string
|
||||
var currentStatus models.Status
|
||||
for _, s := range m.sites {
|
||||
if s.ID == msg.siteID {
|
||||
currentStatus = s.Status
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gitea.lerkolabs.com/lerkolabs/uptop/internal/models"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
)
|
||||
|
||||
@@ -16,7 +17,7 @@ func sinApprox(x float64) float64 {
|
||||
func (m Model) pulseIndicator() string {
|
||||
hasDown := false
|
||||
for _, s := range m.sites {
|
||||
if !s.Paused && !m.isMonitorInMaintenance(s.ID) && (s.Status == "DOWN" || s.Status == "SSL EXP") {
|
||||
if !s.Paused && !m.isMonitorInMaintenance(s.ID) && (s.Status == models.StatusDown || s.Status == models.StatusSSLExp) {
|
||||
hasDown = true
|
||||
break
|
||||
}
|
||||
@@ -127,9 +128,9 @@ func (m Model) computeStats() dashboardStats {
|
||||
continue
|
||||
}
|
||||
switch site.Status {
|
||||
case "DOWN", "SSL EXP":
|
||||
case models.StatusDown, models.StatusSSLExp:
|
||||
s.downCount++
|
||||
case "LATE":
|
||||
case models.StatusLate:
|
||||
s.lateCount++
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ func (m Model) viewDetailPanel() string {
|
||||
|
||||
row("Status", m.fmtStatus(site.Status, site.Paused, m.isMonitorInMaintenance(site.ID)))
|
||||
|
||||
if (site.Status == "DOWN" || site.Status == "SSL EXP" || site.Status == "LATE" || site.Status == "STALE") && site.LastError != "" {
|
||||
if (site.Status == models.StatusDown || site.Status == models.StatusSSLExp || site.Status == models.StatusLate || site.Status == models.StatusStale) && site.LastError != "" {
|
||||
errWidth := m.termWidth - chromePadH - 19
|
||||
if errWidth < 30 {
|
||||
errWidth = 30
|
||||
@@ -58,7 +58,7 @@ func (m Model) viewDetailPanel() string {
|
||||
row("HTTP Code", strconv.Itoa(site.StatusCode))
|
||||
}
|
||||
|
||||
if (site.Status == "DOWN" || site.Status == "SSL EXP") && site.LastError != "" {
|
||||
if (site.Status == models.StatusDown || site.Status == models.StatusSSLExp) && site.LastError != "" {
|
||||
chain := connectionChain(site.LastError, site.Type, site.StatusCode, strings.HasPrefix(site.URL, "https"))
|
||||
if len(chain) > 0 {
|
||||
b.WriteString("\n")
|
||||
@@ -189,7 +189,7 @@ func (m Model) viewDetailPanel() string {
|
||||
for i, sc := range stateChanges {
|
||||
ago := fmtDuration(time.Since(sc.ChangedAt))
|
||||
arrow := m.st.subtleStyle.Render(sc.FromStatus) + " → "
|
||||
if sc.ToStatus == "UP" {
|
||||
if sc.ToStatus == string(models.StatusUp) {
|
||||
arrow += m.st.specialStyle.Render(sc.ToStatus)
|
||||
} else {
|
||||
arrow += m.st.dangerStyle.Render(sc.ToStatus)
|
||||
@@ -198,7 +198,7 @@ func (m Model) viewDetailPanel() string {
|
||||
if dur := computeOutageDuration(stateChanges, i); dur > 0 {
|
||||
line += " " + m.st.warnStyle.Render("outage "+fmtDuration(dur))
|
||||
}
|
||||
if sc.ErrorReason != "" && sc.ToStatus != "UP" {
|
||||
if sc.ErrorReason != "" && sc.ToStatus != string(models.StatusUp) {
|
||||
line += " " + m.st.dangerStyle.Render(sc.ErrorReason)
|
||||
}
|
||||
b.WriteString(line + "\n")
|
||||
|
||||
@@ -17,14 +17,14 @@ type historyStats struct {
|
||||
|
||||
func computeOutageDuration(changes []models.StateChange, idx int) time.Duration {
|
||||
sc := changes[idx]
|
||||
if sc.ToStatus != "UP" {
|
||||
if sc.ToStatus != string(models.StatusUp) {
|
||||
return 0
|
||||
}
|
||||
if idx+1 >= len(changes) {
|
||||
return 0
|
||||
}
|
||||
prev := changes[idx+1]
|
||||
if prev.ToStatus == "UP" {
|
||||
if prev.ToStatus == string(models.StatusUp) {
|
||||
return 0
|
||||
}
|
||||
dur := sc.ChangedAt.Sub(prev.ChangedAt)
|
||||
@@ -122,11 +122,11 @@ func (m Model) buildHistoryContent() string {
|
||||
|
||||
arrow := m.st.subtleStyle.Render(sc.FromStatus) + " → "
|
||||
switch sc.ToStatus {
|
||||
case "UP":
|
||||
case string(models.StatusUp):
|
||||
arrow += m.st.specialStyle.Render(sc.ToStatus)
|
||||
case "LATE":
|
||||
case string(models.StatusLate):
|
||||
arrow += m.st.warnStyle.Render(sc.ToStatus)
|
||||
case "STALE":
|
||||
case string(models.StatusStale):
|
||||
arrow += m.st.staleStyle.Render(sc.ToStatus)
|
||||
default:
|
||||
arrow += m.st.dangerStyle.Render(sc.ToStatus)
|
||||
@@ -138,7 +138,7 @@ func (m Model) buildHistoryContent() string {
|
||||
}
|
||||
|
||||
reason := ""
|
||||
if sc.ErrorReason != "" && sc.ToStatus != "UP" {
|
||||
if sc.ErrorReason != "" && sc.ToStatus != string(models.StatusUp) {
|
||||
reason = m.st.dangerStyle.Render(limitStr(sc.ErrorReason, reasonWidth))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user