Skip to content

Database Workflows

A Database Workflow is a reusable automation that runs business logic against the data model - looking up records, saving changes, submitting for approval, calling other functions, looping over collections, and routing based on conditions. Workflows run inside PostgreSQL as PLV8 functions, which means they are best suited for short, transactional work that stays within the platform: saving and submitting records, validating data, coordinating other workflows or server functions. For anything that calls external APIs, uses AI, handles files, or may run for seconds or longer, use a Server Function instead.

Use a Database Workflow whenUse a Server Function when
Logic only reads/writes platform recordsYou need to call an external HTTP API or webhook
Validation, submission, or approval logicYou need AI generation or embeddings (api.ai.*)
Coordinating saves across multiple entitiesYou need to send email (api.mail.send)
Calling other workflows or functionsYou need file storage or URL fetch (api.files.*)
Logic completes quickly (milliseconds)The task may run for seconds or longer
You want point-and-click Design modeYou need secrets management (api.secrets.*)

When in doubt: if the work stays entirely within the platform and runs fast, use a Database Workflow. If it touches the outside world or might take time, use a Server Function. The two are designed to work together - a Database Workflow can call a Server Function as a step whenever it needs to hand off work that crosses those boundaries.


Navigate to Automation - Database Workflows to see all workflows in the current application:

ColumnDescription
Workflow NameHuman-readable name
Definition TypeDesign or AI/Code
Module NameWhich module the workflow belongs to
Created ByThe user who created it
Modified OnLast modification timestamp
Published OnWhen the workflow was last published
StatusA checkmark (✓) if published and current, or a Publish link if there are unpublished changes

Use + Add to create a new workflow, and the row checkboxes plus Delete to remove workflows in bulk.


Database Workflows can be built two ways, chosen at creation and cannot be changed afterwards:

  • Design mode - a visual canvas where you assemble steps point-and-click, connecting them into a flow without writing code.
  • AI/Code mode - a PLV8 code editor with AI assistance for when you need full programmatic control.

Clicking + Add opens the Add Database Workflow panel. The first and most important choice is Definition Type:

  • AI/Code - creates a PLV8 function you write (or generate with AI) directly as code. Fields: Function Name, Function ID (auto-generated), Function Module, Description.
  • Design - creates a visual workflow built from steps on a canvas. Fields: Workflow Name, Workflow ID (auto-generated), Workflow Module, Input Structure, Output Structure, Description.

Input Structure and Output Structure are optional. When set, they define the typed shape of data passed into the workflow and returned from it - using a Structure defined in Data Model. Setting an Output Structure also unlocks the output mappings option on each step’s End configuration, so step results can be mapped to the workflow’s return value.

The definition type cannot be changed after the workflow is saved.


Click a workflow to open its detail view. Publish sits at the top left. Top right actions: Security Rules, Clone. Run Workflow (next to the tab row) lets you test the workflow directly without leaving the detail view.

The Workflow Details card on the Details tab shows the workflow’s configuration. Click Edit to change any of these settings, including three execution options:

SettingDescription
Log ExecutionWhether each execution is recorded in the execution log
Run AsyncWhether the workflow runs asynchronously - does not block the caller while it runs
Run Under TransactionWhether the workflow runs within a single database transaction

The tabs below depend on the definition type:

  • Design workflows: Details, Diagram
  • AI/Code workflows: Details, AI/Code, Logs

The Diagram tab is the visual canvas. A breadcrumb at the top shows your current location in the workflow - Main at the root level, and Main > [step name] when you drill into a Foreach step’s inner canvas.

Zoom controls sit at the bottom left: +, -, and a fit-to-screen button.

Every Design workflow has two fixed terminal nodes:

  • Start (▶) - where execution enters the workflow
  • End (■) - where execution exits

Steps appear between them as icon nodes, connected by dashed arrows. The canvas is empty when a workflow is first created, showing a “No Steps Yet” message and a central + Add Step button.

Click + Add Step on an empty canvas to open the Select Workflow Step picker - a grid of the nine available step types. Select one to begin configuring it.

