Flows YAML — REST CRUD endpoints + SSE flow.changed broadcast #1070

Closed
opened 2026-05-10 15:38:53 +00:00 by claude-desktop · 0 comments
Collaborator

User story

As the dashboard, I want a complete REST surface for listing, reading, creating, updating, deleting, disabling, dry-running, and reloading flows, plus an SSE channel for change notifications, so that the editor can manage flow files without ssh-ing into the host.

Acceptance criteria

Endpoints (in apps/server/src/http/flows-yaml-routes.ts)

  • GET /flows — list with {name, source, trigger_summary, enabled, mtime}.
  • GET /flows/:name — raw YAML text + parsed metadata + last-run summary.
  • POST /flows — create under flows/custom/. 409 if name exists.
  • PUT /flows/:name — update. Body includes expected_mtime; mismatch → 409 with current contents.
  • DELETE /flows/:name — 409 if source: "default"; otherwise remove file.
  • POST /flows/:name/disable — toggle enabled: false overlay (flows/custom/.disabled.json).
  • POST /flows/:name/dry-run — synthetic event input; per-step trace; no side effects.
  • POST /flows/reload — full re-scan.
  • GET /flows/runs — recent runs across all flows (paginated).
  • GET /flows/runs/:id — single run trace.
  • GET /schemas/flows.schema.json — served from apps/web/public/schemas/.

Default-fork behavior

  • PUT /flows/:name on a source: "default" flow writes a copy to flows/custom/<name>.yml and serves the custom version thereafter.
  • DELETE /flows/:name on a custom-shadowed default removes the custom file (resets to factory).

SSE

  • flow.changed { name, source, mtime } broadcast on every file watcher event and successful CRUD write.
  • All open editors receive it; client decides whether to refresh.

Auth + audit

  • All endpoints gated by existing dashboard auth.
  • Each write logs operator id + diff summary to existing audit log.

Tests

  • CRUD round-trip; mtime conflict; default-fork; default-delete-resets.
  • Dry-run produces deterministic trace and writes nothing to flow_runs.

Out of scope

  • Frontend (covered by #flows-11..13).
  • Git commit-and-push button (deferred; spec §10.3.7).

References

  • Spec: docs/specs/flows-yaml.md §10.3.5, §10.3.7.
## User story As the dashboard, I want a complete REST surface for listing, reading, creating, updating, deleting, disabling, dry-running, and reloading flows, plus an SSE channel for change notifications, so that the editor can manage flow files without ssh-ing into the host. ## Acceptance criteria ### Endpoints (in `apps/server/src/http/flows-yaml-routes.ts`) - [ ] `GET /flows` — list with `{name, source, trigger_summary, enabled, mtime}`. - [ ] `GET /flows/:name` — raw YAML text + parsed metadata + last-run summary. - [ ] `POST /flows` — create under `flows/custom/`. 409 if name exists. - [ ] `PUT /flows/:name` — update. Body includes `expected_mtime`; mismatch → 409 with current contents. - [ ] `DELETE /flows/:name` — 409 if `source: "default"`; otherwise remove file. - [ ] `POST /flows/:name/disable` — toggle `enabled: false` overlay (`flows/custom/.disabled.json`). - [ ] `POST /flows/:name/dry-run` — synthetic event input; per-step trace; no side effects. - [ ] `POST /flows/reload` — full re-scan. - [ ] `GET /flows/runs` — recent runs across all flows (paginated). - [ ] `GET /flows/runs/:id` — single run trace. - [ ] `GET /schemas/flows.schema.json` — served from `apps/web/public/schemas/`. ### Default-fork behavior - [ ] `PUT /flows/:name` on a `source: "default"` flow writes a copy to `flows/custom/<name>.yml` and serves the custom version thereafter. - [ ] `DELETE /flows/:name` on a custom-shadowed default removes the custom file (resets to factory). ### SSE - [ ] `flow.changed { name, source, mtime }` broadcast on every file watcher event and successful CRUD write. - [ ] All open editors receive it; client decides whether to refresh. ### Auth + audit - [ ] All endpoints gated by existing dashboard auth. - [ ] Each write logs operator id + diff summary to existing audit log. ### Tests - [ ] CRUD round-trip; mtime conflict; default-fork; default-delete-resets. - [ ] Dry-run produces deterministic trace and writes nothing to `flow_runs`. ## Out of scope - Frontend (covered by #flows-11..13). - Git commit-and-push button (deferred; spec §10.3.7). ## References - Spec: `docs/specs/flows-yaml.md` §10.3.5, §10.3.7.
Sign in to join this conversation.
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
charles/claude-hooks#1070
No description provided.