WorkestraDocs
Platform

Automations

Build cross-module workflows with the Visual Automation Builder — connect CRM, Finance, Projects, Support, and Recruiting with zero code.

Automations

The Automations module is Workestra's cross-module workflow engine. It lets you define if-this-then-that flows that span any combination of modules — trigger on a CRM deal, create a Finance invoice, notify a Support agent, and open a Project, all in one workflow.

This is not the same as Quick Rules (Settings → Quick Rules). Quick Rules are pre-configured on/off toggles. The Automations module is the full visual workflow builder where you can create custom multi-step flows.


Enabling Automations

The Visual Builder ships feature-flagged off. An admin enables it deployment-wide by setting two environment variables:

NEXT_PUBLIC_AUTOMATIONS_ENABLED=true
AUTOMATIONS_ENABLED=true

Effects of the flag:

StateSidebar entry/automations* routesEvent dispatch
Off (default)HiddenRender a 404No-op — events don't fire any workflows
OnVisibleRender normallyWorkflows fire on matching domain events

The cron sweep always processes any already-queued workflow_executions rows, so a workflow that was mid-run when the flag flipped off still completes.


Where to Find It

Automations is a top-level module in the sidebar — not buried under Settings.

LocationPathDescription
Workflows/automationsList of all workspace workflows
Visual Editor/automations/newCreate a new workflow
Edit Workflow/automations/[id]Edit an existing workflow
Templates/automations/templatesStart from a pre-built template
Runs/automations/runsCross-workflow execution history
Quick Rules/settings/automationsToggle pre-seeded simple rules (legacy surface)

Core Concepts

Workflow

A workflow is a saved automation with three parts:

Trigger  →  (optional Conditions)  →  Actions[]
ComponentWhat it is
TriggerThe event that starts the workflow
ConditionsOptional filters — the workflow only runs if all conditions are met
ActionsThe steps that execute in order when triggered

Status

StatusMeaning
DraftSaved but not active — won't fire on events
ActiveRunning — fires on every matching trigger
PausedTemporarily stopped — can be re-activated
ArchivedHidden from the list — no longer fires

Execution