Once a workflow has steps, new steps can be added inline from the Next Step panel at the end of any step’s configuration (see Next Step configuration below).

Steps connect to each other via their Next Step setting. A step can point to any other step or to End. Condition and Review steps have two outgoing paths each; all other steps have one.

Hovering a step node reveals action icons above it:

  • Unlink left - disconnects this step from its predecessor (the step that currently points to it)
  • Delete (red trash) - removes the step entirely
  • Unlink right - disconnects this step from its successor

Foreach steps additionally show a drill-into icon that opens the step’s inner canvas.

Clicking a step node (not a hover icon) opens its configuration panel to edit it.


Every step is configured through a short panel flow. Most steps have three screens: Step Settings, Step Input, and Next Step. Some steps (Condition, Expression) embed their logic in the Settings screen and skip a separate Input screen.

All steps share two common fields at the top of their Settings screen:

FieldDescription
Step NameHuman-readable label shown on the canvas node
Step IDAuto-generated from the name; used as the step’s identifier in the workflow context

Finds a single record matching a filter and makes its fields available to subsequent steps. Returns the first matching record, or nothing if no match is found. This is distinct from Foreach, which works with a full collection.

Step Settings:

FieldDescription
Record TypeEntity, Component, or View
Entity / Component / ViewThe specific target to look up

Step Input (Mappings):

Each mapping row filters the lookup: a Target field on the record, a Mapping Type (Maps To a context value, or Has Value for a fixed constant), and a Source from the workflow context. Use + Add new mapping to add filter conditions.

Output (available to subsequent steps): the retrieved record and all its fields.


Writes field values to a record (creating or updating it) and makes the record identifiers available to subsequent steps.

Step Settings:

FieldDescription
Record TypeEntity or Component only (Views are read-only)
Entity / ComponentThe specific target to save to

Step Input (Mappings):

Each mapping row sets a field on the target record from the workflow context. Same mapping row structure as Lookup record.

Output (available to subsequent steps): record identifiers - System ID (thing_id) and System Version (version_id) for versioned entities/components; Entity ID for system entities.


Advances a record from Draft to Submitted in the record lifecycle. Only needs to know which record to act on - it does not set any field values.

Step Settings:

FieldDescription
EntityThe entity to submit a record of (no Component or View)

Step Input (Mappings):

Two mappings only - System ID (thing_id) and System Version (version_id) of the record to submit, sourced from a previous step or the workflow input.

Output (available to subsequent steps): System ID and System Version of the now-submitted record.


Calls a published Server Function as a step in the workflow. This is the primary way a Database Workflow hands off work that needs external I/O, AI, file handling, or anything that can’t run inside PLV8.

Step Settings:

FieldDescription
Server FunctionThe Server Function to call
MethodOptional - the specific handler/command to invoke if the function exposes multiple public methods

Step Input (Mappings):

Maps workflow context values into the function’s input structure.

Output (available to subsequent steps): whatever the Server Function returns, if it has an output structure defined or auto-discovered.


Calls another published Database Workflow as a step. Works identically to Execute Server Function - same Settings fields (target workflow + optional method), same input mappings, same output handling.

Use this to compose reusable sub-workflows rather than duplicating logic across multiple workflows.


Evaluates a PostgreSQL expression at runtime and makes the result available to subsequent steps as a single computed value.

Step Settings:

The Settings screen is the full configuration for this step - there is no separate Input screen.

A Calculation Formula code editor takes the expression. An Expand button opens it full-screen. A context helper panel on the right has four sections:

  • STEPS - all previous steps in the workflow, expandable by name to browse their output fields. Workflow Input appears here too.
  • SCALAR SQL FUNCTIONS - published scalar views callable as functions.
  • DATASET SQL FUNCTIONS - published dataset views.
  • POSTGRES FUNCTIONS - the full built-in PostgreSQL function library.

Click any item in the helper to insert a reference into the expression at the cursor.

Output (available to subsequent steps): the single computed value the expression returns.


Evaluates a condition against the workflow context and routes execution to one of two paths.

Step Settings:

The condition builder is embedded in the Settings screen. Each condition row has:

