Files
git.stella-ops.org/docs/modules/release-orchestrator/api/websockets.md

6.6 KiB

Real-Time APIs (WebSocket/SSE)

WebSocket and Server-Sent Events endpoints for real-time updates.

Status: Planned (not yet implemented) Source: Architecture Advisory Section 6.4 Related Modules: Workflow Execution, UI Dashboard

Overview

The Release Orchestrator provides real-time streaming endpoints for workflow runs, deployment progress, agent tasks, and dashboard metrics. These endpoints support both WebSocket connections and Server-Sent Events (SSE) for browser compatibility.


Authentication

All WebSocket and SSE connections require authentication via JWT token:

WebSocket: Token in query parameter or first message

ws://api/v1/workflow-runs/{id}/stream?token=jwt-token

SSE: Token in Authorization header

GET /api/v1/dashboard/stream
Authorization: Bearer jwt-token

Workflow Run Stream

Endpoint: WS /api/v1/workflow-runs/{id}/stream

Streams real-time updates for a workflow run including step progress and logs.

Message Types (Server to Client)

Step Started:

{
  "type": "step_started",
  "nodeId": "security-check",
  "stepType": "security-gate",
  "timestamp": "2026-01-10T14:23:45Z"
}

Step Progress:

{
  "type": "step_progress",
  "nodeId": "deploy",
  "progress": 50,
  "message": "Deploying to target 3/6"
}

Step Log:

{
  "type": "step_log",
  "nodeId": "deploy",
  "line": "Pulling image sha256:abc123...",
  "level": "info",
  "timestamp": "2026-01-10T14:23:50Z"
}

Step Completed:

{
  "type": "step_completed",
  "nodeId": "security-check",
  "status": "succeeded",
  "outputs": {
    "criticalCount": 0,
    "highCount": 3
  },
  "duration": 5.2,
  "timestamp": "2026-01-10T14:23:50Z"
}

Workflow Completed:

{
  "type": "workflow_completed",
  "status": "succeeded",
  "duration": 125.5,
  "outputs": {
    "deploymentId": "uuid"
  },
  "timestamp": "2026-01-10T14:25:50Z"
}

Deployment Job Stream

Endpoint: WS /api/v1/deployment-jobs/{id}/stream

Streams real-time updates for deployment job execution.

Message Types (Server to Client)

Task Started:

{
  "type": "task_started",
  "taskId": "uuid",
  "targetId": "uuid",
  "targetName": "prod-web-01",
  "taskType": "docker.pull",
  "timestamp": "2026-01-10T14:23:45Z"
}

Task Progress:

{
  "type": "task_progress",
  "taskId": "uuid",
  "progress": 75,
  "message": "Pulling layer 4/5"
}

Task Log:

{
  "type": "task_log",
  "taskId": "uuid",
  "line": "Container started successfully",
  "level": "info"
}

Task Completed:

{
  "type": "task_completed",
  "taskId": "uuid",
  "targetId": "uuid",
  "status": "succeeded",
  "duration": 45.2,
  "result": {
    "containerId": "abc123",
    "digest": "sha256:..."
  },
  "timestamp": "2026-01-10T14:24:30Z"
}

Job Completed:

{
  "type": "job_completed",
  "status": "succeeded",
  "targetsDeployed": 4,
  "targetsFailed": 0,
  "duration": 180.5,
  "timestamp": "2026-01-10T14:26:45Z"
}

Agent Task Stream

Endpoint: WS /api/v1/agents/{id}/task-stream

Bidirectional stream for agent task assignment and progress reporting.

Message Types (Server to Agent)

Task Assigned:

{
  "type": "task_assigned",
  "task": {
    "taskId": "uuid",
    "taskType": "docker.pull",
    "payload": {
      "image": "myapp",
      "digest": "sha256:abc123..."
    },
    "credentials": {
      "registry.username": "user",
      "registry.password": "token"
    },
    "timeout": 300
  }
}

Task Cancelled:

{
  "type": "task_cancelled",
  "taskId": "uuid",
  "reason": "Deployment cancelled by user"
}

Message Types (Agent to Server)

Task Progress:

{
  "type": "task_progress",
  "taskId": "uuid",
  "progress": 50,
  "message": "Pulling image layer 3/5"
}

Task Log:

{
  "type": "task_log",
  "taskId": "uuid",
  "level": "info",
  "message": "Image layer downloaded: sha256:def456..."
}

Task Completed:

{
  "type": "task_completed",
  "taskId": "uuid",
  "success": true,
  "result": {
    "imageId": "sha256:abc123..."
  }
}

Dashboard Metrics Stream

Endpoint: WS /api/v1/dashboard/stream

Streams real-time dashboard metrics and alerts.

Message Types (Server to Client)

Metric Update:

{
  "type": "metric_update",
  "metrics": {
    "pipelineStatus": [
      { "environmentId": "uuid", "name": "Production", "health": "healthy" }
    ],
    "pendingApprovals": 3,
    "activeDeployments": 1,
    "recentReleases": 12,
    "systemHealth": {
      "agentsOnline": 8,
      "agentsTotal": 10,
      "queueDepth": 5
    }
  },
  "timestamp": "2026-01-10T14:23:45Z"
}

Alert:

{
  "type": "alert",
  "alert": {
    "id": "uuid",
    "severity": "warning",
    "title": "Deployment Failed",
    "message": "Deployment to Production failed: health check timeout",
    "resourceType": "deployment",
    "resourceId": "uuid",
    "timestamp": "2026-01-10T14:23:45Z"
  }
}

Promotion Update:

{
  "type": "promotion_update",
  "promotion": {
    "id": "uuid",
    "releaseName": "myapp-v2.3.1",
    "targetEnvironment": "Production",
    "status": "awaiting_approval",
    "requestedBy": "John Doe"
  }
}

Connection Management

Reconnection

Clients should implement exponential backoff reconnection:

const connect = (retryCount = 0) => {
  const ws = new WebSocket(url);

  ws.onclose = () => {
    const delay = Math.min(1000 * Math.pow(2, retryCount), 30000);
    setTimeout(() => connect(retryCount + 1), delay);
  };

  ws.onopen = () => {
    retryCount = 0;
  };
};

Heartbeat

WebSocket connections receive periodic heartbeat messages:

{
  "type": "heartbeat",
  "timestamp": "2026-01-10T14:23:45Z"
}

Clients should respond with:

{
  "type": "pong"
}

Connections without pong response within 30 seconds are terminated.


Error Messages

{
  "type": "error",
  "code": "unauthorized",
  "message": "Token expired",
  "timestamp": "2026-01-10T14:23:45Z"
}
Error Code Description
unauthorized Invalid or expired token
forbidden No access to resource
not_found Resource not found
rate_limited Too many connections
internal_error Server error

See Also