absences list is sick leave or care of a sick child and
falls inside the month held in period. Use it on a Flow Guard to skip the variable-salary sync.
salary_amount from the switch’s
subject (the employee).
- The Expression node, which brings the language into any data engine: a property mapping, a sync condition, an inner graph.
- Rule mode on the flow decision nodes. Flow Switch, Flow Filter and Flow Transform have a Decide by setting, Rule or Inner engine; Flow Guard has a rule holds option under Bail when. In rule mode the node’s inner graph is kept but not used, so you can switch back without losing anything.
Names
A rule reads values by name. A name resolves, in this order, to:it— the current item inside awhere(see below).- A field of that item, when inside a
where. - A wired port of the Expression node (
input,a,b,c,d). - An attribute of the subject — the node’s Subject assign, the guard’s Assign, the
filter’s current item (which is also
itin a filter rule), or the data engine’s record.salary_amounton an employee subject reads their salary. - A flow assign —
employee,absences,period, whatever earlier nodes wrote.
employee.salary_amount, period.from, it.start_date. A
custom property has a quoted name: employee."Cost Center", or subject."Cost Center" when
you are reading the subject directly. subject always means the subject; today is the date
the rule runs on.
A name the rule cannot find is an error, never a silent empty value, so a typo cannot pass as
“no data”. A field that exists but holds nothing is nil, because missing data is normal.
Dated properties
An employee’s salary has a history. Readingsalary_amount gives you the value effective
today. To pick another moment, use @:
These are the same moments the Assert, Any and Refute nodes offer, so a rule and a guard next
to it mean the same thing by the same words.
When an entry starts
Every entry in a history starts on a date.valid_from(x) reads that date instead of the value,
and entry_id(x) reads the entry’s id (the id that keeps, for example, two employments apart).
Put the @ after the call to choose the entry:
An entry without a start date has held since forever, so
valid_from gives nothing for it, and
nothing is neither before nor after any date. To keep syncing employees for two months after
they leave:
Comparing
=, !=, <, <=, >, >=, in, not in, and ~= (a case-insensitive pattern). and,
or, not combine them; parentheses group.
A ~= pattern reads Swedish and other non-English letters as letters: "måleri" matches
“MÅLERI”, and . stands for one letter, so "m.leri" matches “Måleri”.
Comparison is forgiving where source data is messy: 123 = "123", 1 = 1.0,
"sick_leave" matches the stored code whether it arrived as text or a symbol, and a date
compares with its 2026-01-01 text. x = blank is true for nothing, an empty text, or an
empty list. Ordering against a missing value is simply false. Ordering a text against a number
is an error.
in takes a list (x in ["a", "b"]), a date range (it.start_date in period), or a text
("ab" in "cabin"). from .. to builds a date range from two dates.
Lists: where and it
absences where twine_time_type = "sick_leave" keeps the items of a list for which the
condition holds. Inside the condition the item’s fields are in scope by their bare names, it
is the item itself, and other assigns are still reachable.
For a list of employees those bare names are the employee’s properties, the same names the
property mapper shows: employees where salary_amount > 40000,
employees where employment_terminated = false and "Cost Center" = "1200" (a custom property
in quotes). A record’s base fields are reachable too, after its properties: id, active_status,
manager_id. The @ selectors work on them as anywhere else:
employees where salary_amount @ period.from > 40000.
Functions summarise a list: count(...), any(...), all(...), sum(...), min(...),
max(...), avg(...), first(...), last(...). A field read on a list reads it on every item,
so sum(absences.minutes) adds up every day of every absence.
A dotted path also works on a function’s result:
first(absences where twine_time_type = "sick_leave").start_date reads the start date of the
first sick-leave absence. first and last keep the list’s own order. On an empty list they
give nothing, and so does any field read on that nothing.
Choosing and calculating
if condition then value else value picks one of two values; chain with else if. A Flow
Switch rule yields the name of the branch to take:
true or false picks the branch named so.
Arithmetic uses +, -, *, /. A calculation on a missing value is missing; dividing by
zero is an error.
Functions
The editor’s Names and functions panel under every rule field lists them all. The ones you will reach for most:- Dates:
days_between(a, b),add_days(d, n),add_months(d, n),start_of_month(d),end_of_month(d),year(d),month(d),day(d),weekday(d),date(text). - Ranges:
range(from, to),days(range),overlaps(a, b),within(x, range),days_in(x, range). A record with start and end dates (an absence, a schedule) counts as a range, sooverlaps(it, period)works directly on an absence. - Text:
trim,lower,upper,starts_with,ends_with,replace,matches,concat,to_string. - Numbers:
round(n, digits),floor,ceil,abs,div,mod,number(text). - Fallbacks:
coalesce(a, b, ...)gives the first value that is not blank;is_blank(x). - History:
valid_from(x)andentry_id(x), see When an entry starts.