Files
metabuilder/workflow/docs/WORKFLOW_VALIDATION_CHECKLIST.md
johndoe6345789 28ab35ba46 chore(docs): reorganize - move subproject docs to their homes (Phase 1)
Moves 45 documentation files from centralized /docs/ to subproject directories
following proximity-based organization principle. All moves use git mv to preserve history.

Changes:
- workflow/ docs: Move 27 files from docs/workflow/ to workflow/docs/
  - DAG executor docs, workflow compliance, executor analysis, loaderv2 guides, etc.
  - Result: workflow/docs/ now has 27 files

- dbal/ docs: Move 11 files from docs/dbal/ to dbal/docs/
  - DBAL architecture, analysis, integration, and workflow integration docs
  - Result: dbal/docs/ now has 18 files (11 new + 7 pre-existing)

- gameengine/ docs: Move 7 files from docs/gameengine/ to gameengine/docs/
  - GameEngine compliance audits, packages, Quake3, soundboard, engine tester
  - Result: gameengine/docs/ now has 20 files (7 new + 13 pre-existing)

Benefits:
- Docs are now closer to their code (easier to keep in sync)
- Reduces /docs/ clutter
- Establishes pattern for per-subproject documentation
- All git history preserved via git mv

Next phases:
- Phase 2: Move package-specific docs to /packages/{id}/docs/
- Phase 3: Separate N8N compliance docs by scope
- Phase 4: Organize UI documentation
- Phase 5: Create cross-project indices

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-01-23 17:22:58 +00:00

13 KiB

Workflow Validation Checklist

Purpose: Quick reference checklist for validating workflows against n8n schema Target: All workflows in MetaBuilder project Last Updated: 2026-01-22


Pre-Validation Checklist

  • Workflow file is valid JSON
  • File is named {workflow_name}.json
  • File location matches package structure: /packages/{packageId}/workflow/ or /packagerepo/backend/workflows/
  • Workflow ID is unique across system
  • No syntax errors in JSON

Required Fields Validation

Identity & Versioning (5 items)

{
  "id": "workflow_package_name",
  "name": "Human Readable Name",
  "version": "1.0.0",
  "active": false,
  "versionId": "v1_2026-01-22"
}
  • id: Present, matches pattern ^workflow_[a-z_]+$, unique
  • name: Present, non-empty, 1-255 characters
  • version: Present, semantic version format (e.g., "1.0.0")
  • active: Present, boolean value (true/false)
  • versionId: Present (optional but recommended), format v{number}_{date}

Metadata (4 items)

{
  "description": "What this workflow does",
  "tenantId": null,
  "createdAt": "2026-01-22T00:00:00Z",
  "updatedAt": "2026-01-22T00:00:00Z"
}
  • description: Present (can be null), max 500 characters
  • tenantId: Present (null for system-wide, UUID for tenant-specific)
  • createdAt: ISO 8601 format or null
  • updatedAt: ISO 8601 format or null

Core Structure (3 items)

{
  "nodes": [{ "id": "node_1", "name": "Node 1", "type": "trigger.http" }],
  "connections": {},
  "settings": { "timezone": "UTC", "executionTimeout": 3600 }
}
  • nodes: Array with minItems 1, all nodes valid
  • connections: Object (can be empty), proper connection structure
  • settings: Object with required properties (timezone, executionTimeout)

Node Structure Validation

For each node in nodes array:

Basic Node Properties

{
  "id": "node_1",
  "name": "Node Name",
  "type": "trigger.http",
  "typeVersion": 1,
  "position": [100, 100]
}
  • id: Unique within workflow, format node_*
  • name: Non-empty, descriptive string
  • type: Valid type string (check against plugin registry)
  • typeVersion: Integer >= 1
  • position: Array with exactly 2 numbers [x, y]

Node Parameters

{
  "parameters": {
    "param1": "value1",
    "param2": 123,
    "param3": true
  }
}
  • parameters: Object or absent
  • All parameter values are valid for node type
  • No undefined or null values (unless explicitly allowed)
  • Complex parameters (objects, arrays) properly formatted

Connection Validation

Connection Structure

{
  "connections": {
    "node_1": {
      "main": {
        "0": [
          { "node": "node_2", "type": "main", "index": 0 }
        ]
      }
    },
    "node_2": {
      "main": {
        "0": [
          { "node": "node_3", "type": "main", "index": 0 }
        ]
      }
    }
  }
}
  • connections is object (empty {} is valid)
  • Each source node ID exists in nodes array
  • Each target node ID exists in nodes array
  • Output indices (0, 1, 2, ...) match node type capabilities
  • No circular connections (no A→B→...→A)
  • All referenced nodes are valid

