Documentation / Conception / Guides pratiques / Choose which events start a workflow

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:

    1. 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;
    2. content and connectionId for a trigger fed by an EAI connection;
    3. eventId and occurredAt.

    Each entry reads path · example value when 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, Number equals, differs from, > ≥ < ≤, is set, is absent
    Boolean equals, differs from, is set, is absent
    String, Code, DateTime, coded types equals, 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,0 is written 6), 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

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.

97 documents12 sectionssource : /docs · généré au build