feat(notifications): add structured category enum to dispatcher and history (#774)

Introduce a NotificationCategory string-literal union (11 values) and
thread it through dispatchAlert as a required second argument. All
callers (DockerEventService, AutoHealService, ImageUpdateService,
MonitorService, PolicyEnforcement, policyGate, SchedulerService,
imageUpdates route) pass an explicit category at every call site,
giving TypeScript compile-time enforcement that no new emit site can
be added without choosing a category.

DatabaseService gains an idempotent migration that adds a nullable
category TEXT column to notification_history; existing rows keep
category=NULL (displayed as Uncategorized in the UI). The
getNotificationHistory method accepts an optional category filter
that is forwarded from the GET /api/notifications/history route via
a ?category= query param.

NotificationPanel gains a category Select dropdown so users can
filter history by category. The frontend types mirror the backend
union so API responses are type-safe end-to-end.

All 75 test files (1410 tests) updated to the new 4-arg dispatchAlert
signature and passing.
This commit is contained in:
Anso
2026-04-25 13:55:07 -04:00
committed by GitHub
parent a74564fd61
commit 44dba59cab
20 changed files with 250 additions and 134 deletions
+3 -1
View File
@@ -275,8 +275,9 @@ export class ImageUpdateService {
try {
await notifier.dispatchAlert(
'info',
'image_update_available',
`[Node: ${nodeName}] Stack "${stackName}" has image updates available.`,
stackName,
{ stackName },
);
} catch (e) {
console.error(`[ImageUpdateService] Failed to dispatch update notification for "${stackName}":`, e);
@@ -286,6 +287,7 @@ export class ImageUpdateService {
try {
db.addNotificationHistory(NodeRegistry.getInstance().getDefaultNodeId(), {
level: 'error',
category: 'system',
message: `[Node: ${nodeName}] Failed to notify about image updates for stack "${stackName}": ${getErrorMessage(e, String(e))}`,
timestamp: Date.now(),
});