You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
h8suga f9dd4d9f9b feat(notify): unified notification manager + webhooks + shell bell
Ships an end-to-end notification pipeline: ring buffer + persistence,
HTTP CRUD + SSE stream, backend Push() calls at ~20 async/scheduled
sites, Telegram+generic HTTP dispatcher, shell bell icon with sliding
panel, and a Notifications settings section for webhook management.

Backend (Agents U + V):
- New pkg internal/services/notify — cap-500 ring, SSE broadcast via
  events.DefaultHub topic "notifications", MarkRead / MarkAllRead /
  Delete / Clear + persistence to <dataDir>/notifications.json with
  500 ms debounced atomic write.
- Webhook dispatcher: goroutine consumes notify.PushChan, fan-out to
  every matching hook. Filters all / errors_only / warn_and_above /
  success_and_above. Retry 3× with 1/2/4 s backoff, 10 s per-request
  timeout. Telegram POST {chat_id, text=title+body, parse_mode:HTML};
  generic POST raw Notification JSON. LastError / LastSuccessAt
  stamped per attempt.
- 11 Push sites: feeds.fetch / feeds.error, routing.apply / commit /
  rollback, awg.tunnel_up / tunnel_down / handshake_recovered,
  update.available / applied / failed, pihole.enabled / disabled /
  container_restarted, auth.login / auth.failed (now with client IP
  + User-Agent via new AuthClient meta), backup.import / export,
  panic.recovered (server.go recoverer middleware), ipmeta.reload.

Frontend (Agents W + X):
- lib/notifications.ts — module-level singleton store,
  useSyncExternalStore hook, refcounted SSE + initial GET, backoff+
  jitter reconnect, optimistic UI actions, sonner-toast fallback for
  incoming errors when the panel is closed.
- NotifyBell + NotifyPanel — bell now lives in the desktop sidebar
  HEADER next to the "NFQWS2" title (was previously footer-only per
  user request), still mounted in mobile top bar. Sheet panel groups
  by Today / Yesterday / Older, filter chips (All / Errors /
  Warnings / Unread), row = colored dot + title (bold if unread) +
  2-line body + relative timestamp (Intl.RelativeTimeFormat) + source
  badge + hover dismiss X. Panel header pr-12 so the sheet's built-in
  close X no longer collides with "Clear all".
- Notifications settings under System — WebhookTable + Add/Edit
  Dialog with kind-dependent labels (Telegram bot-token URL + chat_id
  vs generic URL), inline validation, Test button hitting the backend
  test endpoint.
- All strings routed through dict.ts (en+ru) — 60+ new keys under
  notify.*.

Wiring in server.go / app.go: RegisterNotifyAPI +
RegisterNotifyWebhooksAPI + /api/notifications/stream SSE alias +
notify.InitDispatcher on boot.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2 months ago
..
rr feat(notify): unified notification manager + webhooks + shell bell 2 months ago