mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-24 13:54:57 +00:00
- Moved n8n workflow schema to schemas/n8n-workflow.schema.json - Added `variables` property at workflow root level for type-safe, reusable workflow configuration - Implemented full variable system with: * Type system (string, number, boolean, array, object, date, any) * Validation rules (min, max, pattern, enum) * Scope control (workflow, execution, global) * Required/optional with default values - Created comprehensive N8N_VARIABLES_GUIDE.md (6,800+ words) with: * 5 real-world use case examples * Best practices and migration guide from meta to variables * Complete property reference and expression syntax - Created N8N_VARIABLES_EXAMPLE.json demonstrating e-commerce order processing - Documented schema gaps in N8N_SCHEMA_GAPS.md (10 missing enterprise features) - Created migration infrastructure: * scripts/migrate-workflows-to-n8n.ts for workflow format conversion * npm scripts for dry-run and full migration * N8N_COMPLIANCE_AUDIT.md tracking 72 workflows needing migration - Established packagerepo backend workflows with n8n schema format Impact: Variables now first-class citizens enabling DRY principle, type safety, and enterprise-grade configuration management across workflows. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
414 lines
12 KiB
JSON
414 lines
12 KiB
JSON
{
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"$id": "https://example.com/schemas/n8n-workflow.schema.json",
|
|
"title": "N8N-Style Workflow",
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["name", "nodes", "connections"],
|
|
"properties": {
|
|
"id": {
|
|
"description": "Optional external identifier (DB id, UUID, etc.).",
|
|
"type": ["string", "integer"]
|
|
},
|
|
"name": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
},
|
|
"active": {
|
|
"type": "boolean",
|
|
"default": false
|
|
},
|
|
"versionId": {
|
|
"description": "Optional version identifier for optimistic concurrency.",
|
|
"type": "string"
|
|
},
|
|
"createdAt": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
},
|
|
"updatedAt": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
},
|
|
"tags": {
|
|
"type": "array",
|
|
"items": { "$ref": "#/$defs/tag" },
|
|
"default": []
|
|
},
|
|
"meta": {
|
|
"description": "Arbitrary metadata. Keep stable keys for tooling.",
|
|
"type": "object",
|
|
"additionalProperties": true,
|
|
"default": {}
|
|
},
|
|
"settings": {
|
|
"$ref": "#/$defs/workflowSettings"
|
|
},
|
|
"pinData": {
|
|
"description": "Optional pinned execution data (useful for dev).",
|
|
"type": "object",
|
|
"additionalProperties": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"additionalProperties": true
|
|
}
|
|
}
|
|
},
|
|
"nodes": {
|
|
"type": "array",
|
|
"minItems": 1,
|
|
"items": { "$ref": "#/$defs/node" }
|
|
},
|
|
"connections": {
|
|
"$ref": "#/$defs/connections"
|
|
},
|
|
"staticData": {
|
|
"description": "Reserved for engine-managed workflow state.",
|
|
"type": "object",
|
|
"additionalProperties": true,
|
|
"default": {}
|
|
},
|
|
"credentials": {
|
|
"description": "Optional top-level credential bindings (engine-specific).",
|
|
"type": "array",
|
|
"items": { "$ref": "#/$defs/credentialBinding" },
|
|
"default": []
|
|
},
|
|
"triggers": {
|
|
"description": "Optional explicit trigger declarations for event-driven workflows.",
|
|
"type": "array",
|
|
"default": [],
|
|
"items": { "$ref": "#/$defs/trigger" }
|
|
},
|
|
"variables": {
|
|
"description": "Workflow-level variables for reuse and templating. Access via {{ $workflow.variables.variableName }}",
|
|
"type": "object",
|
|
"additionalProperties": { "$ref": "#/$defs/workflowVariable" },
|
|
"default": {}
|
|
}
|
|
},
|
|
"$defs": {
|
|
"tag": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["name"],
|
|
"properties": {
|
|
"id": { "type": ["string", "integer"] },
|
|
"name": { "type": "string", "minLength": 1 }
|
|
}
|
|
},
|
|
"workflowSettings": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"timezone": {
|
|
"description": "IANA timezone name, e.g. Europe/London.",
|
|
"type": "string"
|
|
},
|
|
"executionTimeout": {
|
|
"description": "Hard timeout in seconds for a workflow execution.",
|
|
"type": "integer",
|
|
"minimum": 0
|
|
},
|
|
"saveExecutionProgress": {
|
|
"type": "boolean",
|
|
"default": true
|
|
},
|
|
"saveManualExecutions": {
|
|
"type": "boolean",
|
|
"default": true
|
|
},
|
|
"saveDataErrorExecution": {
|
|
"description": "Persist execution data on error.",
|
|
"type": "string",
|
|
"enum": ["all", "none"],
|
|
"default": "all"
|
|
},
|
|
"saveDataSuccessExecution": {
|
|
"description": "Persist execution data on success.",
|
|
"type": "string",
|
|
"enum": ["all", "none"],
|
|
"default": "all"
|
|
},
|
|
"saveDataManualExecution": {
|
|
"description": "Persist execution data for manual runs.",
|
|
"type": "string",
|
|
"enum": ["all", "none"],
|
|
"default": "all"
|
|
},
|
|
"errorWorkflowId": {
|
|
"description": "Optional workflow id to call on error.",
|
|
"type": ["string", "integer"]
|
|
},
|
|
"callerPolicy": {
|
|
"description": "Optional policy controlling which workflows can call this workflow.",
|
|
"type": "string"
|
|
}
|
|
},
|
|
"default": {}
|
|
},
|
|
"node": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["id", "name", "type", "typeVersion", "position"],
|
|
"properties": {
|
|
"id": {
|
|
"description": "Stable unique id within the workflow. Prefer UUID.",
|
|
"type": "string",
|
|
"minLength": 1
|
|
},
|
|
"name": {
|
|
"description": "Human-friendly name; should be unique in workflow.",
|
|
"type": "string",
|
|
"minLength": 1
|
|
},
|
|
"type": {
|
|
"description": "Node type identifier, e.g. n8n-nodes-base.httpRequest.",
|
|
"type": "string",
|
|
"minLength": 1
|
|
},
|
|
"typeVersion": {
|
|
"description": "Node implementation version.",
|
|
"type": ["integer", "number"],
|
|
"minimum": 1
|
|
},
|
|
"disabled": {
|
|
"type": "boolean",
|
|
"default": false
|
|
},
|
|
"notes": {
|
|
"type": "string",
|
|
"default": ""
|
|
},
|
|
"notesInFlow": {
|
|
"description": "When true, notes are displayed on canvas.",
|
|
"type": "boolean",
|
|
"default": false
|
|
},
|
|
"retryOnFail": {
|
|
"type": "boolean",
|
|
"default": false
|
|
},
|
|
"maxTries": {
|
|
"type": "integer",
|
|
"minimum": 1
|
|
},
|
|
"waitBetweenTries": {
|
|
"description": "Milliseconds.",
|
|
"type": "integer",
|
|
"minimum": 0
|
|
},
|
|
"continueOnFail": {
|
|
"type": "boolean",
|
|
"default": false
|
|
},
|
|
"alwaysOutputData": {
|
|
"type": "boolean",
|
|
"default": false
|
|
},
|
|
"executeOnce": {
|
|
"description": "If true, node executes only once per execution (engine-dependent).",
|
|
"type": "boolean",
|
|
"default": false
|
|
},
|
|
"position": {
|
|
"$ref": "#/$defs/position"
|
|
},
|
|
"parameters": {
|
|
"description": "Node-specific parameters. Typically JSON-serializable.",
|
|
"type": "object",
|
|
"additionalProperties": true,
|
|
"default": {}
|
|
},
|
|
"credentials": {
|
|
"description": "Node-level credential references.",
|
|
"type": "object",
|
|
"additionalProperties": {
|
|
"$ref": "#/$defs/credentialRef"
|
|
},
|
|
"default": {}
|
|
},
|
|
"webhookId": {
|
|
"description": "Optional webhook id (for webhook-based trigger nodes).",
|
|
"type": "string"
|
|
},
|
|
"onError": {
|
|
"description": "Node-level error routing policy (engine-dependent).",
|
|
"type": "string",
|
|
"enum": ["stopWorkflow", "continueRegularOutput", "continueErrorOutput"]
|
|
}
|
|
}
|
|
},
|
|
"position": {
|
|
"type": "array",
|
|
"minItems": 2,
|
|
"maxItems": 2,
|
|
"items": {
|
|
"type": "number"
|
|
}
|
|
},
|
|
"credentialRef": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["id"],
|
|
"properties": {
|
|
"id": {
|
|
"description": "Credential id or stable key.",
|
|
"type": ["string", "integer"]
|
|
},
|
|
"name": {
|
|
"description": "Optional human label.",
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"credentialBinding": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["nodeId", "credentialType", "credentialId"],
|
|
"properties": {
|
|
"nodeId": { "type": "string", "minLength": 1 },
|
|
"credentialType": { "type": "string", "minLength": 1 },
|
|
"credentialId": { "type": ["string", "integer"] }
|
|
}
|
|
},
|
|
"connections": {
|
|
"description": "Adjacency map: fromNodeName -> outputType -> outputIndex -> array of targets.",
|
|
"type": "object",
|
|
"additionalProperties": {
|
|
"$ref": "#/$defs/nodeConnectionsByType"
|
|
},
|
|
"default": {}
|
|
},
|
|
"nodeConnectionsByType": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"main": {
|
|
"$ref": "#/$defs/outputIndexMap"
|
|
},
|
|
"error": {
|
|
"$ref": "#/$defs/outputIndexMap"
|
|
}
|
|
},
|
|
"anyOf": [
|
|
{ "required": ["main"] },
|
|
{ "required": ["error"] }
|
|
]
|
|
},
|
|
"outputIndexMap": {
|
|
"description": "Output index -> array of connection targets.",
|
|
"type": "object",
|
|
"additionalProperties": {
|
|
"type": "array",
|
|
"items": { "$ref": "#/$defs/connectionTarget" }
|
|
},
|
|
"default": {}
|
|
},
|
|
"connectionTarget": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["node", "type", "index"],
|
|
"properties": {
|
|
"node": {
|
|
"description": "Target node name (n8n uses node 'name' in connections).",
|
|
"type": "string",
|
|
"minLength": 1
|
|
},
|
|
"type": {
|
|
"description": "Input type on target node (typically 'main' or 'error').",
|
|
"type": "string",
|
|
"minLength": 1
|
|
},
|
|
"index": {
|
|
"description": "Input index on target node.",
|
|
"type": "integer",
|
|
"minimum": 0
|
|
}
|
|
}
|
|
},
|
|
"trigger": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["nodeId", "kind"],
|
|
"properties": {
|
|
"nodeId": { "type": "string", "minLength": 1 },
|
|
"kind": {
|
|
"type": "string",
|
|
"enum": ["webhook", "schedule", "queue", "email", "poll", "manual", "other"]
|
|
},
|
|
"enabled": { "type": "boolean", "default": true },
|
|
"meta": {
|
|
"description": "Trigger-kind-specific metadata for routing/registration.",
|
|
"type": "object",
|
|
"additionalProperties": true,
|
|
"default": {}
|
|
}
|
|
}
|
|
},
|
|
"workflowVariable": {
|
|
"description": "Workflow-level variable definition with type safety and validation",
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["name", "type"],
|
|
"properties": {
|
|
"name": {
|
|
"description": "Variable identifier (use in expressions as $workflow.variables.{name})",
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$"
|
|
},
|
|
"type": {
|
|
"description": "Variable data type for validation",
|
|
"type": "string",
|
|
"enum": ["string", "number", "boolean", "array", "object", "date", "any"]
|
|
},
|
|
"description": {
|
|
"description": "Human-readable variable documentation",
|
|
"type": "string",
|
|
"maxLength": 500
|
|
},
|
|
"defaultValue": {
|
|
"description": "Default value if not provided at execution time"
|
|
},
|
|
"required": {
|
|
"description": "Whether this variable must be provided (if true and no defaultValue, execution fails)",
|
|
"type": "boolean",
|
|
"default": false
|
|
},
|
|
"scope": {
|
|
"description": "Variable lifetime and visibility scope",
|
|
"type": "string",
|
|
"enum": ["workflow", "execution", "global"],
|
|
"default": "workflow"
|
|
},
|
|
"validation": {
|
|
"description": "Optional validation rules",
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"min": {
|
|
"description": "Minimum value (for numbers) or length (for strings/arrays)",
|
|
"type": "number"
|
|
},
|
|
"max": {
|
|
"description": "Maximum value (for numbers) or length (for strings/arrays)",
|
|
"type": "number"
|
|
},
|
|
"pattern": {
|
|
"description": "Regex pattern for string validation",
|
|
"type": "string"
|
|
},
|
|
"enum": {
|
|
"description": "Allowed values (whitelist)",
|
|
"type": "array",
|
|
"items": {}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|