FieldDescription
Operand 1A field from the workflow context (previous step output or Workflow Input)
OperatorComparison operator - Equals, Contains, Greater Than, Is Empty, and others
Source TypeValue of (compare to another context field) or Fixed value (compare to a constant)
ValueThe constant to compare against, when Source Type is Fixed value

Complex nested conditions are supported via the Back navigation within the condition builder.

Output: none - Condition only routes, it does not produce a value.

Next Step: two paths - Next if True and Next if False, each independently pointing to another step or End.


Pauses the workflow and routes a record to one or more reviewers for approval. When execution reaches a Review step, the workflow pauses and waits asynchronously until a reviewer acts. The workflow resumes only when approval or rejection is recorded.

Multiple Review steps in a single workflow implement a multi-stage approval policy.

Step Settings:

FieldDescription
Review TypeAny Reviewer - one approval from any listed reviewer is sufficient; All Reviewers - every listed reviewer must approve; Minimum Reviewers - a specified minimum number must approve
Minimum Number of ReviewersRequired when Review Type is Minimum Reviewers
ReviewersOne or more reviewer identities, added with + Add more

Step Input (Mappings):

Two mappings - System ID (thing_id) and System Version (version_id) of the record being reviewed. In most cases these come directly from the workflow’s Input Structure, since workflows are typically triggered when a record is submitted.

Next Step: two paths:

  • Next if approved - where to go when the review passes
  • Next if rejected - where to go when rejected. This does not have to be End/Failed - it can route to another step (for example, a notification or a reset step) before eventually ending.

Iterates over a collection of records - a component’s rows or a view’s result set - running a nested set of steps on each record in turn.

Step Settings:

FieldDescription
Record TypeComponent or View (View can cover entities, components, or any other query result)
Component / ViewThe specific target to iterate over

Step Input (Mappings):

Filter parameters for the Component or View - controls which records are included in the iteration. Same mapping structure as Lookup record.

The inner canvas:

Click the drill-into icon on a Foreach node (visible on hover) to enter the step’s inner canvas. The breadcrumb at the top updates to Main > [foreach step name] to show where you are.

The inner canvas is a full workflow canvas in its own right - the same empty state, the same + Add Step button, and the same nine step types. Build the steps that should run on each record here.

Within the inner canvas, the workflow context includes:

  • Current record - the fields of the record in the current iteration
  • Parent scope - all step outputs from the Main canvas that preceded this Foreach step

When a step inside the Foreach reaches End, it means only the current iteration is complete - execution moves to the next record. There is no Succeeded/Failed status, no message, and no output mappings on an inner End.

Next Step (outer): a single next step - where the workflow goes after all iterations have completed.


Every step that produces output makes it available to all steps that come after it. When configuring any mapping, condition, or expression, the Source dropdown exposes:

  • Workflow Input - the fields of the workflow’s Input Structure (if one was defined)
  • Previous step outputs - each preceding step listed by name, expandable to its output fields

Steps can only reference steps that precede them in the execution flow. Referencing a later step will prevent the workflow from publishing.


Every step ends with a Next Step panel - the final screen before saving the step. From here:

  • Next Step - select any existing step to chain to, or select End to terminate this path
  • + Add New Step - create a new step inline without going back to the canvas

When End is selected, two additional options appear:

FieldDescription
StatusSucceeded or Failed - marks the overall workflow execution outcome for this path
MessageFree text, surfaced to the caller - especially useful on Failed paths to explain what went wrong
MappingsMap step output values to the workflow’s Output Structure fields - only available if the workflow was created with an Output Structure

Condition and Review steps show this panel twice - once per path (True/False for Condition, Approved/Rejected for Review).


The AI/Code tab is only available on workflows created with the AI/Code definition type. Design mode workflows use the Diagram tab instead and do not expose a code editor.

The interface works identically to the AI/Code mode on Server Functions - AI chat as the primary view, See Code to toggle to the code editor, Context picker to add entities/views/functions as AI context, and Apply to push AI suggestions into the editor.

