Client Onboarding Pipeline
Module 16 · business · intermediate
report.js
// Collect what each step did. Every step runs with "On Error: Continue", so a failed step
// shows up here as { error } instead of stopping the whole onboarding.
// A step only counts as done if it returned an id: some nodes return an empty item instead of an error
// (ClickUp did, without credentials).
const plan = $('Check Registry').first().json;
const errText = (j) => (typeof j.error === 'string' ? j.error : j.error?.message ?? (j.error ? JSON.stringify(j.error) : null));
const done = (j) => !j.error && Boolean(j.id);
const why = (j) => errText(j) ?? 'no id returned (check the credential and the ids in Settings)';
const drive = $('Create Drive Folder').first().json;
const slack = $('Create Slack Channel').first().json;
const tasks = $('Create ClickUp Tasks').all().map((i) => i.json);
const email = $('Send Welcome Email').first().json;
const steps = [
{ step: 'drive_folder', ok: done(drive), detail: done(drive) ? drive.webViewLink ?? drive.id : why(drive) },
{ step: 'slack_channel', ok: done(slack), detail: done(slack) ? `#${slack.name ?? plan.channel_name}` : why(slack) },
{
step: 'clickup_tasks',
ok: tasks.length > 0 && tasks.every(done),
detail: `${tasks.filter(done).length}/${tasks.length} tasks created` + (tasks.find((t) => !done(t)) ? `; first problem: ${why(tasks.find((t) => !done(t)))}` : ''),
},
{ step: 'welcome_email', ok: done(email), detail: done(email) ? `sent to ${plan.contact_email}` : why(email) },
];
const status = steps.every((s) => s.ok) ? 'complete' : 'partial';
const db = $getWorkflowStaticData('global');
db.onboarded = db.onboarded ?? {};
db.onboarded[plan.slug] = { status, at: DateTime.now().toISO(), steps: steps.map((s) => `${s.step}:${s.ok ? 'ok' : 'failed'}`) };
return [{
json: {
status,
client_name: plan.client_name,
slug: plan.slug,
start_date: plan.start_date,
failed_steps: steps.filter((s) => !s.ok).map((s) => s.step),
steps,
},
}];