Workflow Builder Architecture
A developer-focused overview of the Workflow Builder, covering core concepts, key components, data flow, and state management.
Workflow Builder Architecture
Source: This page is based on docs/WORKFLOW_BUILDER.md
This document provides a developer-focused overview of the Workflow Builder in Project Eddy. It covers the core concepts, key components, data flow, and state management that power the creation and editing of workflows.
For details on the individual content elements within a page, see the Block Architecture documentation.
1. Core Concepts
The Workflow Builder is a multi-faceted tool for designing structured processes. A workflow is composed of several key entities:
- Workflow: The top-level container for a process template. It holds pages, transitions, roles, and settings.
- Pages (or Stages): These represent the individual steps or screens in a workflow. A user interacts with the content on a page during a workflow run.
- Transitions (or Edges): These are the directed links between pages that define the flow of the process. They can contain conditional logic to control which path is taken based on user-provided data.
- Roles (or Participants): These define the different actors who can participate in a workflow (e.g., "Author", "Reviewer", "Approver"). Roles are assigned to specific stages to control permissions.
- Sections & Blocks: Pages are composed of sections, which in turn contain blocks. Blocks are the atomic units of content and user input (e.g., text fields, multiple-choice questions, content displays).
2. Key UI Components & Functional Areas
The builder's UI is divided into several distinct, cooperative areas, primarily managed from the main builder page at /workspaces/[groupId]/workflows/[workflowId].
A. The Stage Graph (Visual Flow Editor)
This is the primary interface for orchestrating the high-level structure of the workflow.
- Component:
BuilderStageGraph(inferred fromFRONTEND_APP_MAP.md). - Technology: React Flow.
- Functionality:
- Displays pages as nodes and transitions as edges in a diagram.
- Users can visually create, delete, and rearrange pages (nodes).
- Creating a connection between two nodes creates a
page_transitionrecord. - Double-clicking an edge opens the Transition Editor.
B. The Transition Editor (Conditional Logic)
This modal allows builders to define the rules that govern movement between stages.
- Component:
app/components/builder/BuilderGraphEdgeEditor.tsx - Functionality:
- Opens when a transition edge is double-clicked on the Stage Graph.
- Allows the builder to define a set of conditions using a query builder UI (
QueryBuilderPopover). - These rules are evaluated against data stored in the workflow's associated Sheet. For example, a transition might only be active if a "Status" column in the sheet is set to "Approved".
- The rules are saved to the
ruleJSONb field in thepage_transitionstable via thePOST /api/page_transitions/updateendpoint.
C. The Page Editor (Content Authoring)
When a user needs to edit the content of a specific page, the Page Editor panel is used.
- Primary Component:
app/components/builder/PageBuilder.tsx - Mobile Wrapper:
app/components/builder/layouts/components/PageBuilderMobile.tsx - Functionality:
- Provides a view of all sections and blocks within a single page.
- Uses
dnd-kitto enable drag-and-drop reordering of both sections and the blocks within them. - Handles the creation of new sections (
POST /api/sections/create). - Renders individual blocks using
BuilderBlocksRenderer, which wraps each block in aBlockEditor. - The
BlockEditor(app/components/renderers/components/BlockEditor.tsx) provides the UI chrome (edit/delete buttons) around each block, which in turn opens the appropriate block configuration panel.
D. The Role Manager (Participant Definition)
This area is dedicated to defining the different roles that will participate in the workflow.
- Component:
app/components/builder/components/BuilderPartyFrameGroup.tsx - Functionality:
- Uses a unique "Party Frame" UI (
BuilderPartyFrame.tsx) for each role. - Allows for the creation, deletion, and editing of workflow roles (
workflow_rolestable). - Each role can be configured with a name, description, color, and avatar icon.
- Supports drag-and-drop reordering of roles, also powered by
dnd-kit. - Changes are saved via mutation hooks like
useCreateWorkflowRoleMutationanduseUpdateWorkflowRoleMutation.
- Uses a unique "Party Frame" UI (
E. Stage Role Assignments
Once roles are defined, they must be assigned to pages to grant permissions.
- Triggered From: The Page Editor (
PageBuilderMobile.tsxshows an icon for this). - Functionality:
- A modal or panel allows the builder to assign one or more roles to the current page.
- This creates records in the
stage_role_assignmentstable. - Permissions like
can_writeandcan_progressare defined here, controlling what a user in that role can do on that specific stage during a run. - See
SESSION_PROGRESSION_RULES.mdfor more on how these assignments affect a live session.
3. Data Flow & State Management
The builder relies heavily on React Query for fetching server state and useMutation for writes, ensuring the UI stays in sync with the database.
- Initial Load: When the builder page mounts, it uses a series of hooks to fetch all necessary data:
useGetWorkflowfetches the core workflow object, including its pages, sections, and blocks.useGetPageTransitionsByWorkflowIdfetches the edges for the graph.useGetWorkflowRolesByWorkflowIdfetches the participants for the Role Manager.
- User Actions & Mutations:
- When a user performs an action (e.g., renames a role, adds a block, changes a transition rule), a dedicated mutation hook is called.
- Example:
useUpdateWorkflowRoleMutationinBuilderPartyFrame.tsxsends aPOSTrequest to/api/workflow_roles/update. - On success, the mutation invalidates the relevant React Query cache keys (e.g.,
queryClient.invalidateQueries('workflow')). This triggers a refetch of the stale data and causes the UI to update with the latest state from the server.
- Drag-and-Drop State:
- The
dnd-kitimplementation inPageBuilder.tsxuses theuseDndHandlerhook to manage the client-side state of sections and blocks during a drag operation. - On
onDragEnd, a mutation is fired to persist the new ordering to the backend. The API uses a consolidated endpoint (POST /api/workflows/reorder) to handle these complex reordering operations atomically, preventing race conditions.
- The
- State Stores (Zustand):
useUIStore: Manages the visibility of various editor panels and modals (e.g.,toggleOpeners.pageEditor,editingBlockId).useWorkflowBuilderStore: Holds state specific to the builder's context, such as the currently selected page.useCommonStore: Caches common data like user permissions (memberCanUpdate) and workflow preview data.
4. Workflow Creation & Sharing
- Creation: The creation process begins at
/workspaces/[groupId]/workflows.- The list view (
index.tsx) contains the "New Workflow" button, which opensNewWorkflowModal. - The simplified form at
/workspaces/[groupId]/workflows/new.tsx(and the modal) gathers the initialnameanddescriptionand callsPOST /api/workflows/create. A key option here isscaffold_sheet, which automatically creates a new Sheet to store data for the workflow's blocks.
- The list view (
- Sharing & Distribution:
- The
ShareWorkflowModal.tsxcomponent provides multiple ways to distribute a workflow:- Direct Share: Invite specific users via email.
- Permalink: A direct link to the workflow's builder page.
- Self-Service Link: A public link that allows non-members to start a new session of the workflow. This is managed via the
self_service_startstable.
- The
5. Workflow Lifecycle: Drafts and Publishing
To ensure that workflows can be safely edited without disrupting live processes, Project Eddy employs a draft and publishing system. Every workflow exists in one of two states: Draft or Published.
Draft State
A workflow in the Draft state is considered a work-in-progress.
- Characteristics:
- It can be freely edited by builders with the appropriate permissions.
- It cannot be started by end-users through normal means (like self-service links or scheduled starts). This prevents users from running incomplete or unstable versions.
- This is the default state for any newly created workflow.
- Database Representation: A workflow is a draft when its
published_atcolumn in theworkflowstable isNULL.
Published State
A Published workflow is a stable, live version that is ready for use.
- Characteristics:
- It is considered the "official" version of the process.
- End-users can initiate sessions (workflow runs) from it.
- While it can be edited, changes may affect new sessions immediately. To make significant changes, the recommended practice is to revert it to a draft.
- Database Representation: A workflow is published when its
published_atcolumn contains a valid timestamp.
The Publishing Process
The transition from a draft to a published state is a manual action performed by a workflow builder.
- Mechanism: This is handled via the
POST /api/workflows/publishendpoint, which sets thepublished_attimestamp. The UI for this is typically a "Publish" button within the workflow builder's top bar or settings. - Impact: Publishing a workflow unlocks certain features. For example, as seen in
ShareWorkflowModal.tsx, the ability to create a "Self-Service Link" is disabled until a workflow has apublishedAtdate.
Reverting to a Draft
A published workflow can be converted back into a draft. This is useful for making significant updates or temporarily disabling a workflow without archiving it.
- Mechanism: This action is handled by the
POST /api/workflows/draftendpoint, which sets thepublished_atcolumn back toNULL.
6. Workflow Validation
To ensure that workflows are robust, functional, and ready for use, the builder includes a comprehensive, real-time validation system. This system checks for common configuration errors and structural issues, providing immediate feedback to the builder and preventing incomplete workflows from being published.
The validation logic is hierarchical, starting from the workflow level and drilling down into each page, section, and block.
Validation Hierarchy and Key Rules
The validation process is handled by a set of utility functions (validateWorkflow.ts, validatePage.ts, etc.) that perform checks at each level of the workflow structure.
A. Workflow-Level Validation (validateWorkflow.ts)
At the highest level, the system checks for the overall structural integrity of the workflow:
- Must Have Pages: A workflow must contain at least one page.
- Must Have a Starting Page: The workflow needs a single, designated starting point for a session to begin (not required for single-page workflows).
- Must Have an End Page: There must be at least one page marked as an "end stage" to define a clear completion point.
- No Orphaned Pages: All pages must be connected to the graph via transitions. Any page that is not a source or target of a transition is considered an "orphan" and will be flagged.
B. Page-Level Validation (validatePage.ts)
For each page within the workflow, the following is checked:
- Must Have Sections: A page cannot be empty; it must contain at least one section.
- Must Have Role Assignments: Every page must have at least one workflow role assigned to it. This ensures that there is always a participant who can access and act on the stage during a run.
C. Section-Level Validation (validateSection.ts)
Within each page, sections are validated:
- Must Have Blocks: A section must contain at least one block, unless it is a special read-only section type.
D. Block-Level Validation (validateBlock.ts)
Finally, individual blocks are checked for correct configuration:
- Input Blocks Must Have Data Bindings: Any block designed to capture user input (e.g., text fields, date pickers, select dropdowns) must be bound to a Sheet and Column (
sheet_idandcolumn_id). This is critical for ensuring that user data is saved correctly.
UI Integration
The results of these validation checks are integrated directly into the builder UI to guide the user:
- Real-time Feedback: As the builder makes changes, validation rules are re-evaluated. Errors are often displayed as warnings or error icons next to the misconfigured element (e.g., on a page node in the graph or within the Page Editor).
- Preventing Publishing: The "Publish" button for a workflow is typically disabled if any validation errors are present. This acts as a gate, ensuring that only complete and correctly configured workflows can be made live for end-users.
This systematic validation ensures data integrity, prevents runtime errors, and guides builders toward creating complete and logical processes.