Human approval gate
Persist, request review, pause the exact execution, then approve or reject through a separate validated webhook.
NEEDS_APPROVAL → HANDOFF_SENT
Portfolio case study · executable demo
An n8n reference implementation for validated intake, explainable scoring, human approval, CRM-neutral persistence, retries, audit, and safe channel handoff — with zero paid API dependencies.
lead_mg5qk2_1x9a2bThe problem
A webhook-to-CRM shortcut looks efficient until malformed payloads, duplicates, noisy alerts, approval ambiguity, or a failing downstream API appears. The workflow must preserve a lead even when the happy path stops.
Architecture
POST /demo-lead422 on invalidlead_id + UTC3 match rules0—100Persist, request review, pause the exact execution, then approve or reject through a separate validated webhook.
NEEDS_APPROVAL → HANDOFF_SENT
Write the qualified lead first, acknowledge the intake, then resume after a configurable delay.
FOLLOW_UP_SCHEDULED
Keep the record and audit trail without generating an immediate sales notification.
STORED
Deterministic intelligence
The Code node produces a readable summary, recommendation, and evidence list. Every point can be traced to a rule; a local LLM can be added later without becoming a critical dependency.
“Anna Petrova from Northwind Dental wants WhatsApp automation. Budget: 500. Recommended action: review and contact within 15 minutes.”
Failure handling
Integration nodes retry three times with a fixed delay. Permanent failures stop retrying and move to a named terminal state.
Correlation ID, failed step, error message, retry count, and the persisted lead remain available for diagnosis and replay.
RECEIVED through FAILED events use one portable schema: timestamp, lead ID, step, status, and message.
Unexpected automatic-execution failures enter a separate workflow with execution and last-node context.
Implementation evidence
Test matrix
| Case | Score | Tier | Expected terminal state | Coverage |
|---|---|---|---|---|
| A Complete high-intent lead | 100 | HOT | HANDOFF_SENT | approval + adapters |
| B Qualified without budget | 50 | WARM | FOLLOW_UP_SCHEDULED | wait + follow-up |
| C Low-context request | 0 | COLD | STORED | quiet persistence |
| D Missing contact + message | — | — | VALIDATION_FAILED | 422 + audit |
| E Repeated email / phone | — | — | DUPLICATE | existing lead ID |
| F Permanent handoff failure | 100 | HOT | DEAD_LETTER | retry × 3 + recovery |
npm testworkflow shape · fixtures · mock API · links · secret scanProduction adapters
The orchestration contract remains stable. Each local boundary can be replaced independently without rewriting qualification or approval logic.
File-backed lookup and upsert
→ HubSpot · Airtable · SheetsTelegram, WhatsApp, email blocks
→ credentialed production nodesPortable event contract
→ database · stream · SIEMReplayable failure payload
→ queue · incident workflowSource package
Workflow exports, local infrastructure, fixtures, documentation, and verification scripts are available in the repository.