As discussed in the CQFlow Overview, the flow definition is a JSON representation of a flow diagram. It describes the inputs, outputs, and clinical logic that makes up a CDS flow.
A flow definition is generally authored by a clinical domain expert using the Flow Editor.
Clinical Decision Support logic tends to be complex and nuanced, and a visual representation and editor is crucial for understanding, structuring, and communicating the rules.
Creating a clinical flow can at times be as much of an art as a science. Even the most experienced clinical domain experts may iterate through several versions of a flow definition before arriving at a final version that is both accurate and intuitive.
In fact, one of our primary recommendations to those working on the flow diagrams is to focus on making the flow as intuitive as possible. Give priority to a flow that is readable, intuitive, and clinically sound over one that encompasses every technical nuance and detail. We provide this recommendation because we have found that flow diagrams that are too complex tend to be difficult to maintain or modify, or end up not being used at all. It is always possible to offload the nuance and calculations to the flow implementation, where the product and engineering teams can collect technical requirements and build software modules that are robust and maintainable through the proper use of unit tests and other software engineering best practices.
As a brief example, let's consider a flow that suggests one of 10 different types of medications to be recommended to a patient. Each medication may have different dosage instructions, choices of generics vs brand names, interactions with other medications, etc. Instead of trying to capture all of these details in the diagram itself, the diagram can paint a high level picture of the process and then lookup tables or other information structures can be used in the flow implementation to handle the details.
The flow definition is a directed graph made up of nodes and edges. The nodes each have specific purposes such as flow control or emitting data, while the edges act as connection points between the nodes.
Each flow definition starts with exactly one Start node . It may finish at many different End nodes, but every flow path must finish with an End node.
The True/False is the most basic control flow node and directs the flow path between a True or False edge. The Branch and Logic Tree nodes are built on top of the True/False node to allow for more complex logic to be expressed in a more compact and intuitive form.
Input data nodes are used to collect key data for use in calculations and decision points. Generally, a single flow may be dependent upon many aspects of a patient's medical history, however there are certain inputs that are more "key" to the flow and must be collected in order to proceed with the execution process. For instance, in the Hypertension Diagnosis example, the Systolic and Diastolic blood pressure readings were key inputs that needed to be collected.
It is always possible to auto-populate an input node using data from the patient's medical history. Depending on whether the flow implementation is interactive or non-interactive, the input node will behave differently when the data is not found.
An interactive flow implementation can surface a form component and allow the user to manually entry information.
A non-interactive flow can not present any data entry components, and must therefore either throw an error or default to a specific assumed value.
The Emit Data node is the primary node for returning information to a calling system. It can produce any type of data that is needed, although generally a JSON blob is produced. The specific data and it's shape is controlled by the flow implementation. The emitted data can then be used by calling systems to perform tasks such as presenting a specific UI, opening up an order form, scheduling an appointment, etc.
The Action node is a special output node that can be called at most once within a particular flow. There are several ways that a single node can be executed several times, such as when a user changes previous answers or when there are logical loops in the flow. In these cases, it may not make sense to submit an action over and over. As an example, we could design a flow that allows a physician to order a medication for a patient. It would only make sense to order that medication exactly one time during a flow routine, instead of unintentionally ordering it multiple times.
The Action node is not strictly necessary, and the same functionality can be achieved by using the Emit Data node. For instance, one could emit a medication request as a JSON structure, and only when the flow is complete would the calling system use that emitted data to make the medication request. The choice between the two is mostly a matter of where it makes the most sense to place the implementation logic, either during the flow execution or after the flow is complete.
Next we will take a deeper dive into the Flow Editor and the flow definition format.