fix(config): ensure NotifyOnResolve defaults to true for new and legacy configs

This commit is contained in:
rcourtman
2026-02-05 09:30:08 +00:00
parent 93fd5788c9
commit dc66eb544c
2 changed files with 37 additions and 1 deletions
+15 -1
View File
@@ -123,6 +123,14 @@ func (h *NotificationHandlers) UpdateEmailConfig(w http.ResponseWriter, r *http.
log.Info().
Msg("Received email config update")
// Parse strict subset to check for presence of fields
var presenceCheck struct {
RateLimit *int `json:"rateLimit"`
}
if err := json.Unmarshal(body, &presenceCheck); err != nil {
// Non-fatal, just means we can't do presence check
}
var config notifications.EmailConfig
if err := json.Unmarshal(body, &config); err != nil {
log.Error().Err(err).Msg("Failed to parse email config") // Don't log body with passwords
@@ -130,12 +138,18 @@ func (h *NotificationHandlers) UpdateEmailConfig(w http.ResponseWriter, r *http.
return
}
existingConfig := h.getMonitor(r.Context()).GetNotificationManager().GetEmailConfig()
// If password is empty, preserve the existing password
if config.Password == "" {
existingConfig := h.getMonitor(r.Context()).GetNotificationManager().GetEmailConfig()
config.Password = existingConfig.Password
}
// If rateLimit was NOT provided (nil in presence check), preserve existing
if presenceCheck.RateLimit == nil {
config.RateLimit = existingConfig.RateLimit
}
log.Info().
Bool("enabled", config.Enabled).
Str("smtp", config.SMTPHost).
+22
View File
@@ -530,6 +530,9 @@ func (c *ConfigPersistence) LoadAlertConfig() (*alerts.AlertConfig, error) {
Memory: &alerts.HysteresisThreshold{Trigger: 85, Clear: 80},
Disk: &alerts.HysteresisThreshold{Trigger: 90, Clear: 85},
},
Schedule: alerts.ScheduleConfig{
NotifyOnResolve: true,
},
StorageDefault: alerts.HysteresisThreshold{Trigger: 85, Clear: 80},
TimeThreshold: 5,
TimeThresholds: map[string]int{
@@ -594,6 +597,25 @@ func (c *ConfigPersistence) LoadAlertConfig() (*alerts.AlertConfig, error) {
if config.HysteresisMargin <= 0 {
config.HysteresisMargin = 5.0
}
// NotifyOnResolve defaults to true (send recovery notifications).
// Since bool zero-value is false, we check raw JSON to distinguish
// "missing field" (old configs) from "explicitly set to false".
if !config.Schedule.NotifyOnResolve {
// Use a temporary map to check if the field exists in the JSON
var raw map[string]interface{}
// Ignore error here as we've already unmarshaled successfully above
if json.Unmarshal(data, &raw) == nil {
// Check if "schedule" exists and has "notifyOnResolve"
if schedule, ok := raw["schedule"].(map[string]interface{}); ok {
if _, exists := schedule["notifyOnResolve"]; !exists {
config.Schedule.NotifyOnResolve = true
}
} else {
// "schedule" block missing entirely -> default to true
config.Schedule.NotifyOnResolve = true
}
}
}
// NodeDefaults.Temperature: Allow Trigger=0 to disable temperature alerting
if config.NodeDefaults.Temperature == nil || config.NodeDefaults.Temperature.Trigger < 0 {
config.NodeDefaults.Temperature = &alerts.HysteresisThreshold{Trigger: 80, Clear: 75}