feat(service,features): a workspace's automations and an automation's runs are live reads

Merged
CH
9d ago
+825-45

Stack 2 · Task list and automations, piece 5. Stacked on #3284 (luke/neon-realtime-agent-notices).

New live reads on the central live layer:

  • live.automations (GET /api/live/automations?workspaceId=) returns every automation in the workspace the account can read. Each comes with its newest run (a lateral join), that run's agent, and the inputs to the agent's status.
  • live.automationRuns (GET /api/live/automation-runs?id=) returns the automation's newest 50 runs, after reading the automation as the account. An automation the account can't read answers not-found.

Both work like every other live read: each names the account it's read for (sameUser), and polls with Realtime off.

Shared fragments in packages/service/src/live/agent-standing.ts, also used by the task list:

  • the newest turn;
  • the newest awaiting line;
  • the failure word, which is named in SQL so a turn's detail never leaves the database.

Repositories: an automation with no repositories of its own falls back to its task's repository on the reader side, because jsonb_build_array isn't immutable.

Assembly: @luke/features/automation-live builds the held list and history at an instant. The host uses it in the next PR.

Tests:

  • Parity, run as raw SQL against the app's held list and runs routes.
  • mutableFunctionsOf on both statements.
  • The endpoints.