feat(notifications): aggregate alerts from all nodes in the notification panel

Remote-node alerts now appear in the local notification bell alongside
local ones, each tagged with the originating node name.

- backend: reorder WS upgrade handler so /ws/notifications?nodeId=<remote>
  falls through to the existing proxy path instead of short-circuiting
- frontend/api.ts: add fetchForNode() helper for explicit node-targeted
  requests without touching the localStorage active-node key
- frontend/EditorLayout: fetch notification history from all registered
  nodes in parallel on mount and on node-list changes; open a per-remote
  WebSocket connection for real-time push; route mark-read / delete / clear
  actions back to the originating node; show node-name badge on remote alerts
This commit is contained in:
SaelixCode
2026-03-21 17:38:55 -04:00
parent 30fe77cd5d
commit 1690f0d3c6
4 changed files with 207 additions and 30 deletions
+26
View File
@@ -47,4 +47,30 @@ export async function apiFetch(
return response;
}
/** Fetch against a specific node by ID without touching the localStorage active-node key.
* Used by the notification panel to target individual remote nodes explicitly. */
export async function fetchForNode(
endpoint: string,
nodeId: number,
options: RequestInit = {}
): Promise<Response> {
const { headers: extraHeaders, ...rest } = options;
const response = await fetch(`${API_BASE}${endpoint}`, {
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'x-node-id': String(nodeId),
...(extraHeaders as Record<string, string> | undefined),
},
...rest,
});
if (response.status === 401) {
window.dispatchEvent(new Event('sencho-unauthorized'));
throw new Error('Unauthorized');
}
return response;
}
export { API_BASE };