Phase 2: monitoring warnings, dashboard alerts & notification system

- Monitoring page: "Távoli monitoring" section showing healthcheck ping UUID
  configuration status (configured/not configured) for each of the 5 pings
- Alert manager: persistent dashboard banners on all pages generated from
  health check results, missing pings, and backup status
- Notification system: controller-side notifier sends events to hub relay,
  with cooldown tracking and event-type filtering
- Notification preferences UI: email, event checkboxes, cooldown settings
  on the settings page with test email functionality
- Settings refactored: shared settingsData() helper, NotificationPrefs
  struct with getter/setter and defaults

New files:
- controller/internal/web/alerts.go (AlertManager)
- controller/internal/notify/notifier.go (hub notification client)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-16 19:29:45 +01:00
parent ded59b687e
commit 3eee330ed5
10 changed files with 837 additions and 23 deletions
@@ -527,6 +527,29 @@ h3 {
}
.form-group-auto label { margin: 0; }
.auto-generated-badge { color: var(--green); font-size: .8rem; font-weight: 500; }
.checkbox-group {
display: flex;
flex-direction: column;
gap: .5rem;
margin-top: .25rem;
}
.form-inline {
display: flex;
align-items: center;
gap: .75rem;
}
.form-control-narrow {
width: 80px;
}
.form-hint {
font-size: .85rem;
color: var(--text-muted);
}
.form-actions {
display: flex;
gap: .75rem;
margin-top: 1rem;
}
.form-control {
width: 100%;
padding: .55rem .75rem;
@@ -640,6 +663,37 @@ select.form-control option { background: var(--bg-secondary); color: var(--text-
border-color: rgba(210, 153, 34, 0.3);
}
/* Dashboard alert banners */
.alerts-container { margin-bottom: 1rem; }
.alert-banner {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 0.75rem 1rem;
border-radius: 8px;
margin-bottom: 0.5rem;
font-size: 0.9rem;
border: 1px solid;
}
.alert-banner-error {
background: rgba(248, 113, 113, 0.1);
border-color: rgba(248, 113, 113, 0.3);
color: #f87171;
}
.alert-banner-warning {
background: rgba(250, 204, 21, 0.1);
border-color: rgba(250, 204, 21, 0.3);
color: #facc15;
}
.alert-banner-info {
background: rgba(96, 165, 250, 0.1);
border-color: rgba(96, 165, 250, 0.3);
color: #60a5fa;
}
.alert-icon { flex-shrink: 0; }
.alert-message { flex: 1; }
.alert-link { margin-left: auto; white-space: nowrap; }
/* Memory summary on deploy page */
.memory-summary {
background: var(--bg-card);
@@ -1488,6 +1542,34 @@ a.stat-card:hover {
.monitor-card h3 {
margin-bottom: .75rem;
}
.monitoring-banner {
padding: .75rem 1rem;
border-radius: 8px;
font-size: .9rem;
border: 1px solid;
}
.monitoring-banner-green {
background: var(--green-bg);
color: var(--green);
border-color: rgba(35, 134, 54, 0.3);
}
.monitoring-banner-yellow {
background: var(--yellow-bg);
color: var(--yellow);
border-color: rgba(210, 153, 34, 0.3);
}
.monitoring-banner-red {
background: var(--orange-bg);
color: var(--orange);
border-color: rgba(219, 109, 40, 0.3);
}
.ping-status-ok { color: var(--green); }
.ping-status-warn { color: var(--yellow); }
.ping-schedule {
color: var(--text-muted);
font-size: .85rem;
margin-left: .75rem;
}
.monitor-card-header {
display: flex;
align-items: center;