Using Tasks
to Manage Workflow
Introduction
Workflow is an essential part of healthcare, and healthcare operations requiring coordination of many manual steps physicians, patients, nurses, care coordinators, etc.
While the majority of FHIR resources represent clinical data that is operated on, FHIR also defines a set of workflow resources that describe and track work to be done. This guide will discuss the usage of the Task
resource, which is the basic building-block resource used to implement care plans and track workflow progress.
For example, a Task
might represent the task of having a practitioner complete a PHQ-9 questionnaire for a patient as part of their onboarding.
A common application is for organizations to build task queue systems to route tasks to the correct practitioner based on specialty, level of credential, and availability. The Medplum Task Demo application provides a minimalist task queue that demonstrates task search, assignment, and status.
Task type
The Task.code
element is used to represent the task type, equivalent to the task title. This can either be different from task to task, or selected from a standard set of task types. Using the latter approach helps enable querying across all Tasks
of the same type.
While using SNOMED or LOINC codes are preferred, many implementations simply use the Task.code.text
element, as task types are often implementation-specific.
Task.description
can be used to add additional descriptive text to the specific Task
instance.
**Example: **
{
resourceType: 'Task',
id: 'example-task',
code: {
text: 'Complete PHQ-9',
coding: [{
code: '715252007',
system: 'http://snomed.info/sct'
}]
},
description: "Patient to complete PHQ-9 depression screening",
//...
}
Task status
Designing status codes for tasks varies from implementation to implementation, and requires a good understanding of your operations.
Task
provides three fields: status
, businessStatus
, and statusReason
.
Task.status
maps to the FHIR task lifecycle shown below. It provides coarse-grained information about the activity state of a Task
and is most useful for day-to-day operations, as it allows for efficient queries on active, completed, and cancelled tasks. These queries will remain stable as your implementation scales. (Note: in the diagram below, the codes requested
, received
, accepted
, and rejected
only apply when Tasks
are shared between systems. Most implementations will just use ready
to indicate a Task
can be actioned.)
Task.businessStatus
should map to your implementation's specific operational funnel. It provides fine-grained information to help customer service and operations teams troubleshoot tasks and monitor progress. It is also useful for analytics teams to compute conversion metrics between pipeline stages.
Task.statusReason
describes why the Task
has the current status, and is most commonly used when status
is set to "on-hold"
or "cancelled"
. Using an orthogonal statusReason
allows operations teams to efficiently query for all tasks at the same point in the funnel, while analytics teams can further break down by all the reasons they may be on hold.
Task priority
Task.priority
can be used to indicate the urgency of the task. This field uses a fixed set of codes that are borrowed from acute in-patient care settings.
Code | Definition |
---|---|
routine | The request has normal priority. |
urgent | The request should be actioned promptly - higher priority than routine . |
asap | The request should be actioned as soon as possible - higher priority than urgent . |
stat | The request should be actioned immediately - highest possible priority (i.e., an emergency). |
While these terms might feel awkward in a digital health setting, Medplum recommends that implementations use these codes rather than create their own extensions in order to maintain interoperability with the ecosystem.
Task assignment
Task.for
indicates who benefits from the task, and is most commonly the patient for whom care is being delivered.
Task.owner
indicates the party responsible for performing the task. This can be either:
- An individual:
Practitioner
,PractitionerRole
,Patient
,RelatedPerson
, or - A group:
Organization
,HealthcareService
,CareTeam
You can search for all unassigned tasks using the :missing
search modifier.
- Typescript
- CLI
- cURL
await medplum.searchResources('Task', 'owner:missing=true');
medplum get 'Task?owner:missing=true'
curl 'https://api.medplum.com/fhir/R4/Task?owner:missing=true' \
-H 'authorization: Bearer $ACCESS_TOKEN' \
-H 'content-type: application/fhir+json' \
A common pattern in telehealth practices is the assignment of tasks to all practitioners with a given role (e.g., clinical specialty, level of credential, etc.). Task.performerType
is a searchable element that can be used to indicate which roles can/should perform this task.
It is a best practice to select these roles from a standard code system to promote interoperability. The US Core Guidelines recommend using the SNOMED Care Team Member Function valueset for performerType
.
In rare instances, SNOMED might not contain an appropriate code for a given role (e.g., Customer Service Representative). Medplum recommends using the Standard Occupational Classification (SOC) codes published by the Bureau of Labor Statistics.
The table below contains SNOMED codes for common roles used in digital healthcare. Use the SNOMED online browser to search for additional codes.
Name | SNOMED Code | SOC Code |
---|---|---|
Doctors | 158965000 (Doctor) | 29-1210 (Physicians) |
Nurse Practitioner | 224571005 (Nurse Practitioner) | 29-1171 (Nurse Practitioners) |
Registered Nurse | 224535009 (Registered Nurse) | 29-1141 (Registered Nurses) |
Care Coordinator | 768820003 (Care Coordinator) | 11-9111 (Medical and Health Services Managers) |
Care Team Coordinator | 768821004 (Care Team Coordinator) | 11-9111 (Medical and Health Services Managers) |
Medical Billing Specialist | 1251542004 (Medical Coder) | 29-2072 (Medical Records Specialists) |
Quality Assurance | 56542007 (Medical record administrator) | 15-1253 (Software Quality Assurance Analysts and Testers) |
Assistant | 449161006 (Physician assistant) | 29-1071 (Physician Assistants) |
Below is an example of a Task.performerType
CodeableConcept using both SNOMED and SOC systems.
{
resourceType: 'Task',
// ...
performerType: [
{
text:'Medical Billing Specialist',
coding:[
// Snomed
{
code:'1251542004',
system: 'http://snomed.info/sct',
display: 'Medical Coder'
},
// US SOC
{
code:"29-2072"
system: "https://www.bls.gov/soc"
}
],
}
]
}
Task focus
The Task.focus
element tracks the FHIR resource being operated on by this task, known as the "focal resource". See the Examples section below for examples of focal resources in common scenarios.
Well maintained Task.focus
elements are critical for data hygiene and streamlining operations and analytics . Ensuring that every Task
has a populated focus
reference will make it easier to find all touchpoints for a given clinical resource, spot operational bottlenecks, and calculate turnaround-times, conversions, and care quality metrics as your implementation scales.
Task start / due dates
The Task.restriction.period
field describes the time period over which the Task
should be fulfilled, with Task.restriction.period.end
representing the due date, and Task.restriction.period.start
representing the (potentially optional) start date.
Task completion times
The Task.executionPeriod
field describes the time period over which the Task
was actually actioned. Properly populating this field makes it easier to identify stalled tasks and compute turnaround-time metrics.
Task.executionPeriod.start
is used to store the start time of the first action taken against this task.
Task.executionPeriod.end
is used to mark the completion time of the final action taken against this task.
Task comments
Task.note
can be used to capture narrative text that is not represented elsewhere in the resource.
The most common use for this field is to record comments from the task assignee as they work on the task. When used this way, it is a best practice to include the author
and time
fields in the Annotation
.
Subtasks
Tasks
can be organized into a hierarchical structure to create subtasks. To represent this hierarchy, subtasks should reference their parent using the using the Task.partOf
element. Task.partOf
is a searchable field that can be used to query all sub-tasks of a given task, and can be combined with the _revinclude
and :iterate
directives to query the entire Task
tree.
While task hierarchy functionality is powerful, it can be complex to maintain and operationalize. Medplum recommends that most implementations start with a single-level Task
hierarchy and gradually add depth over time.
Examples
Use Case | Task Owner | Focal Resource | Example businessStatuses | Additional Info |
---|---|---|---|---|
Complete patient intake questionnaire | New Patient. Care Coordinator | Questionnaire |
| Use Task.output to reference resulting QuestionnaireResponse |
Review lab report | Physician | DiagnosticReport |
| |
Verify patient identity (e.g. driver's license) | Patient. Care Coordinator | DocumentReference |
| |
Complete encounter notes | Physician | ClinicalImpression |
| Use Task.encounter to reference the original encounter |