feat(queue): Messages-dashboard met realtime SSE + JP-acties (PBI-5) #18

Merged
janpeter merged 1 commit from feat/queue-messages-dashboard into main 2026-05-31 12:33:42 +02:00
Owner

Wat

PBI-5 uit s4m-queue verbeterronde 2026-Q2 (sprint S-2026-05-31-1). Verhuist de Messages-pagina van Ops-dashboard naar scrum4me-workers en bouwt 'm uit met realtime SSE-stream + JP-acties (push / reply / cancel / requeue) via iron-session server actions.

Data-toegang via het bestaande Worker Insights pattern: kale pg.Pool op OPS_DATABASE_URL, app-name scrum4me-workers-queue. Géén AgentMessage Prisma-model in shared — die tabel is eigendom van Ops-dashboard (per ADR uit de plan-fase).

Wijzigingen

lib/queue/types.ts

Identity-allowlists, types, validateTaskMeta. Spiegelt s4m-queue/src/types.ts maar staat hier los (workers heeft geen shared-package import voor queue). SERVERS = ['mac','scrum4me-server','max2'], MODELS = ['claude','codex','jp'] — lopen mee met PBI-1 in s4m-queue.

lib/queue/ops-db.ts

  • getQueuePool() — pg.Pool met max: 3, idleTimeoutMillis: 10_000, connectionTimeoutMillis: 5_000, statement_timeout: 8_000, gecached via globalThis (zoals lib/worker-insights/ops-db.ts:8).
  • Typed wrappers: listAgentMessages, getAgentMessage, pushAgentMessage, cancelAgentMessage, requeueAgentMessage, failAgentMessage, replyToAgentMessage.
  • NOTIFY-payloads compatibel met de PBI-2 envelope-shape (id/type/from_*/to_*/in_reply_to/status/previous_status). mutateWithNotify helper voor cancel/requeue/fail; replyToAgentMessage emit twee NOTIFYs (nieuwe reply-rij + request-close), analoog aan s4m-queue/src/db.ts → doneWithReply in PR #3.

app/(app)/queue/messages/page.tsx

