An event carries no workflow name. When one arrives — a prescription recorded, a lab result received — every published workflow whose trigger receives that event type starts its own run, unless its trigger filter excludes the event. A workflow receives a declared event with the trigger Événement reçu, the event chosen in Event (« Événement »), or with a dedicated trigger of the plugin that declares it; both kinds of workflows start on the same event. A filter restricts only its own workflow: two workflows with overlapping filters both start. This page shows how to restrict what your workflow receives and how to see what else starts on the same event. The model behind it (declared events, fan-out, run ids and duplicates) is explained in Events and triggers.
Restrict a workflow with a trigger filter
A filter (trigger.selector) is a jexl expression on the event payload, in
the expression language of the flow.guard node (see
Branch with guards and switch). The payload
is bound to event, so a field is read as event.<field>:
trigger:
type: trigger.bio-result-received
selector: event.analyte == "creatinine" && event.value > 150
With this filter, the workflow starts on a creatinine above 150 µmol/L and on
nothing else. A workflow on the same event without a filter starts on every
lab result, this one included. Without the event. prefix,
analyte == "creatinine" reads no field of the event: the console check and
publication refuse it.
The filter reads the event as received, not the trigger's outputs. Its
fields are those of the event's contract, with their JSON types, plus any
undeclared field the producer sent: event.value on BioResultReceived is a
number, while the trigger's result output is an Observation. The static check
covers the syntax, the transforms and that paths start at event, not that a
field is in the contract; on an event without the field, the path evaluates to
undefined. See
Events and triggers — what a filter reads.
A filter that fails to evaluate excludes only its workflow. A transform
applied to a value of the wrong type (event.value|length, on a number) raises
an error: that workflow does not start for that event, the incident is logged
and counted (meridian.selector.errors), and the traffic history shows a
Filter in error entry for it. The other
workflows start as usual. The console checks the filter as you type, and
publication refuses one that does not compile, an empty one (remove selector
to receive every event of the type) and a constant one that reads no field of
event.
When published workflows receive the event type but no filter keeps an event,
the event is filtered: POST /api/events answers 200 with no run, and
the traffic history shows it as Filtered. An event type that no workflow
receives at all is refused (400). See
Event ingestion API.
Default filter of an event
A plugin can declare a default filter on one of its events (defaultSelector
in contributes.events; see
Declare an event
and Plugin manifest).
It is proposed to every workflow that receives the event, whatever its trigger,
and it is never applied at run time: the workflow's own filter alone decides.
CommunicationReceived, declared by @posos/common, has
event.sender != "meridian", which reads sender, an optional String field of
the event.
The console prefills the default filter when you pick a trigger of the event, or
Événement reçu and the event, in the creation dialog (Empty or
Assistant), or change the trigger type or the event in the editor. An imported
file keeps its own filter: no default filter is added.
Publication warns when the workflow's filter does not contain the default
filter:
Événement « CommunicationReceived » : le filtre par défaut est absent du sélecteur (event.sender != "meridian").
Keep it, combined with your own conditions by &&.
Edit the filter in the console
The filter is edited in the Filter section of the trigger inspector, and in the creation dialog under Trigger. The section starts with what the filter does for this trigger: which events of the type the workflow receives, message filtering for an EAI connection, or no effect for a trigger that has its own address (webhook, schedule, sub-workflow call — a filter written by hand there is shown with Remove the filter). On Événement reçu with no event chosen, it reads Choose the event first (« Choisir d'abord l'événement. ») and checks nothing: the fields come from the event.
Two modes edit the same selector:
Guided — one condition per row: a Field, an Operator and a Value. With two rows or more, Combination chooses All conditions (
&&) or At least one condition (||). The expression produced is shown below the rows. An incomplete row is not applied: the selector keeps its last complete value.The Field list follows the trigger's event, in this order:
- for a declared event, the contract's fields in declaration order (with one level of sub-fields for a structured type), then the identifier fields of its context kinds, then the example's keys outside the contract; for an address (a trigger with its own address, such as an EAI reception), the keys of the catalogue's example (one level of sub-fields for an object), then the identifier fields of the context kinds the trigger establishes;
contentandconnectionIdfor a trigger fed by an EAI connection;eventIdandoccurredAt.
Each entry reads
path · example valuewhen the example has a value for it. The type and the required mark of a declared field are in the Declared event section, which sits above the filter in the trigger inspector (the creation dialog shows the filter without it). Other field… takes a path typed by hand.The operators follow the field's declared type:
Field type Operators Decimal,Integer,Numberequals, differs from, >≥<≤, is set, is absentBooleanequals, differs from, is set, is absent String,Code,DateTime, coded typesequals, differs from, is one of, contains, is set, is absent lists contains, is set, is absent structured types is set, is absent A DateTime field is compared as text: there is no date comparison. A number accepts a decimal comma (
6,0is written6), a text containing a backslash is written in Expression mode, and is one of takes one value per line.Expression — the jexl text itself. A selector the guided mode cannot represent (a mix of
&&and||, a filter on a list item, a function) stays in this mode.
The API checks the selector as you type (POST /api/expressions/check, nothing
is written): problems with their column, a note
Field not in the <event> contract: event.<field>. for each field the filter
reads outside the trigger's declared event (the filter stays valid; check the
spelling, see Static validation), the
result on the example event
(kept or not kept), the workflows that would receive the example event once
this one is published, and — when other published workflows receive the same
event — a note listing them with their filter and their effects (notifications,
record writes, human tasks, agent calls, sub-workflows), the effects of the
same kind as yours, and how many events of the type arrived over the last 7
days. In the creation dialog, Create waits for the check of the current
expression.
A filter that is present but empty (selector: "", for example in an imported
file) keeps no event: it counts as a filter in error. The panel shows
expression vide. and offers Remove the filter; the creation dialog's
Create stays blocked until the filter is removed or written.
The AI assistant can also propose a trigger type and a selector; the editor applies them (see Use the AI assistant).
What else starts on the same event
Publishing (or rolling back to) a version whose event other published
workflows also receive returns a non-blocking note in warnings:
- the full form at the first publication, or when another receiver has been
published since your current active version:
Les événements BioResultReceived démarrent aussi : « bio-result » : Ajouter la condition ; « renal-alert » (filtre). - the short form otherwise:
Les événements BioResultReceived démarrent aussi 2 autres workflows, sans changement depuis la version active.
In the full form, (filtre) marks a workflow with a filter and
(filtre en erreur) a workflow whose filter is empty, which starts on no
event.
Nothing is refused: several workflows on one event, with or without filters, is a normal configuration. Check the effects listed before publishing — two workflows alerting on the same fact produce two alerts. The proxy also logs, at startup, each event type that starts several workflows and the effect node types they have in common.
Two workflows started by the same event read and write the patient record in no guaranteed order: one may read a value the other has not written yet (for example a renal function that one workflow derives and another reads). Do not read what another workflow writes for the same event; put both treatments in one workflow, or call one as a sub-workflow of the other.
Meridian's own writes come back as events
A note written to the record (notify.send with toRecord) comes back as a
CommunicationReceived event through the FHIR binding, with the sender
« meridian », and starts every workflow of that event type (see
Events and triggers).
Filter these events out at the trigger:
trigger:
type: trigger.communication-received
selector: event.sender != "meridian"
This is the default filter of CommunicationReceived. A communication without a
sender passes it. A guard on the sender output inside
the graph is a second line of defence, but the run has already started.
A condition added to the record comes back as ConditionRecorded. That event has
no field that identifies the writer, and has no default filter: a
workflow on ConditionRecorded that adds a condition starts again on its own
write, unless its filter excludes that condition (by its code, for
example).
Filter the messages of an EAI connection
A workflow bound to an EAI connection receives each message of that connection
(its trigger has its own address, see
Events addressed to one workflow).
A filter selects messages as it selects events: a workflow whose filter is
false does not receive the message, and the other bound workflows do. It reads
the same event: event.content holds the source message and
event.connectionId the connection, for example
"ADT^A01" in event.content.
Send an event to one workflow
To start one workflow whatever its filter, designate it: __workflowFile in
the body of POST /api/events names the workflow file, and the Emit an
event composer does the same when a Target workflow is chosen. No other
workflow receives the event. Duplicates and redelivery are covered in
Events and triggers — run identity and duplicates.
Reading the routing table
Routing (« Routage ») in the console rail (/routing) lists, for each
event type, every published workflow that receives it, in file order, with its
filter or no filter. It is the screen that answers "why did these
workflows run?". A workflow whose filter is empty, or failed on a recent event,
carries a filter in error badge. The same page shows the Traffic history: each
event received, the workflows it started with the reason (Reason), and the
outcomes Routed, Duplicate, Filtered, Filter in error and
Rejected.
Before upgrading an instance
An operator runs the read-only routing audit before an upgrade that changes which workflows start: see Audit event routing.
Pausing a workflow
Not by emptying anything: unpublish it. It is the platform's single pause, whatever the trigger — an event-triggered workflow stops receiving events, and a scheduled one is disarmed on the scheduler. Its published versions are kept, so a rollback republishes it as it was. See Manage workflow storage.
See also
- Events and triggers — declared events, fan-out, run ids and duplicates
- Event ingestion API — the
POST /api/eventsbody, refusals, response and run ids - Organisation metadata — the lifecycle that decides which workflows receive events
- JEXL expressions — the filter's scope and what happens when it fails to evaluate
- Run and resolve — send an event and follow its runs
- Inspect loaded plugins — the declared events of each plugin and the triggers that claim them
- The open event model — declared events from the plugin author's side
- Declare an event — the contract of an event and its default filter, in a plugin
- Connecter un EAI — binding workflows to an EAI connection
- Branch with guards and switch — the same expression language, inside a workflow
- Trigger with a webhook and Schedule a workflow — the triggers that address one workflow directly
Multiple entries
A workflow may have several entry nodes, each with its own event and filter. Exactly one is selected per incoming event. See Start a workflow from several events.