Endpoint¶
ws://host/api/v2/dashboard/ws
wss://host/api/v2/dashboard/ws (production)
Connection¶
Query Parameters¶
| Parameter | Type | Required | Description |
|---|---|---|---|
token |
string | No* | JWT authentication token |
*When multi-tenant mode is enabled, token is required either as query param or in the first message.
Authentication (WS3.4)¶
- Query parameter:
ws://host/api/v2/dashboard/ws?token=<JWT> - First message: Send
{"token": "<JWT>"}within 5 seconds of connection
If authentication fails, the server sends:
{"event": "error", "message": "Authentication required"}
and closes the connection with code 1008.
Message Format¶
All messages are JSON-encoded strings.
Server -> Client Events¶
connected¶
Sent immediately after successful connection:
{
"event": "connected",
"client_id": "ws-1",
"heartbeat_seconds": 30
}
heartbeat¶
Sent every N seconds (configurable, default 30):
{
"event": "heartbeat",
"timestamp": 1710700000.123,
"clients": 3
}
project_updated¶
Sent when audit, compliance, or release gate analysis completes:
{
"event": "project_updated",
"project_name": "my-project",
"trigger": "audit",
"timestamp": 1710700000.123
}
pong¶
Response to client ping:
{"event": "pong"}
Client -> Server Messages¶
| Message | Description |
|---|---|
ping |
Keep-alive ping, server responds with pong |
Configuration¶
In config.yaml:
dashboard:
websocket_enabled: true
websocket_heartbeat_seconds: 30
JavaScript Client Example¶
const protocol = location.protocol === "https:" ? "wss:" : "ws:";
const ws = new WebSocket(`${protocol}//${location.host}/api/v2/dashboard/ws`);
ws.onopen = () => console.log("Connected");
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
switch (msg.event) {
case "connected":
console.log("Client ID:", msg.client_id);
break;
case "project_updated":
console.log("Updated:", msg.project_name);
// Refresh dashboard data
break;
case "heartbeat":
break;
}
};
ws.onclose = () => {
// Reconnect after 5s
setTimeout(() => connect(), 5000);
};
React Hook¶
The dashboard provides a useWebSocket hook:
import { useWebSocket } from "@/hooks/useWebSocket";
function Dashboard() {
const { connected, lastMessage } = useWebSocket((projectName) => {
// Called when project_updated event received
refetchData();
});
return <div>WS: {connected ? "connected" : "disconnected"}</div>;
}