Skip to main content

Task dashboard workflow (snapshot + SSE)

This document describes the dashboard API/runtime in alakai (backend) built on top of Redis task tracking. The Next.js UI lives in the separate alakai-dashboard repository.

Scope

  • Snapshot reads for current task status list views.
  • Realtime no-polling updates via SSE.
  • Available project list endpoint for dashboard filters.
  • Mandatory Google-authenticated access to dashboard routes.
  • Optional strict visibility filtering based on creator/responsible users.

Runtime topology

Dashboard runtime is always active:

  1. RedisTaskDashboardReadService reads projected latest-state task records from Redis.
  2. RedisTaskTrackingStreamTailer tails task-events:v1 (XREAD, blocking).
  3. TaskDashboardUpdatesHub keeps bounded replay and fanouts updates to subscribers.
  4. HTTP routes expose:
    • GET /dashboard/projects
    • GET /dashboard/tasks
    • GET /dashboard/tasks/stream (text/event-stream)
Redis Stream (task-events:v1)

├─> RedisTaskStatusProjector -> Redis latest-state hashes + project ZSET

└─> RedisTaskTrackingStreamTailer -> TaskDashboardUpdatesHub -> SSE clients

Redis read model used by dashboard

  • Per execution hash: task-tracking:execution:{executionId}
  • Per project ordered index: task-tracking:project:{project}:executions
    • score: occurredAt timestamp (ms)
    • value: executionId

Available projects endpoint

GET /dashboard/projects

  • Returns configured projects (each with their applications) for dashboard filtering:
{
"items": [
{
"project": "rukipay",
"displayName": "Rukipay",
"applications": [
{ "app": "rukipay-backend", "repo": "houlak/rukipay-backend" }
]
}
]
}
  • Source of truth is the projects workflow config loaded at runtime (S3 with file fallback if configured that way).
  • Note: task events (the /dashboard/tasks snapshot below) still key their project field by owner/repo, not by the project slug — the two endpoints expose different identifiers.
  • Requires authenticated viewer (returns 401 dashboard_unauthorized when missing/invalid auth).

Snapshot endpoint

GET /dashboard/tasks

Query params:

  • project (recommended for practical queries)
  • statuses (comma-separated or repeated array values)
  • cursor (opaque cursor for pagination)
  • limit
  • authToken (optional Google ID token fallback; Authorization: Bearer preferred)

Response:

{
"items": [
{
"executionId": "...",
"taskName": "...",
"status": "in_progress|success|error",
"project": "owner/repo",
"occurredAt": "ISO-8601",
"flow": "...",
"actor": { "provider": "slack|github", "id": "..." },
"prLinks": [],
"visibility": { "responsibleUsers": [] },
"lastEventId": "<redis-stream-id>"
}
],
"nextCursor": "..."
}

Realtime endpoint

GET /dashboard/tasks/stream

  • Content type: text/event-stream
  • Supports resume via:
    • Last-Event-ID header
    • cursor query
  • Supports authToken query fallback for EventSource/browser environments where custom Authorization headers are not practical.

Event types:

  • task_status_updated
  • snapshot_refresh_required
  • keepalive

If a cursor cannot be replayed from the in-memory replay window, the server emits snapshot_refresh_required and the client should reload snapshot.

Auth boundary (mandatory Google auth)

Dashboard routes require an authenticated viewer.

Token inputs:

  • Preferred: Authorization: Bearer <google_id_token>
  • SSE/browser fallback: authToken query param

Identity resolution:

  • google:{email} when verified email is available
  • google-sub:{sub} fallback

When identity cannot be resolved, routes return:

  • HTTP 401
  • error: "dashboard_unauthorized"

Visibility model

Visibility behavior is controlled by TASK_DASHBOARD_ENFORCE_VISIBILITY:

  • false (default): all tasks are visible to authenticated viewers.
  • true: access allowed only when:
    1. Viewer identity matches task creator ({provider}:{id}), or
    2. Viewer identity appears in visibility.responsibleUsers.

Operational guidance

Required env

  • TASK_TRACKING_REDIS_URL
  • TASK_DASHBOARD_GOOGLE_CLIENT_IDS

Optional env

  • TASK_DASHBOARD_HEARTBEAT_MS (default 15000)
  • TASK_DASHBOARD_REPLAY_LIMIT (default 200)
  • TASK_DASHBOARD_SNAPSHOT_DEFAULT_LIMIT (default 50)
  • TASK_DASHBOARD_SNAPSHOT_MAX_LIMIT (default 200)
  • TASK_DASHBOARD_ENFORCE_VISIBILITY (true | false, default false)

Local run

  1. Start backend: yarn dev
  2. Start dashboard UI in separate repo: cd ~/houlak_projects/alakai-dashboard && yarn dev
  3. Open http://localhost:5173

Build checks

  • Backend: yarn build
  • Dashboard (separate repo): cd ~/houlak_projects/alakai-dashboard && yarn build