The key difference from Server Functions: the code generated here is PLV8 (synchronous JavaScript running inside PostgreSQL), not Node.js. PLV8 is suited for short, transactional platform-data work - it does not support external HTTP calls, AI APIs, file operations, or long-running logic. For those, use an Execute Server Function step in your Design workflow, or choose a Server Function directly.

New AI/Code workflows start with a PLV8 template pre-populated in the editor (METADATA, CONSTANTS, PRIVATE_FUNCTIONS, HANDLERS structure). JSDoc on handlers works the same way - properly annotated handlers get their metadata extracted at publish time, powering the Published methods picker in Run Function and the method selector in workflow Execute Database Workflow steps.

Run Function and Logs work identically to Server Functions - see Running a function and Function logs.

For PLV8 API reference and code conventions, see Developer Reference - PLV8 Database Functions.


Security Rules (top right of the detail view) controls who can execute this workflow. Each rule overrides the default access behaviour for a specific set of users or roles:

FieldDescription
Rule NameHuman-readable name for the rule
Access LevelAllow - the matched users/roles can execute this workflow; Forbid - they cannot
All UsersWhen checked, the rule applies to all users regardless of Security Dimensions
Security DimensionsOne or more User or Role entries the rule applies to. Use + Add more to add additional users or roles.

The Workflow Triggers card sits on the Details tab alongside the Workflow Details card. Click Edit to open the Workflow Triggers panel where you can add, edit, and remove triggers for this workflow.

A workflow can have zero, one, or more triggers. Each trigger defines one way the workflow can be invoked - either as an action button on entity records in the UI (Manual), or automatically on a recurring schedule (Scheduled).


A Manual trigger makes the workflow available as an action button on records of the specified entities. When a user clicks that button, the workflow is invoked with the record’s identifiers passed into its input.

FieldDescription
Trigger NameHuman-readable name shown on the action button
Trigger IDAuto-generated from the name
EntitiesOne or more entities whose records should show this trigger as an action. Use + Add more to add additional entities.
MappingsMaps the triggering record’s identifiers to the workflow’s input structure fields. Target is a field on the workflow’s Input Structure (e.g. System ID, System Version); Source is the corresponding identifier from the triggering record.
Show ObjectWhen checked: if the workflow’s output contains record identifiers, the platform automatically opens that record once the workflow completes. Useful when a workflow creates or transitions a record and you want the user to land on the result.
IconThe icon displayed on the action button in the UI
Trigger ModuleWhich module this trigger belongs to
Trigger DescriptionOptional free text

A Scheduled trigger runs the workflow automatically on a cron schedule, without any user interaction.

FieldDescription
Trigger NameHuman-readable name
Trigger IDAuto-generated from the name
Schedule ExpressionA cron expression in 5-field format: Minutes, Hours, Day of month, Month, Day of week. Click the gear icon to open the Schedule Configuration helper.
Logging LevelWhat gets recorded when the scheduled run executes: No Logging, Errors Only, or Everything
Run As UserThe user identity the workflow runs as (e.g. system_user). The workflow executes with this user’s permissions for access control and audit purposes.
Trigger ModuleWhich module this trigger belongs to
Trigger DescriptionOptional free text

Schedule Configuration helper: clicking the gear icon on the Schedule Expression field opens a panel with:

  • Quick Presets - one-click shortcuts: Every minute, Hourly, Daily, Weekly, Monthly. Selecting a preset fills in all five cron fields.
  • Individual fields - Minutes, Hours, Day of month, Month, Day of week - for custom schedules not covered by a preset.
  • Next Occurrences - once a valid expression is set, the panel shows the next several execution times in both GMT (server time) and LOCAL (UTC), so you can confirm the schedule fires when you expect before saving.

A published Database Workflow is callable from anywhere in the platform that can invoke a function:

  • As an Execute Database Workflow step inside another workflow - enabling reusable sub-workflows.
  • From a Server Function via api.execute_function - useful when a Node process needs to delegate transactional data work back into PLV8.
  • From Triggers - to run automatically in response to record changes, on a schedule, or other system events.
  • From the UI via Portal Components - as an action a user triggers directly.