From d13beb7a2a646b226636e04d39ec1cf58822950a Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 1 Nov 2026 04:16:19 +0000 Subject: [PATCH] fix(automation): describe the HTTP and approval flow nodes in business words The node description and config help are the Studio flow palette and node-card text an admin reads. Rewrite the HTTP node's description and its method / durable / timeoutMs / signingSecret / body help, and the approval node's description, in business words; the outbox, HMAC, literal and CEL detail moves to code comments beside each entry. Copy only: no key, type, default or behaviour change. Claude-Session: https://claude.ai/code/session_01FEkQ5oZiDbKQCsyey7KM7z Co-authored-by: Claude --- .../28234-flow-node-help-business-words.md | 17 ++++++++ .../plugin-approvals/src/approval-node.ts | 7 +++- .../src/builtin/http-node-signing.test.ts | 7 ++-- .../src/builtin/http-nodes.ts | 41 +++++++++++++++---- 4 files changed, 58 insertions(+), 14 deletions(-) create mode 100644 .changeset/28234-flow-node-help-business-words.md diff --git a/.changeset/28234-flow-node-help-business-words.md b/.changeset/28234-flow-node-help-business-words.md new file mode 100644 index 00000000000..5ea8eb2df66 --- /dev/null +++ b/.changeset/28234-flow-node-help-business-words.md @@ -0,0 +1,17 @@ +--- +'@objectstack/service-automation': patch +'@objectstack/plugin-approvals': patch +--- + +Clause-②: no +Metadata-protocol: none + +The HTTP and approval flow nodes now describe themselves in business words. The node description and +config help are the text the Studio flow palette and node cards show an admin, and the HTTP node's +spoke of the messaging outbox, retry / dead-letter, an HMAC-SHA256 secret, "a literal, read as +written" and a CEL value envelope; the approval node's said it "suspends the flow". The HTTP node now +reads "Send a request to an outside web service: wait for its answer, or hand it off to be delivered +in the background with automatic retries", with plain help for the request kind, background delivery, +the wait time, the signing secret and what to send; the approval node reads "Ask people to approve or +reject a record". The engineer detail moved to code comments beside each entry. No key, type, default, +accepted value or behaviour changed. diff --git a/packages/plugins/plugin-approvals/src/approval-node.ts b/packages/plugins/plugin-approvals/src/approval-node.ts index e972e15b693..faae7ee86d6 100644 --- a/packages/plugins/plugin-approvals/src/approval-node.ts +++ b/packages/plugins/plugin-approvals/src/approval-node.ts @@ -135,8 +135,11 @@ export function registerApprovalNode( type: APPROVAL_NODE_TYPE, version: '1.0.0', name: 'Approval', - description: 'Route a record for human approval; suspends the flow until a decision, ' - + 'then continues down the approve / reject branch.', + // Palette and node-card text an admin reads, in business words. The run + // suspends here until a decision, then resumes down the `approve` / + // `reject` edge (see `resumeAuthority` below). + description: 'Ask people to approve or reject a record. The flow waits for their decision, ' + + 'then continues down the approve or reject path.', icon: 'check-circle', category: 'human', paradigms: ['flow'], diff --git a/packages/services/service-automation/src/builtin/http-node-signing.test.ts b/packages/services/service-automation/src/builtin/http-node-signing.test.ts index 87445691e0c..f50a593aa4e 100644 --- a/packages/services/service-automation/src/builtin/http-node-signing.test.ts +++ b/packages/services/service-automation/src/builtin/http-node-signing.test.ts @@ -19,9 +19,10 @@ import { registerHttpNodes } from './http-nodes.js'; * wire, on EVERY arm the node can take. * * The key is declared without qualification — `HttpConfigSchema.signingSecret` - * and the descriptor's `configSchema` both read "HMAC-SHA256 secret → - * X-Objectstack-Signature" — yet only the durable arm used to hand it to - * anything that signs (the messaging outbox). The inline arm, and the durable + * reads "HMAC-SHA256 secret → X-Objectstack-Signature", and the descriptor's + * `configSchema` says it signs each request — yet only the durable arm used + * to hand it to anything that signs (the messaging outbox). The inline arm, + * and the durable * arm's no-outbox fallback that degrades to it, built their `fetch` from * `headers` alone: the request went out unsigned and the run said * `success: true`. diff --git a/packages/services/service-automation/src/builtin/http-nodes.ts b/packages/services/service-automation/src/builtin/http-nodes.ts index 3b72e5b6533..dba06b391eb 100644 --- a/packages/services/service-automation/src/builtin/http-nodes.ts +++ b/packages/services/service-automation/src/builtin/http-nodes.ts @@ -123,9 +123,15 @@ export function registerHttpNodes(engine: AutomationEngine, ctx: PluginContext): type: HTTP_TYPE, version: '1.0.0', name: 'HTTP', + // The description and the config help below are the Studio flow + // palette and node-card text an admin reads, so they speak business + // words. The engineer detail they used to carry lives here: with + // `durable: true` the call is enqueued on the messaging HTTP outbox + // (retry / dead-letter) and the run does not see the response; + // otherwise it runs inline and returns the response. description: - 'Call an external HTTP endpoint. With `durable: true`, the call is enqueued on the ' - + 'messaging outbox with retry / dead-letter; otherwise it runs inline and returns the response.', + 'Send a request to an outside web service: wait for its answer, or hand it off to be ' + + 'delivered in the background with automatic retries.', icon: 'globe', category: 'io', source: 'builtin', @@ -166,9 +172,13 @@ export function registerHttpNodes(engine: AutomationEngine, ctx: PluginContext): + 'path is the secret: call the service through a token-authenticated connector instead, such ' + 'as the `slack` connector with its bot token.', }, + // `method` is a literal, read as written (#19939): no `{{ }}` + // rendering. Default `GET`; `POST` when `durable` is true. method: { type: 'string', - description: 'HTTP method (default GET; POST when durable) — a literal, read as written', + description: + 'The kind of request, such as GET or POST. GET by default; POST when the request is ' + + 'delivered in the background.', }, headers: { type: 'object', @@ -180,19 +190,32 @@ export function registerHttpNodes(engine: AutomationEngine, ctx: PluginContext): + 'authenticated upstream through a `connector_action` on a declarative connector whose ' + '`auth.credentialRef` names the secret.', }, + // `body` is JSON-serialised: a CEL value envelope + // `{ dialect: 'cel', source }` evaluated per run to the payload, + // or a literal sent as written. body: { - description: - 'Request body (JSON-serialised) — a CEL value envelope `{ dialect: \'cel\', source }` ' - + 'evaluated per run to the payload, or a literal sent as written', + description: 'What to send, as JSON: a fixed value, or an expression worked out on each run.', }, + // `durable: true` is fire-and-forget through the messaging HTTP + // outbox (retry / dead-letter) instead of an inline + // request / response. durable: { type: 'boolean', - description: 'Fire-and-forget via the durable outbox (retry/dead-letter) instead of inline request/response', + description: + 'Deliver the request in the background and keep retrying if it fails, instead of ' + + 'waiting for the answer; the flow does not see the response.', }, - timeoutMs: { type: 'number', description: 'Per-request timeout (ms)' }, + // Per-request timeout in milliseconds, on both arms; a literal + // number, read as written. + timeoutMs: { type: 'number', description: 'How long to wait for an answer, in milliseconds.' }, + // The HMAC-SHA256 secret that signs the request body into the + // `X-Objectstack-Signature` header, on every arm; the secret + // itself, read as written (`''` sends unsigned on purpose). signingSecret: { type: 'string', - description: 'HMAC-SHA256 secret → X-Objectstack-Signature — the secret itself, read as written', + description: + 'A shared secret used to sign each request, so the receiving service can check it came ' + + 'from you (sent as the X-Objectstack-Signature header).', }, }, },