Connection Validation Steps

For each connection entry:

  1. Source node ID exists
  2. Target node ID exists
  3. Connection path main0 is present
  4. Target node reference contains node, type, index
  5. Index is non-negative integer
  6. No circular dependencies

Advanced Fields Validation

Tags (Optional)

{
  "tags": [
    { "id": "tag_1", "name": "automation" },
    { "id": "tag_2", "name": "daily" }
  ]
}
  • tags: Array of objects
  • Each tag has id and name
  • Tag IDs are unique within workflow
  • Tag names are non-empty strings

Meta (Optional)

{
  "meta": {
    "category": "notifications",
    "author": "admin_user_id",
    "permissions": {
      "execute": ["authenticated"],
      "edit": ["admin"]
    }
  }
}
  • meta: Object (can be empty {})
  • Common keys: category, author, description, permissions
  • Custom keys allowed for extensibility
  • Values are valid types

Settings (Required)

{
  "settings": {
    "timezone": "UTC",
    "executionTimeout": 3600,
    "saveExecutionProgress": true,
    "saveDataErrorExecution": "all",
    "saveDataSuccessExecution": "all"
  }
}
  • timezone: Valid timezone string (e.g., "UTC", "America/New_York")
  • executionTimeout: Positive integer (milliseconds)
  • saveExecutionProgress: Boolean
  • saveDataErrorExecution: "all", "final", "none"
  • saveDataSuccessExecution: "all", "final", "none"

Credentials (Optional)

{
  "credentials": [
    {
      "id": "cred_1",
      "name": "API Key",
      "type": "api_key",
      "binding": "node_2"
    }
  ]
}
  • credentials: Array (can be empty)
  • Each credential has id, name, type, binding
  • Binding node ID exists in nodes array
  • Credential IDs are unique

Triggers (Optional)

{
  "triggers": [
    {
      "type": "http",
      "config": {
        "method": "POST",
        "path": "/api/v1/webhook"
      }
    },
    {
      "type": "schedule",
      "config": {
        "cron": "0 9 * * MON-FRI"
      }
    }
  ]
}
  • triggers: Array (can be empty for manual workflows)
  • Each trigger has type and config
  • Trigger types are valid (http, schedule, event, webhook, etc.)
  • Config matches trigger type requirements

Variables (Optional)

{
  "variables": {
    "maxRetries": {
      "type": "integer",
      "value": 3
    },
    "apiEndpoint": {
      "type": "string",
      "value": "https://api.example.com"
    }
  }
}
  • variables: Object (can be empty)
  • Each variable has type and value
  • Variable types are valid: "string", "integer", "boolean", "array", "object"
  • Variable values match declared type

StaticData & PinData (Engine-Managed)

{
  "staticData": {},
  "pinData": {
    "node_1": [
      { "example": "data" }
    ]
  }
}
  • staticData: Object (reserved for engine, usually empty)
  • pinData: Object (optional, for development/testing)
  • PinData values are arrays of objects (execution results)

Multi-Tenant Safety Validation

  • tenantId field present (null or valid UUID)
  • All database query nodes include tenantId filtering
  • No hard-coded tenant IDs in node parameters
  • Credential bindings are tenant-scoped
  • Data responses filtered by tenantId
  • No cross-tenant data exposure in node outputs

Check each node with database operations:

  • Node has tenantId parameter
  • TenantId is sourced from request/context, not hard-coded
  • Filter conditions include tenantId: "{{ $request.user.tenantId }}"

Error Handling Validation

  • Workflow has error handler nodes (if/else, error node)
  • All conditional branches have both "true" and "false" paths
  • Error paths respond with appropriate HTTP status code (400, 401, 404, 500)
  • Error messages are meaningful and user-friendly
  • Error nodes don't leak sensitive information

For each conditional node:

  • "then" path connects to valid node
  • "else" path connects to valid node or error handler
  • Condition expression is valid

HTTP Response Validation

For workflows exposing HTTP endpoints:

{
  "id": "respond_success",
  "type": "packagerepo.respond_json",
  "parameters": {
    "body": { "ok": true, "data": "..." },
    "status": 200
  }
}
  • Response node has status field
  • Status code is valid HTTP status (200, 201, 400, 401, 404, 500)
  • Response body is valid JSON
  • Response includes ok or error field for clarity
  • Error responses include message field
  • Content-Type headers correct (application/json)

