Logic Nodes

I nodi Logic permettono di controllare il flusso di esecuzione, trasformare dati e gestire la logica dei workflow.


Condition

condition

Valuta un’espressione e dirige il flusso verso branch diversi.

Configurazione

CampoTipoObbligatorioDescrizione
labeltextNome identificativo
conditionexpressionEspressione da valutare
modeselectNoModalità (simple, switch, multiple)

Modalità

ModalitàDescrizione
simpleTrue/False - 2 branch
switchValore esatto - N branch
multipleMultiple condizioni - N branch

Workflow Esempio: Order Routing

Diagramma di flusso

Configurazione simple
type: condition
mode: simple
condition: "{{trigger.data.total}} > 100"
label: "Order > 100€?"

Output: true o false

Configurazione switch
type: condition
mode: switch
switchValue: "{{trigger.data.orderType}}"
cases:
  - value: "digital"
    label: "Digital Product"
  - value: "physical"
    label: "Physical Product"
  - value: "subscription"
    label: "Subscription"
  - default: true
    label: "Unknown"
label: "Order Type Router"
Configurazione multiple
type: condition
mode: multiple
conditions:
  - expression: "{{data.status}} === 'urgent' && {{data.priority}} > 8"
    label: "Critical"
  - expression: "{{data.status}} === 'urgent'"
    label: "Urgent"
  - expression: "{{data.priority}} > 5"
    label: "High Priority"
  - default: true
    label: "Normal"
label: "Priority Router"

Operatori supportati

OperatoreDescrizioneEsempio
===Uguale (strict){{a}} === 'value'
!==Diverso{{a}} !== null
>, <, >=, <=Comparazione{{count}} > 10
&&AND logico{{a}} && {{b}}
||OR logico{{a}} || {{b}}
!NOT!{{flag}}
includes()Contiene{{arr}}.includes('x')
startsWith()Inizia con{{str}}.startsWith('http')

Transform

transform

Trasforma e manipola dati tra i nodi.

Configurazione

CampoTipoObbligatorioDescrizione
labeltextNome identificativo
operationselectTipo operazione
expressioncodePer customEspressione JavaScript
mappingsarrayPer mapMappature campi

Operazioni disponibili

OperazioneDescrizione
mapMappa campi da input a output
filterFiltra elementi array
reduceAggrega array in valore singolo
flattenAppiattisce array annidati
groupRaggruppa per chiave
sortOrdina array
customEspressione JavaScript custom

Workflow Esempio: Data Processing

Diagramma di flusso

Operazione map
type: transform
operation: map
mappings:
  - source: "{{api.data.user.id}}"
    target: "userId"
  - source: "{{api.data.user.email}}"
    target: "email"
  - source: "{{api.data.created_at}}"
    target: "createdAt"
    transform: "new Date(value).toISOString()"
  - static: "active"
    target: "status"
label: "Map User Data"
Operazione filter
type: transform
operation: filter
input: "{{api.data.orders}}"
condition: "item.status === 'completed' && item.total > 50"
label: "Filter Large Orders"

Output:

{
  "filtered": [...],
  "originalCount": 100,
  "filteredCount": 25
}
Operazione group
type: transform
operation: group
input: "{{api.data.transactions}}"
groupBy: "category"
aggregations:
  - field: "amount"
    operation: "sum"
    as: "totalAmount"
  - field: "id"
    operation: "count"
    as: "transactionCount"
label: "Group by Category"

Output:

{
  "groups": {
    "food": { "totalAmount": 1500, "transactionCount": 45 },
    "transport": { "totalAmount": 800, "transactionCount": 20 }
  }
}
Operazione custom
type: transform
operation: custom
expression: |
  const orders = {{api.data.orders}};
  
  return {
    totalOrders: orders.length,
    totalRevenue: orders.reduce((sum, o) => sum + o.total, 0),
    averageOrder: orders.reduce((sum, o) => sum + o.total, 0) / orders.length,
    byStatus: orders.reduce((acc, o) => {
      acc[o.status] = (acc[o.status] || 0) + 1;
      return acc;
    }, {}),
    topCustomer: orders
      .reduce((acc, o) => {
        acc[o.customerId] = (acc[o.customerId] || 0) + o.total;
        return acc;
      }, {})
      |> Object.entries
      |> (arr => arr.sort((a,b) => b[1] - a[1])[0])
  };
label: "Calculate Order Stats"

Merge

merge

Combina output da multiple branch in un singolo flusso.

Configurazione

