Skip to Content
Fusee Docs
Guides

Waiting for people

A refund over a limit needs a manager. An expense needs finance. A contract waits for a signature. The run asks, waits (minutes or weeks, at no cost while it waits), and continues when the answer comes.

A signal and a timeout

const decision = signal("decision");

const expense = workflow("expense", async (ctx, claim) => {
  await ctx.step("ask", () => mail.send(finance, approvalLink(ctx.workflowId)));
  const answer = await ctx.waitFor(decision, { timeout: "3d" });
  if (answer === undefined) return "expired";
  if (!answer.approved) return `rejected by ${answer.by}`;
  return ctx.step("pay", (s) => payments.reimburse(claim, s.key));
});

// The approval page's handler, any process, any time later:
await engine.run("expense-7").signal(decision, { approved: true, by: "dana" });

While it waits, the run is parked: nothing of it is in memory, and a restart or a deploy changes nothing. A signal that arrives before the code reaches waitFor is kept and taken when it gets there. fusee runs signal expense-7 decision '{"approved": true, "by": "dana"}' and the UI's Signal button send the same signal, and both record who sent it (audit).

When the answer comes from a system that only knows how to call a URL (an e-signature service, a payment page), wait on a completion instead:

const signed = await ctx.awaitCompletion("signature", (cb) => esign.send(contract, { webhook: cb.url }));

cb.url completes that step when something POSTs the value to it (…/v1/fail/<token> fails it). The URL is unguessable, names the run, step and attempt, and stops working once used.

Showing where a run is

A query answers from the run's state without changing it:

ctx.onQuery("status", () => (answered ? "decided" : "waiting for finance"));
const status = await engine.run("expense-7").query("status");

Reminders are a sleep in a loop with the wait: ctx.sleep("remind-1", "1d") raced against the signal with ctx.race. Escalation is a second wait with a new approver. Each is a few lines of ordinary code, recorded step by step.

The human approval example runs in five languages.

On this page