Template: customer onboarding (Operations)

Document information
  • Canonical URL: /docs/12_workflows/40_template-customer-onboarding
  • Version: 2026-10-02
  • Tags: operations, processflow, template, guides

Copyable ProcessFlow pattern for a customer onboarding journey that feeds My Work. This is documentation for tenant admins and Trace — it does not insert demo requests into employee queues. Clone the steps in ProcessFlow, connect real integrations, then run with real or sandbox input you choose.

Outcome

An employee sees a My Work card, understands why they are involved, Approves a real gate, and the process writes back to CRM. Failures open an Exception card with Retry when input was stored.

Process shape

StepKindOperations write
1. IntakeAutomaticupdateProgress — journey_beat: received
2. Enrich from CRMAutomaticupdateProgress — checks + system_refs
3. AI document skim (optional)AI-assistedupdateProgress with ai_summary
4. Credit / risk decisionHuman approvalopenApproval with human_request_id
5. Activate in CRMAutomaticupdateProgress — journey_beat: systems
6. Failure handlerExceptionopenException
7. FinishAutomaticcomplete

Set process category to business.

Stable identity

const external_id = `crm-onboarding-${customer_id}`;

Reuse the same external_id on every upsert so My Work updates one card.

Step sketches

Progress after enrich

await tf.operations.updateProgress({
  external_id,
  subject: `Onboard ${customer_name}`,
  party: customer_name,
  process_name: "Customer onboarding",
  status: "open",
  attention: "info",
  journey_beat: "in_process",
  journey_stage_label: "Documents checked",
  checks: [
    { label: "Company registration", state: "verified" },
    { label: "Credit pack", state: "pending" }
  ],
  system_refs: [{ system: "CRM", label: "Account", external_ref: customer_id }]
});

Open approval (after human-input pause)

await tf.operations.openApproval({
  external_id,
  subject: `Approve onboarding for ${customer_name}`,
  party: customer_name,
  process_name: "Customer onboarding",
  human_request_id: String(pending_human_request_id),
  why_visible: "You own customer activation for this region.",
  consequence: "Approving activates the account in CRM and continues provisioning.",
  required_action: "Confirm credit pack and approve or reject.",
  journey_beat: "in_process",
  journey_stage_label: "Activation decision",
  actor_hint: "person"
});

Exception

await tf.operations.openException({
  external_id,
  subject: `Onboarding blocked for ${customer_name}`,
  process_name: "Customer onboarding",
  required_action: "Fix the CRM write error, then Retry or Pass to Delivery.",
  why_visible: "Activation failed in CRM after approval.",
  journey_beat: "systems"
});

Complete

await tf.operations.complete({
  external_id,
  subject: `Onboarded ${customer_name}`,
  process_name: "Customer onboarding"
});

Verify before go-live

  1. tf.operations.validate({ … attention: "approval", human_request_id: "…" }) → approve_buttons_would_show: true
  2. Run once with a test account; open My Work as the intended owner
  3. Confirm Approve resumes the process and CRM updates
  4. Force a failure path and confirm Exception copy (no raw stack on the primary panel)

Related