Status Code Mapping:

  • 200 - Success (GET, data retrieval)
  • 201 - Created (POST, new resource)
  • 400 - Bad Request (validation error)
  • 401 - Unauthorized (auth failure)
  • 404 - Not Found (resource missing)
  • 500 - Server Error (workflow execution failure)

Performance & Limits Validation

  • executionTimeout >= 3000ms and <= 300000ms
  • Node count <= 100 (check against meta.nodeCount)
  • Connection count <= 200 (check against meta.edgeCount)
  • No deeply nested connections (max 5 levels)
  • Loop nodes have exit conditions
  • No infinite loops detected
  • Variable sizes reasonable (< 100MB total)
  • Batch operation sizes limited (< 10000 items per batch)

Performance Checks:

  • Average node execution < 1000ms
  • Total workflow execution < timeout
  • Memory usage reasonable
  • No resource leaks in loops

Documentation Validation

  • description field is present and meaningful (50+ chars)
  • meta.category documents workflow purpose
  • All nodes have descriptive name (not just "node_1")
  • Complex nodes have explanation in meta
  • Parameter values documented (especially for magic strings)
  • Trigger configuration documented
  • Variable documentation includes type and purpose
  • Example data in pinData is realistic

Security Audit

  • No hard-coded credentials in node parameters
  • All secrets use credential bindings
  • API keys/tokens not logged in execution data
  • No SQL injection in database query parameters
  • Input validation on all user-provided data
  • Output sanitization for HTML contexts
  • Permission checks for sensitive operations
  • Audit logging for compliance
  • No XSS vulnerabilities in response bodies

Final Validation Checklist

Pre-Deployment Checks

  • Entire workflow JSON is valid (no syntax errors)
  • All required fields present and correct
  • All optional fields properly formatted
  • Nodes are all valid and connected properly
  • Connections have no circular references
  • All node IDs are unique
  • All external references (other nodes) exist
  • Settings include all required properties
  • Error handling complete
  • Documentation sufficient
  • Multi-tenant safety verified
  • Security audit passed
  • Performance acceptable

Testing Before Deployment

  • Unit test: Each node executes independently
  • Integration test: Workflow runs end-to-end
  • Error test: Error paths execute correctly
  • Performance test: Execution within timeout
  • Concurrency test: Multiple executions don't interfere
  • Data test: Output matches expected format
  • Security test: No data leaks, proper auth

Deployment Sign-Off

  • Code review completed and approved
  • All tests passing (100% pass rate)
  • Documentation complete and accurate
  • Team lead sign-off received
  • Rollback plan documented
  • Monitoring/alerting configured

Quick Validation Script

# Validate workflow JSON syntax
jq . packages/ui_workflow_editor/workflow/initialize_editor.json > /dev/null && echo "✅ Valid JSON"

# Check for required fields
jq '.id, .name, .version, .active, .nodes, .connections, .settings' workflow.json

# Count nodes
jq '.nodes | length' workflow.json

# List all node IDs
jq '.nodes[] | .id' workflow.json

# Check for node references in connections
jq '.connections | keys[]' workflow.json

# Validate connection targets exist
jq '.connections[].main | .[] | .[]' workflow.json

Common Issues & Fixes

Issue Symptom Fix
Missing id Cannot store in DB Add id: "workflow_packageid_name"
Invalid version Won't parse Use semver: "1.0.0"
Empty nodes Workflow won't run Add at least one node
Missing connections Parser error Add "connections": {}
Node not in connections Can't execute Ensure all source nodes referenced
Circular connections Infinite loop Verify graph is DAG (directed acyclic)
Invalid node type Type not found Check plugin registry for valid types
Missing node ID Connection fails Ensure all nodes have unique id
Wrong position format Canvas won't display Use [x, y] format, both numbers
Missing settings Parser error Add all 5 required settings properties

  • N8N Workflow Schema: /schemas/n8n-workflow.schema.json
  • Package Workflow Schema: /schemas/package-schemas/workflow.schema.json
  • UI Workflow Editor Update Plan: /docs/UI_WORKFLOW_EDITOR_UPDATE_PLAN.md
  • Workflow Engine Guide: /workflow/WORKFLOW_GUIDE.md
  • YAML Entity Definition: /dbal/shared/api/schema/entities/core/workflow.yaml

Use this checklist before committing any workflow changes