CampoTipoObbligatorioDescrizione
labeltextNome identificativo
modeselectModalità merge
waitForarrayPer waitAllNodi da attendere

Modalità

ModalitàDescrizione
waitAllAttende tutti gli input
waitAnyProcede al primo input
combineCombina in array
objectCombina in oggetto con chiavi

Workflow Esempio: Parallel API Calls

Diagramma di flusso

Configurazione waitAll
type: merge
mode: waitAll
waitFor:
  - nodeId: "fetchUsers"
  - nodeId: "fetchOrders"
  - nodeId: "fetchProducts"
label: "Wait All APIs"

Output:

{
  "fetchUsers": { "data": [...] },
  "fetchOrders": { "data": [...] },
  "fetchProducts": { "data": [...] }
}
Configurazione combine
type: merge
mode: combine
inputs:
  - "{{apiA.output.items}}"
  - "{{apiB.output.items}}"
  - "{{apiC.output.items}}"
flatten: true
label: "Combine All Items"

Split

split

Divide un array in elementi singoli per processamento parallelo.

Configurazione

CampoTipoObbligatorioDescrizione
labeltextNome identificativo
inputexpressionArray da splittare
batchSizenumberNoElementi per batch
parallelismnumberNoMax esecuzioni parallele

Workflow Esempio: Batch Processing

Diagramma di flusso

Configurazione
type: split
input: "{{database.output.users}}"
batchSize: 50
parallelism: 5
label: "Split Users into Batches"

Output (per ogni iterazione):

{
  "batch": [...],  // 50 elementi
  "batchIndex": 0,
  "totalBatches": 20,
  "isFirst": true,
  "isLast": false
}

Delay

delay

Introduce un ritardo nell’esecuzione.

Configurazione

CampoTipoObbligatorioDescrizione
labeltextNome identificativo
durationnumberDurata in millisecondi
unitselectNoUnità (ms, s, m, h)
untildatetimeNoAttendi fino a data/ora

Use cases

ScenarioConfigurazione
Rate limiting API5000ms tra chiamate
Retry backoff30s prima di retry
Scheduled actionuntil: 2024-01-15T09:00:00
Polling interval60s tra check

Workflow Esempio: Retry with Backoff

Diagramma di flusso

Configurazione exponential backoff
type: delay
duration: "{{Math.pow(2, set.output.retryCount) * 1000}}"
maxDuration: 60000  # Max 60 secondi
label: "Exponential Backoff"

Set

set

Imposta variabili per uso successivo nel workflow.

Configurazione

CampoTipoObbligatorioDescrizione
labeltextNome identificativo
variablesarrayVariabili da impostare

Workflow Esempio: State Management

Diagramma di flusso

Configurazione
type: set
variables:
  - name: "counter"
    value: "{{(set.output.counter || 0) + 1}}"
  - name: "items"
    value: "{{[...set.output.items, api.output.data]}}"
  - name: "lastRun"
    value: "{{new Date().toISOString()}}"
label: "Update State"

Output:

{
  "counter": 5,
  "items": [...],
  "lastRun": "2024-01-15T10:30:00Z"
}

Logger

logger

Registra messaggi e dati per debug e audit.

Configurazione

CampoTipoObbligatorioDescrizione
labeltextNome identificativo
levelselectNoLivello log (debug, info, warn, error)
messagetextMessaggio da loggare
datajsonNoDati aggiuntivi

Livelli di log

LivelloUse case
debugDettagli tecnici per sviluppo
infoInformazioni operative normali
warnSituazioni anomale non bloccanti
errorErrori che richiedono attenzione
Configurazione
type: logger
level: info
message: "Order processed successfully"
data:
  orderId: "{{trigger.data.orderId}}"
  total: "{{api.output.total}}"
  processingTime: "{{Date.now() - trigger.timestamp}}"
label: "Log Order Processed"

Workflow Completo: ETL Pipeline

Diagramma di flusso


Best Practices

Condition nodes
  1. Nomina chiaramente ogni branch
  2. Usa switch per più di 3 casi
  3. Gestisci sempre il caso default
  4. Evita condizioni troppo complesse - splitta in più nodi
Transform nodes
  1. Preferisci operazioni built-in a custom
  2. Valida sempre l’input
  3. Gestisci null/undefined
  4. Documenta trasformazioni complesse
Parallel processing
  1. Limita parallelism per non sovraccaricare
  2. Usa batch per grandi volumi
  3. Implementa backoff per rate limiting
  4. Monitora memoria e performance