Workflow Export
Design and behavior of the workflow export feature in Eddy
Workflow Export Functionality
Source: This page is based on docs/WORKFLOW_EXPORT.md
Last Updated: January 1, 2026
This document outlines the design and behavior of the workflow export feature in Eddy. The feature allows users to export a complete workflow definition into a structured JSON file. This file can be used for backups, migrating workflows between environments, or as a basis for a templating system.
Overview
The export process packages a single, non-archived workflow and all its constituent parts into a versioned JSON object. The process is designed to be robust, ensuring data integrity and excluding irrelevant or archived data.
The core logic is handled by the exportWorkflow service, exposed via a secure API endpoint.
API Endpoint
Route: POST /api/workflows/export
Authorization: The requesting user must be a member of the group that owns the workflow.
Request Body:
{
"workflow_id": "string (uuid)",
"include_sheets": "boolean (optional, default: false)"
}Response:
- On success, it returns a
200 OKstatus with a JSON payload - HTTP headers are set to prompt a file download in the browser:
Content-Type: application/jsonContent-Disposition: attachment; filename="eddy-workflow-export-<workflow-name>-<date>.json"
- On failure (e.g., workflow not found, archived, or unauthorized), it returns an appropriate
4xxerror code
Exported Data Structure
The exported JSON file has a top-level structure containing metadata and arrays of the workflow's components. The structure is strictly validated by EddyWorkflowExportZ.
// High-level structure from app/types/export.ts
type EddyWorkflowExportT = {
version: number // Currently 1
exportedAt: Date
sourceWorkflowId: string
// Core Workflow Components
workflow: WorkflowDatabaseT
pages: PageDatabaseT[]
sections: SectionDatabaseT[]
blocks: BlockDatabaseT[]
blockOptions: BlockOptionT[]
pageTransitions: PageTransitionT[]
workflowRoles: WorkflowRoleT[]
stageRoleAssignments: StageRoleAssignmentBaseDatabaseT[]
// Optional Components
sheets?: SheetT[]
columns?: ColumnT[]
}Core Logic & Data Integrity
The export service (app/services/workflows/export.ts) follows several key principles to ensure a clean and valid export.
1. Transactional Read
All database queries are wrapped in a single knex.transaction, ensuring a consistent snapshot of the data is read.
2. Exclusion of Archived Data
This is a fundamental rule:
- The export will fail if the target workflow itself is archived
- Any related entity (Page, Section, Block, Block Option, Sheet, Column) with a non-null
archived_attimestamp is filtered out of the export - The logic also correctly excludes children of archived parents. For instance, if a
Pageis archived, all of itsSectionsandBlockswill be excluded, even if they are not archived themselves - Similarly, if a
Sectionis archived, itsBlocksare also excluded Page TransitionsandStage Role Assignmentsare excluded if they reference an archived page
3. Sheet & Column Export (include_sheets: true)
When include_sheets is true, the service gathers a unique set of sheet IDs referenced by the workflow.
Sheets are included if they are linked from:
- The workflow's
scaffold_sheet_id - A section's
sheet_id - A block's
sheet_id
Columns have stricter inclusion criteria. They are only included if they meet two conditions:
- They are directly referenced by a non-archived block's
column_id - Their parent sheet is also being exported (i.e., it is not archived)
This means that other columns belonging to an exported sheet will not be included unless they are explicitly linked to a block, and columns referenced by blocks will not be included if their parent sheet is archived.
4. Final Validation
Before returning the data, the entire assembled object is parsed and validated against the EddyWorkflowExportZ schema. This Zod schema includes a .refine() check that programmatically verifies no archived entities are present, providing a final layer of defense for data integrity.
Edge Cases and Behavior
The integration tests (app/__tests__/integration/workflowExport.test.ts) cover numerous scenarios:
- Empty Workflow: A workflow with no pages, sections, or blocks can be exported successfully. The corresponding arrays in the JSON file will simply be empty.
- No Sheet References: If
include_sheetsistruebut no sheets are linked to the workflow, thesheetsandcolumnsarrays will be present but empty. - Orphaned Entities: The system is robust against orphaned data. For example, a
block_optionwhose parentblockis archived will not be included because the parent block is filtered out first. - Data Isolation: The export is strictly scoped to the provided
workflowId. No data from other workflows, even within the same group, will be included. - Deduplication: Sheets referenced by multiple sources (e.g., as a scaffold sheet and by a block) will only be included once in the
sheetsarray.
Use Cases
1. Workflow Backup
Export workflows regularly to create backups that can be restored if needed.
2. Environment Migration
Export a workflow from a development environment and import it into staging or production.
3. Workflow Templates
Export a well-designed workflow and share it as a template for others to import and customize.
4. Version Control
Store exported workflows in version control systems to track changes over time.