When an active workflow matches a trigger, Workestra:

  1. Creates a workflow_executions row in pending status.
  2. Runs the actions in order, recording each step's outcome.
  3. Flips the execution to completed (or failed / paused depending on the workflow's error-handling strategy).

Runs are visible at /automations/runs with status, duration, and error details.


Available Triggers

Triggers are grouped by module. Wired triggers fire automatically when the corresponding domain event happens. Manual triggers fire only when you hit "Run now" or when the daily cron sweeps a matching scheduled workflow.

CRM

TriggerFires WhenAuto-fires?
Deal CreatedA new deal is created
Deal Stage ChangesAn opportunity moves to a new pipeline stage
Deal Closed WonA deal is marked as Closed Won
Contact CreatedA new contact is added

Projects

TriggerFires WhenAuto-fires?
Task Status ChangesA task's status is updated
Task CompletedA task is marked complete

Support

TriggerFires WhenAuto-fires?
Ticket CreatedA new support ticket is opened
Ticket EscalatedA ticket's priority is escalated
Ticket ResolvedA ticket is marked resolved

Finance

TriggerFires WhenAuto-fires?
Invoice PaidAn invoice flips to paid status
Invoice RefundedA refund is processedManual only

Recruiting

TriggerFires WhenAuto-fires?
Candidate AppliedA new application is submitted
Candidate Stage ChangesA candidate moves to a different stage

Platform

TriggerFires WhenAuto-fires?
Email SentAny email is sent via WorkestraManual only
Scheduled (Cron)On a recurring scheduleDaily cron sweep
Webhook ReceivedA POST request is received on the workflow's URLManual only

Available Actions

Actions execute in order. Each routes through a shared platform service — emails via sendEmail, notifications via notificationService, webhooks with HMAC signing, audit events via the audit log.

ActionModuleWhat it does
Send Template EmailPlatformSend an email to a recipient via Resend
Send In-App NotificationPlatformPush a notification into a user's inbox
Call WebhookPlatformPOST a signed payload to an external URL (HMAC via WEBHOOK_SIGNING_SECRET)
Log EventPlatformWrite a custom event to the audit log
Wait / DelayPlatformPause for a set duration before the next action
Create DealCRMInsert a new deal record
Update DealCRMUpdate whitelisted fields (title, stage, status, value, currency, probability, notes)
Update Win ProbabilityCRMSet the probability field on an opportunity (0–100)
Assign OwnerCRM / Projects / SupportReassign the owner of a deal, contact, ticket, task, issue, or project
Flag as StaleCRMRecord a stale_flagged event in the audit log
Create TicketSupportOpen a new support ticket
Create ProjectProjectsOpen a new project
Close Sprint CycleProjectsClose the active sprint cycle
Create InvoiceFinanceInsert a draft invoice
Create QuotationFinanceInsert a draft quotation
Notify ATSRecruitingSend a recruiting-team notification
Generate DocumentPlatformReserved — pending the shared document service

Creating a Workflow

From Scratch

  1. Navigate to Automations in the sidebar.
  2. Click New Workflow.
  3. Give the workflow a name and optional description.
  4. Select a Trigger from the dropdown (searchable, grouped by module).
  5. Add one or more Actions from the left palette. Drag to reorder.
  6. Set a per-action Delay if you want a pause before it runs.
  7. Click Save — the workflow is saved as a Draft.
  8. Click Activate to make it live.

From a Template

  1. Navigate to Automations → Templates.
  2. Browse templates grouped by category (Sales, Marketing, Customer Success, Operations).
  3. Click Use Template — a real workflow is created in your workspace and the editor opens on it.
  4. Review and adjust the trigger and actions.
  5. Click Save then Activate.

Default Templates

Every workspace sees the same 20 system templates in /automations/templates. Pick one, click Use Template, the workflow is copied into your workspace as an editable draft. Every copy is yours to tweak — the original system template stays pristine.

Sales

TemplateWhat it does
Lead Welcome EmailSends a welcome email when a new contact is created
Deal Created → Slack AlertPosts a signed webhook when a new deal lands
Deal Stage → Negotiation NudgeNotifies the sales manager and bumps win probability to 60%
Deal Won → Thank-You EmailSends a thank-you email and logs the win
Deal Won → Auto-Generate InvoiceDrafts an invoice pre-filled from the deal

Customer Success

TemplateWhat it does
Customer Onboarding KickoffSends welcome email, assigns a CSM, logs the onboarding
Ticket Created → Auto-AcknowledgeSends an acknowledgement the moment a ticket opens
Ticket Resolved → CSAT SurveySends a satisfaction survey on resolution
New Contact → CSM NotificationPings a CSM when a new contact is created

Operations

TemplateWhat it does
Deal Won → Kickoff ProjectOpens a kickoff project and assigns a lead
Ticket Escalation → Ops PagerDutyNotifies ops, logs escalation, pings a paging webhook
Task Completed → Audit LogWrites an audit event every time a task is completed
Candidate Applied → Auto-ConfirmationConfirms the candidate and notifies the recruiter
Candidate Stage → Recruiter AlertPings recruiting when a candidate changes stage

Marketing

TemplateWhat it does
Invoice Paid → Thank-You EmailSends a thank-you and logs the payment
Invoice Paid → Accounting WebhookForwards a signed webhook to an external accounting system
Invoice Refunded → Apology EmailSends an apology and logs the refund

Custom / Platform

TemplateWhat it does
Daily Digest (Scheduled)Fires once per day and writes a digest event
Stale Deal Alert (Scheduled)Flags stale deals daily and notifies the sales manager
External Webhook → Create TicketOpens a ticket from an incoming signed webhook

★ = featured. Featured templates show at the top of the gallery.

Publishing your own templates

Workspace admins can publish custom workflows as templates via TemplatesService.publish(). They appear in the same gallery — scoped to your workspace only — next to the system defaults, marked with a Workspace badge. Use this to share recurring patterns with the rest of your team without duplicating each workflow manually.

Usage counts

Each time someone clicks Use Template for a given template, its usage_count bumps by 1. The gallery surfaces the count under each card so you can see which templates are most popular.

How system templates are managed. System defaults live in the workflow_templates table with workspace_id IS NULL. They're seeded by a Supabase migration, not by hardcoded TypeScript — so admins can update the catalog without a code deploy. The TypeScript side keeps a SYSTEM_TEMPLATE_SLUGS registry and a drift-check unit test so the two never diverge.


Run History

The Runs tab (/automations/runs) shows every execution in the workspace.

ColumnMeaning
Status iconPending / Running / Completed / Failed / Cancelled / Paused
WorkflowName (links to the editor)
StartedRelative time
DurationTotal run time (ms → s → m → h)
ErrorInline error message when the run failed

Filter by status using the tabs at the top. Click a row to jump to the workflow it came from.


Error Handling

Each workflow has an error-handling strategy set in the right-hand Workflow Settings panel:

StrategyBehaviour when an action fails
Continue on error (default)Skip the failed action, keep executing subsequent ones
Retry on errorRetry the action up to 3× with backoff, then continue
Stop on errorHalt the run, mark execution failed

Failures are captured in completed_actions[].error on the execution row, and surfaced inline on /automations/runs.


Security

  • Workspace isolation — every workflow and execution is scoped by workspace_id via RLS. The stats view uses security_invoker=true so it honours RLS of the base tables.
  • Role-gated deletes — only workspace owners and admins can delete workflows.
  • Signed webhooksCall Webhook actions sign the payload with HMAC-SHA256 using WEBHOOK_SIGNING_SECRET. The receiving server verifies via the X-Workestra-Signature header.
  • Defense-in-depth on the JSONB shape — CHECK constraints on workflows.trigger / .actions / .conditions reject malformed rows at the DB boundary. Application writes validate with Zod before the insert.
  • Executor whitelistingUpdate Deal only accepts a fixed list of columns, so a workflow author cannot rewrite arbitrary fields.

Difference: Quick Rules vs. Workflows

FeatureQuick Rules (/settings/automations)Visual Workflows (/automations)
ComplexitySingle trigger → single actionMulti-step, multi-action
EditingToggle on/off onlyFull visual editor with React Flow canvas
ConditionsNot supportedFull condition logic
ScopePre-defined system rulesFully custom
Storageautomation_rules tableworkflows + workflow_executions tables
Best forCommon platform automationsCustom business logic

Use Quick Rules for common patterns that ship pre-configured. Use Workflows for any custom logic specific to your business.


Architecture (For Developers)

Layers

UX:        /automations/* pages           →  Thin shells over the module
Module:    src/modules/automations/*      →  Services, hooks, schemas, components, events
Dispatch:  src/modules/automations/events/dispatcher.ts  →  fireWorkflowEvent
Runner:    src/modules/automations/events/runner.ts      →  runExecution + sweep
Cron:      /api/cron/workflow-runner       →  Daily sweep of pending executions
Data:      Supabase: workflows + workflow_executions + workflow_run_stats view

Key files

FilePurpose
src/modules/automations/lib/workflow-constants.tsSingle source of truth for the trigger + action catalog
src/modules/automations/lib/trigger-mapper.tsUI key ↔ stored trigger shape (handles legacy rows)
src/modules/automations/lib/action-mapper.tsUI key ↔ canonical action type
src/modules/automations/lib/workflow-to-graph.tsStored workflow ↔ React Flow nodes/edges
src/modules/automations/lib/workflow-templates.tsBuilt-in template catalog
src/modules/automations/lib/feature-flag.tsisAutomationsEnabledClient / isAutomationsEnabledServer
src/modules/automations/schemas/workflow-schema.tsZod schemas for reads/writes
src/modules/automations/services/Workflows, executions, stats data access
src/modules/automations/hooks/TanStack Query hooks (list / one / stats / executions + mutations)
src/modules/automations/components/Canvas, palette, config panel, editor, list row, stats strip
src/modules/automations/events/dispatcher.tsfireWorkflowEvent, triggerWorkflowManually
src/modules/automations/events/runner.tsrunExecution, sweepPendingExecutions
src/modules/automations/events/executors.ts17 action executors wired to platform services
src/modules/automations/events/dispatch-action.tsServer action wrapper for client callers
src/app/(dashboard)/automations/Pages (list, [id], templates, runs, layout gate)
src/app/api/cron/workflow-runner/route.tsDaily cron sweep
supabase/migrations/20260424200000_automations_visual_builder.sqlBase tables
supabase/migrations/20260424210000_automations_security_hardening.sqlSecurity hardening

Supabase objects

ObjectPurpose
workflowsWorkflow definitions (trigger + conditions + actions as JSONB)
workflow_executionsImmutable execution history + audit log
workflow_run_statsView with security_invoker=true — powers the 4-col stats strip
seed_workspace_workflows(ws_id)RPC — seeds the default onboarding workflow for new workspaces
automation_rulesSeparate system — Quick Rules (legacy surface)

How domain events fire workflows

The dispatcher (fireWorkflowEvent) is called from the following paths. Each call is fire-and-forget and wrapped in try/catch — workflow dispatch never breaks the underlying mutation.

Trigger keyCalled from
deal_createdDealService.createDeal
deal_stage_changeDealService.moveDealToStage
deal_closed_wonSame path when stage === "closed_won"
contact_createdContactService.createContact
task_status_changeTaskService.updateIssueStatus
task_completedSame path when status === "done"
ticket_createdTicketService.createTicket
ticket_escalatedTicketService.escalateTicket
ticket_resolvedTicketService.resolveTicket
invoice_paidPaymentService.refreshInvoicePaidAmount (server-only)
candidate_appliedApplicationService.createApplication
candidate_stage_changeApplicationService.updateApplicationStatus

The in-process runner is called immediately after a dispatch for low latency. The daily cron at /api/cron/workflow-runner is the backstop for executions that crashed, were delayed, or need to resume after a Wait / Delay action.


Next Steps