feat(notifications): deep-link bell rows to source stack and container logs (#692)

Add stack_name and container_name columns to notification_history so bell
rows can act as jump points. Producers (AutoHeal, Docker events) pass the
container context through dispatchAlert; the panel renders routable rows
as buttons that load the target stack and, when a container name is
present, open its logs modal. Non-structural notifications stay as
passive display rows.
This commit is contained in:
Anso
2026-04-19 03:56:59 -04:00
committed by GitHub
parent 7c01906e70
commit ed2a16af79
9 changed files with 165 additions and 28 deletions
@@ -121,6 +121,7 @@ describe('DockerEventService - die classification', () => {
'error',
expect.stringContaining('Container Crash Detected'),
undefined,
'web',
);
});
@@ -188,6 +189,7 @@ describe('DockerEventService - die classification', () => {
'error',
expect.stringContaining('OOM Kill'),
undefined,
'hog',
);
});
@@ -220,6 +222,7 @@ describe('DockerEventService - die classification', () => {
'error',
expect.stringContaining('Healthcheck failed'),
undefined,
'api',
);
});
@@ -314,6 +317,7 @@ describe('DockerEventService - malformed payloads', () => {
'error',
expect.stringContaining('Container Crash Detected'),
undefined,
'ok',
);
});
});
@@ -497,6 +501,7 @@ describe('DockerEventService - hardening', () => {
'error',
expect.stringContaining('Container Crash Detected'),
undefined,
'app',
);
});
@@ -550,6 +555,7 @@ describe('DockerEventService - hardening', () => {
'error',
expect.stringContaining('Container Crash Detected'),
undefined,
'ephemeral',
);
});
@@ -214,6 +214,23 @@ describe('NotificationService - routing logic', () => {
level: 'info',
message: 'Should be logged',
timestamp: expect.any(Number),
stack_name: undefined,
container_name: undefined,
});
});
it('persists stackName and containerName context on the history row', async () => {
mockGetEnabledNotificationRoutes.mockReturnValue([]);
mockGetEnabledAgents.mockReturnValue([]);
await svc.dispatchAlert('warning', 'Restarted', 'my-app', 'my-app-web-1');
expect(mockAddNotificationHistory).toHaveBeenCalledWith({
level: 'warning',
message: 'Restarted',
timestamp: expect.any(Number),
stack_name: 'my-app',
container_name: 'my-app-web-1',
});
});