Portal Community

The Two Data Models

ProcessElement (Backend/DB)WorkflowNode (Frontend)
Primary keyElementId (int)id (string: "http-request-x7k2")
Type identifierTypeCode (string)type (same string)
PositionPositionX, PositionY (int columns)position: { x, y }
ConfigConfigJson (string)data.config (object)
LabelNamedata.label

ProcessElementToNodeTranslator

// packages/flow-studio-core/src/translators/ProcessElementToNodeTranslator.ts
export class ProcessElementToNodeTranslator {
  translate(element: ProcessElement, nodeType: NodeType): WorkflowNode {
    return {
      id: element.ElementId.toString(),
      type: element.TypeCode,
      position: { x: element.PositionX, y: element.PositionY },
      data: {
        label: element.Name,
        config: JSON.parse(element.ConfigJson ?? '{}'),
        formId: nodeType.formId,
        ports: nodeType.ports,      // always taken from the live NodeType
        nodeType: element.TypeCode,
        icon: nodeType.icon,
        color: nodeType.color,
      }
    };
  }
}

Why Port Data Comes from NodeType, Not ProcessElement

Port definitions are owned by the NodeType template, not by individual node instances. This means if a template's ports are updated (e.g., an error port is added), all existing workflow instances automatically get the new port on next load — without needing to migrate stored workflow data.

Port Addition Is Safe; Port Removal Is Breaking Adding a new port to a NodeType is safe — existing instances just get the new port. Removing a port from a NodeType may break saved workflows that have edges connected to that port. Check for existing edge references before removing ports.