Server component, requireWorkersAdmin (layout doet 't ook, hier extra defense-in-depth). Toont waarschuwing als OPS_DATABASE_URL ontbreekt.

app/(app)/queue/messages/_components/messages-view.tsx

Client component:

  • Filters: server, model, type, status (incl. stale preset → vastzittende claims via claimed AND claimed_at < now() - 4h).
  • Tabel + detail-panel (body, meta, latency claim/total, reply-keten).
  • Push-form met meta.task velden bij task/review_request.
  • Reply-form op detail-panel voor pending/claimed verzoeken.
  • SSE-listener herlaadt bij elk binnenkomend event; 10s-poll als safety-net.

app/api/queue/messages/stream/route.ts

SSE-route. Dedicated pg.Client, LISTEN agent_queue, robust cleanup via bestaande lib/realtime/pg-client-cleanup.ts, 25s heartbeat.

actions/queue-messages.ts

'use server' actions met requireWorkersAdmin + validateTaskMeta:

  • refreshMessagesAction(filter) — list met optioneel stale preset.
  • pushMessageAction(input) — push (dashboard-afzender uit env: default mac:jp).
  • cancelMessageAction(id), requeueMessageAction(id).
  • replyMessageAction(id, body) — doneWithReply met dubbele NOTIFY.

Geen --as-flag, geen impersonatie; alle write-acties achter de iron-session.

Verify

npm run verify (lint + typecheck + vitest) → 305 / 305 groen.

Afhankelijkheden

  • Runtime: OPS_DATABASE_URL env-var moet wijzen naar de ops_dashboard-DB met SELECT/INSERT/UPDATE op agent_message.
  • PBI-2 NOTIFY-helper (s4m-queue#3) is nodig voor volledige SSE-coverage (status-overgangen). De dashboard zelf gebruikt al de uitgebreide envelop-shape; pre-PBI-2 berichten missen alleen status/previous_status velden — niet kritiek.
  • Geen schema-wijziging in scrum4me-shared.

Niet in deze PR

  • Ops-dashboard messages-pagina disable — hoort in Ops-dashboard repo, niet hier. Plan: feature-flag of route-disable na merge + workers-deploy.
  • Per-user filtering op de SSE-stream (alle events naar de client; client filtert). Hangt op de JP-routing in v3 (VAPID-plan).

🤖 Gegenereerd met Claude Opus 4.7 (1M context)

## Wat PBI-5 uit s4m-queue verbeterronde 2026-Q2 (sprint `S-2026-05-31-1`). Verhuist de Messages-pagina van Ops-dashboard naar `scrum4me-workers` en bouwt 'm uit met **realtime SSE-stream** + **JP-acties** (push / reply / cancel / requeue) via iron-session server actions. Data-toegang via het bestaande **Worker Insights pattern**: kale `pg.Pool` op `OPS_DATABASE_URL`, app-name `scrum4me-workers-queue`. Géén `AgentMessage` Prisma-model in shared — die tabel is eigendom van Ops-dashboard (per ADR uit de plan-fase). ## Wijzigingen ### `lib/queue/types.ts` Identity-allowlists, types, `validateTaskMeta`. Spiegelt s4m-queue/src/types.ts maar staat hier los (workers heeft geen shared-package import voor queue). `SERVERS = ['mac','scrum4me-server','max2']`, `MODELS = ['claude','codex','jp']` — lopen mee met PBI-1 in s4m-queue. ### `lib/queue/ops-db.ts` - `getQueuePool()` — pg.Pool met `max: 3, idleTimeoutMillis: 10_000, connectionTimeoutMillis: 5_000, statement_timeout: 8_000`, gecached via `globalThis` (zoals `lib/worker-insights/ops-db.ts:8`). - Typed wrappers: `listAgentMessages`, `getAgentMessage`, `pushAgentMessage`, `cancelAgentMessage`, `requeueAgentMessage`, `failAgentMessage`, `replyToAgentMessage`. - NOTIFY-payloads compatibel met de PBI-2 envelope-shape (`id/type/from_*/to_*/in_reply_to/status/previous_status`). `mutateWithNotify` helper voor cancel/requeue/fail; `replyToAgentMessage` emit twee NOTIFYs (nieuwe reply-rij + request-close), analoog aan `s4m-queue/src/db.ts → doneWithReply` in PR #3. ### `app/(app)/queue/messages/page.tsx` Server component, `requireWorkersAdmin` (layout doet 't ook, hier extra defense-in-depth). Toont waarschuwing als `OPS_DATABASE_URL` ontbreekt. ### `app/(app)/queue/messages/_components/messages-view.tsx` Client component: - Filters: server, model, type, status (incl. `stale` preset → vastzittende claims via `claimed AND claimed_at < now() - 4h`). - Tabel + detail-panel (body, meta, latency claim/total, reply-keten). - Push-form met `meta.task` velden bij `task`/`review_request`. - Reply-form op detail-panel voor pending/claimed verzoeken. - SSE-listener herlaadt bij elk binnenkomend event; 10s-poll als safety-net. ### `app/api/queue/messages/stream/route.ts` SSE-route. Dedicated `pg.Client`, `LISTEN agent_queue`, robust cleanup via bestaande `lib/realtime/pg-client-cleanup.ts`, 25s heartbeat. ### `actions/queue-messages.ts` `'use server'` actions met `requireWorkersAdmin` + `validateTaskMeta`: - `refreshMessagesAction(filter)` — list met optioneel `stale` preset. - `pushMessageAction(input)` — push (dashboard-afzender uit env: default `mac:jp`). - `cancelMessageAction(id)`, `requeueMessageAction(id)`. - `replyMessageAction(id, body)` — doneWithReply met dubbele NOTIFY. Geen `--as`-flag, geen impersonatie; alle write-acties achter de iron-session. ## Verify `npm run verify` (lint + typecheck + vitest) → **305 / 305 groen**. ## Afhankelijkheden - **Runtime**: `OPS_DATABASE_URL` env-var moet wijzen naar de `ops_dashboard`-DB met SELECT/INSERT/UPDATE op `agent_message`. - **PBI-2 NOTIFY-helper** ([s4m-queue#3](https://git.jp-visser.nl/janpeter/s4m-queue/pulls/3)) is nodig voor volledige SSE-coverage (status-overgangen). De dashboard zelf gebruikt al de uitgebreide envelop-shape; pre-PBI-2 berichten missen alleen `status`/`previous_status` velden — niet kritiek. - Geen schema-wijziging in `scrum4me-shared`. ## Niet in deze PR - **Ops-dashboard messages-pagina disable** — hoort in Ops-dashboard repo, niet hier. Plan: feature-flag of route-disable na merge + workers-deploy. - **Per-user filtering** op de SSE-stream (alle events naar de client; client filtert). Hangt op de JP-routing in **v3** (VAPID-plan). 🤖 Gegenereerd met Claude Opus 4.7 (1M context)
PBI-5 uit sprint S-2026-05-31-1 (Scrum4Me product: scrum4me-workers,
product_id cmpn8hd5k0000pg7rkwxr77rw). Verhuist de Messages-pagina
van Ops-dashboard naar scrum4me-workers en bouwt het uit met
realtime SSE-stream + JP-acties (push / reply / cancel / requeue) via
iron-session-server-actions.

Data-toegang via het bestaande Worker Insights pattern:
`lib/queue/ops-db.ts` met kale `pg.Pool` op `OPS_DATABASE_URL`,
app-name `scrum4me-workers-queue`. Geen `AgentMessage` Prisma-model
in shared — die tabel is eigendom van Ops-dashboard.

- lib/queue/types.ts: identity-allowlists (SERVERS incl max2, MODELS
  incl jp), types, taskMeta-validator. SOT spiegelt s4m-queue/src/types.ts.
- lib/queue/ops-db.ts: pg.Pool helper + typed wrappers (list / get /
  push / cancel / requeue / fail / reply). NOTIFY-payloads compatibel
  met PBI-2 envelop-shape (id/type/from_*/to_*/in_reply_to/status/
  previous_status). doneWithReply doet 2 NOTIFYs (reply-row + request-
  close), analoog aan PBI-2.
- app/(app)/queue/messages/page.tsx: server component met
  requireWorkersAdmin (layout doet dat al, hier extra guard), initial
  list, render MessagesView.
- app/(app)/queue/messages/_components/messages-view.tsx: client
  component met filters (server + model + type + status incl 'stale'
  preset voor vastzittende claims), tabel + detail-panel met body /
  meta / latency, push-form (incl meta.task velden bij task /
  review_request) en reply-form.
- app/api/queue/messages/stream/route.ts: SSE met dedicated pg.Client,
  LISTEN agent_queue, robust cleanup via closePgClientSafely,
  25s heartbeat tegen reverse-proxy timeouts.
- actions/queue-messages.ts: 'use server' actions met requireWorkersAdmin
  + validateTaskMeta. Dashboard-afzender mac:jp (override via env
  S4M_DASHBOARD_SERVER / S4M_DASHBOARD_MODEL); geen --as-impersonatie.

Verify: lint + typecheck + 305/305 tests groen.

Niet in deze PR:
- Ops-dashboard messages-pagina disable: hoort in Ops-dashboard repo,
  niet hier.
- Per-user filtering op de SSE-stream (alle events naar de client;
  client kan zelf filteren). Hangt op JP-routing in v3.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
janpeter/scrum4me-workers!18
No description provided.