feat: Hub monitoring takeover — event system, dead man's switch, notifications (v0.3.0)
Replace external Healthchecks.io with Hub-native monitoring. New events table + /api/v1/event endpoint for structured events from controllers. Staleness checker (60s) detects unresponsive nodes. Backup deadline checker (daily 05:00) catches missed backups. Notification dispatcher sends operator (English) + customer (Hungarian) emails via Resend with per-event cooldowns. Event timeline on customer page, dashboard badges. Config form deprecates Monitoring UUIDs section. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -223,12 +223,14 @@ func (s *Server) handleCustomerUnified(w http.ResponseWriter, r *http.Request, c
|
||||
}
|
||||
}
|
||||
|
||||
// History, notifications, infra backup
|
||||
// History, notifications, events, infra backup
|
||||
var history []store.CustomerSummary
|
||||
var notifPrefs *store.NotificationPrefs
|
||||
var recentNotifs []store.NotificationLogEntry
|
||||
var infraMeta *store.InfraBackupMeta
|
||||
var infraBackupAge string
|
||||
var events []store.Event
|
||||
var eventCounts map[string]int
|
||||
|
||||
if customer != nil {
|
||||
history, _ = s.store.GetCustomerHistory(customerID, 24*time.Hour)
|
||||
@@ -238,6 +240,8 @@ func (s *Server) handleCustomerUnified(w http.ResponseWriter, r *http.Request, c
|
||||
if infraMeta != nil {
|
||||
infraBackupAge = timeAgo(infraMeta.UpdatedAt)
|
||||
}
|
||||
events, _ = s.store.GetRecentEvents(customerID, 50)
|
||||
eventCounts, _ = s.store.CountEventsBySeverity(customerID, time.Now().Add(-24*time.Hour))
|
||||
}
|
||||
|
||||
type pageData struct {
|
||||
@@ -270,6 +274,9 @@ func (s *Server) handleCustomerUnified(w http.ResponseWriter, r *http.Request, c
|
||||
RecentNotifications []store.NotificationLogEntry
|
||||
History []store.CustomerSummary
|
||||
|
||||
Events []store.Event
|
||||
EventCounts map[string]int // severity → count (last 24h)
|
||||
|
||||
Flash string
|
||||
ActiveNav string
|
||||
}
|
||||
@@ -304,6 +311,9 @@ func (s *Server) handleCustomerUnified(w http.ResponseWriter, r *http.Request, c
|
||||
RecentNotifications: recentNotifs,
|
||||
History: history,
|
||||
|
||||
Events: events,
|
||||
EventCounts: eventCounts,
|
||||
|
||||
Flash: r.URL.Query().Get("flash"),
|
||||
ActiveNav: "configs",
|
||||
}
|
||||
@@ -697,7 +707,7 @@ func buildConfigJSON(r *http.Request) string {
|
||||
overrides["git"] = git
|
||||
}
|
||||
|
||||
// Monitoring UUIDs
|
||||
// Monitoring UUIDs (legacy — only written if user explicitly provides values)
|
||||
uuids := make(map[string]interface{})
|
||||
for _, key := range []string{"heartbeat", "system_health", "db_dump", "backup", "backup_integrity"} {
|
||||
if v := strings.TrimSpace(r.FormValue("uuid_" + key)); v != "" {
|
||||
|
||||
Reference in New Issue
Block a user