Clinical Practice Guidelines, published by HL7 International / Clinical Decision Support. This guide is not an authorized publication; it is the continuous build for version 2.0.0 built by the FHIR (HL7® FHIR® Standard) CI Build. This version is based on the current content of https://github.com/HL7/cqf-recommendations/ and changes regularly. See the Directory of published versions
Building on the Workflow module in FHIR, this topic describes in detail how each type of activity in a computable Clinical Guideline transitions through the overall phases of the activity lifecycle, as depicted in the following diagram:
Down the left side of the diagram are the activity phases:
The proposal, plan, and order phases are all represented using the request pattern (Request State Machine), while the event phase is represented using the event pattern (Event Statement Machine).
In general, decision support services will typically produce Request resources in proposal intent with a status of draft, indicating the proposal is in need of additional information, or active, indicating the proposal is a complete recommendation, ready to be accepted or rejected.
Valid state transitions for RequestStatus:
In addition, any state can be transitioned to entered-in-error
Only active proposals can be transitioned to plans. Transitioning a proposal to a plan is expected to produce a Request resource in plan intent with a status of draft or active
Only active plans can be transitioned to orders. Transitioning a plan to an order is expected to produce a Request resource in order intent with a status of draft or active
Only active orders can be transitioned to events. Transitioning an order to an event is expected to produce an Event resource with a status of prepration or in-progress
With the appropriate authority, the plan and/or order steps in this flow can be skipped (i.e. a proposal can transition directly to an order or an event)
The draft status for requests can be used to indicate that the request is not yet complete enough to be moved to the next phase and that more information is needed to do so. This information (and the status change to active) can be provided with the Update operation.
Valid state transitions for EventStatus:
In addition, any state can be transitioned to entered-in-error
Accounting for these general state transitions, the following sections detail a proposed set of capabilities for transitioning activities through the various phases of proposal, plan, order, and event. Each capability provides a snippet of pseudo-code that describes what changes are made to resource elements by that transition. These capabilities are described in terms of the Request and Event patterns, so this is only a pattern-level description of the capability. Following the description of each capability is a set of tables that describe exactly what elements and values need to be used in these capabilities to apply each transition to the concrete resources used to represent each type of activity.
Given a draft or active request, update the request. This includes transitioning a request from draft to active status.
requestApi.update(Request inputRequest)
check inputRequest.status in { draft | active }
engine.save(inputRequest)
Given a preparation or in-progress event, update the event
requestApi.update(Event inputEvent)
check inputEvent.status in { preparation | in-progress }
engine.save(inputEvent)
Given an active request, suspend the request, with or without a reason
requestApi.suspend(Request inputRequest, String reason)
check inputRequest.status = active
set inputRequest.status = on-hold
set inputRequest.statusReason = reason
engine.save(inputRequest)
Given an in-progress event, suspend the event, with or without a reason
requestApi.suspend(Event inputEvent, String Reason)
check inputEvent.status = in-progress
set inputEvent.status = on-hold
set inputEvent.statusReason = reason
engine.save(inputEvent)
Given a suspended request, resume the request
requestApi.resume(Request inputRequest)
check inputRequest.status = on-hold
set inputRequest.status = active
set inputRequest.statusReason = null
engine.save(inputRequest)
Given a suspended event, resume the event
requestApi.resume(Event inputEvent)
check inputEvent.status = on-hold
set inputEvent.status = in-progress
set inputEvent.statusReason = null
engine.save(inputEvent)
Given an active proposal, plan the proposal:
Request requestApi.preparePlan(Request inputProposal)
check inputProposal.intent = proposal
check inputProposal.status = active
var result = new Request(copy from inputProposal)
set result.id = null
set result.intent = plan
set result.status = draft
set result.basedOn = referenceTo(inputProposal)
requestApi.initiatePlan(Request preparedPlan)
check preparedPlan.basedOn is not null
var basedOnProposal = engine.get(preparedPlan.basedOn)
check basedOnProposal.intent = proposal
check basedOnProposal.status = active
check preparedPlan.status in { draft | active }
check preparedPlan.intent = plan
engine.save(preparedPlan)
Note that this operation is performed in two steps in order to allow for application-level interation to occur. The prepare step constructs a draft plan that can then be presented in an application, and the initiate step then operates on that prepared draft plan to finalize the actual changes.
Note also that this capability applies to both a proposal for an activity, as well as a proposal not to perform. In the latter case, the creation of a request with plan intent means a plan to not perform the activity.
Given an active request, revoke the request, with or without a reason. Revoking a request indicates that the request is no longer applicable, and is typically done by the actor that originated the request. This is different than rejecting a request, which is done with the Reject operation.
requestApi.revoke(Request inputRequest, String inputReason)
check inputRequest.status = active
set inputRequest.status = revoked
set inputRequest.statusReason = inputReason
engine.save(inputProposal)
Given an active request, reject the request, with or without a reason
requestApi.reject(Request inputRequest, Task fulfillmentTask, String inputReason)
check inputRequest.status = active
check fulfillmentTask.status = requested
check fulfillmentTask.focus = inputRequest
check fulfillmentTask.code = fulfill
set fulfillmentTask.status = rejected
set fulfillmentTask.statusReason = inputReason
engine.save(fulfillmentTask)
Given an active proposal or plan, order the proposal
Request requestApi.prepareOrder(Request inputRequest)
check inputRequest.intent in { proposal | plan }
check inputRequest.status = active
var result = new Request(copy from inputRequest)
set result.id = null
set result.intent = order
set result.status = draft
set result.basedOn = referenceTo(inputRequest)
requestApi.initiateOrder(Request preparedOrder)
check preparedOrder.basedOn is not null
var basedOn = engine.get(preparedOrder.basedOn)
check basedOn.intent in { proposal | plan }
check basedOn.status = active
check preparedOrder.status in { draft | active }
check preparedOrder.intent = order
set basedOn.status = completed
try
engine.save(preparedOrder)
engine.save(basedOn)
commit
Note that this operation is performed in two steps in order to allow for application-level interation to occur. The prepare step constructs a draft order that can then be presented in an application, and the initiate step then operates on that prepared draft order to finalize the actual changes.
Note also that this capability applies to both an order for an activity, as well as an order not to perform. In the latter case, the creation of a request with order intent means an order not to perform the activity.
Given a request, mark the proposal entered-in-error, with or without a reason
requestApi.enteredInError(Request inputRequest, String reason)
set inputRequest.status = entered-in-error
set inputRequest.statusReason = reason
engine.save(inputRequest)
Given an event, mark the event entered-in-error, with or without a reason
requestApi.enteredInError(Event inputEvent, String reason)
set inputEvent.status = entered-in-error
set inputEvent.statusReason = reason
engine.save(inputEvent)
Given an active proposal, plan, or order, perform the event
Event requestApi.preparePerform(Request inputRequest)
check inputRequest.intent in { proposal | plan | order }
check inputRequest.status = active
var result = new Event(copy from inputRequest)
result.status = preparation
result.basedOn = referenceTo(inputRequest)
requestApi.initiatePerform(Event preparedEvent)
check preparedEvent.basedOn is not null
var basedOn = engine.get(preparedEvent.basedOn)
check basedOn.intent in { proposal | plan | order }
check basedOn.status = active
check preparedEvent.status in { preparation | in-progress }
set basedOn.status = completed // see completion note
try
engine.save(basedOn)
engine.save(preparedEvent)
commit
Note that this operation is performed in two steps in order to allow for application-level interation to occur. The prepare step constructs a draft event that can then be presented in an application, and the initiate step then operates on that prepared draft event to finalize the actual changes.
Whether this capability should set the status of the request to complete depends on whether the activity overall is complete. For example, if the activity is a medication prescription, whether the request should be marked complete depends on whether the dispense/administration/documentation represents a completion of the activity. Dispensing the initial fill, when there are multiple refills ordered, does not complete the overall order, so the status should remain active until all actions related to the completion of the order are done.
Note that in general, this capability is not used for requests not to perform an activity; in those cases there is typically no event resource, since the activity should not be performed.
Given a preparation event, start the event
requestApi.start(Event inputEvent)
check inputEvent.status = preparation
set inputEvent.status = in-progress
engine.save(inputEvent)
Given a preparation event, mark the event not-done (with or without a reason)
requestApi.notDone(Event inputEvent, String reason)
check inputEvent.status = preparation
set inputEvent.status = not-done
set inputEvent.statusReason = reason
engine.save(inputEvent)
Given an in-progress event, stop the event, with or without a reason
requestApi.stop(Event inputEvent, String reason)
check inputEvent.status = in-progress
set inputEvent.status = stopped
set inputEvent.statusReason = reason
engine.save(inputEvent)
Given an in-progress event, complete the event
requestApi.complete(Event inputEvent)
check inputEvent.status = in-progress
set inputEvent.status = completed
engine.save(inputEvent)
The following table summarizes the request resource types and the instantiates
, basedOn
, and status
elements and values for each activity as it moves through the activity flow.
instantiates
Element column is the name of the element in the resource type that provides the link from the proposal to the definitionbasedOn
Element column is the name of the element in the resource type that provides the link from the plan to the proposal, and from the order to the planstatus
Element column is the name of the status element in the resource typeThe following table summarizes the event reosurce types for each activity type, and the basedOn
and status
elements and values for each activity as it moves through the activity flow.
basedOn
Element column is the name of the element in the resource type that represents the link from the event resource back to the request that it is based onstatus
Element column is the name of the status element in the resource typeActivity | Resource Type | basedOn Element |
status element |
Preparation | In-progress | Not-Done | On Hold | Stopped | Completed | Entered-in-error |
---|---|---|---|---|---|---|---|---|---|---|
Send Message | CPGCommunication | basedOn | status | preparation | in-progress | not-done | on-hold | stopped | completed | entered-in-error |
Collect information | CPGQuestionnaireResponse | basedOn | status | in-progress | cancelled | on-hold | failed | completed | entered-in-error | |
Order a medication | See "Dispense a medication" \n"Administer a Medication" \n"Document a Medication" | - | - | - | - | - | - | - | - | - |
Dispense a medication | CPGMedicationDispense | authorizingPrescription | status | preparation | in-progress | cancelled | on-hold | stopped | completed | entered-in-error |
Administer a medication | CPGMedicationAdministration | request | status | in-progress | not-done | on-hold | stopped | completed | entered-in-error | |
Document a medication | CPGMedicationStatement | basedOn | status | intended | active | not-taken | on-hold | stopped | completed | entered-in-error |
Recommend an immunization | CPGImmunization | status | not-done | completed | entered-in-error | |||||
Order a service | CPGProcedure | basedOn | status | preparation | in-progress | not-done | on-hold | stopped | completed | entered-in-error |
Enroll a patient | CPGCase | status | planned | active | cancelled | onhold | finished | entered-in-error | ||
Generate a report | CPGMetricReport | status | pending | complete | error | |||||
^ | CPGCaseSummary | summaryFor | status | pending | complete | error | ||||
^ | CPGCasePlanSummary | summaryFor | status | pending | complete | error | ||||
^ | CPGCasePlanProgressingNote | summaryFor | status | pending | complete | error | ||||
Propose a diagnosis | CPGCondition | clinicalStatus and verificationStatus are present but neither map to event status | - | - | - | - | - | - | - | |
Record a detected issue | CPGDetectedIssue | status | preliminary? | cancelled | final | entered-in-error | ||||
Record an inference | CPGObservation | basedOn | status | preliminary? | cancelled | final | entered-in-error | |||
Report a flag | CPGFlag | status | active | inactive? | entered-in-error |