Clinical Practice Guidelines
2.0.0-ballot - ballot International flag

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-ballot 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

Activity Flow

Activity Flow

General Activity Flow

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:

Unified State Diagram for Activity Workflow

Down the left side of the diagram are the activity phases:

  • Definition: Activities are specified as definitions using one of the ActivityDefinition profiles
  • Proposal: Definitions are applied to produce a proposal, or a suggestion or recommendation to perform (or not perform) a particular activity
  • Plan: The proposal is accepted or rejected by the user, resulting in a plan to perform (or not perform) the activity
  • Order: The plan is authorized by an appropriately qualified user, resulting in an order to perform (or not perform) the activity
  • Event: The order is fulfilled through actually performing the activity.

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

Valid state transitions for RequestStatus:

  • draft -> active
  • active -> on-hold
  • on-hold -> active
  • active -> completed
  • active -> revoked

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

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

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

Note that with the appropriate authority, the plan step in this process can be skipped (i.e. a proposal can transition directly to an order)

Valid state transitions for EventStatus:

  • preparation -> not-done
  • preparation -> in-progress
  • in-progress -> on-hold
  • on-hold -> in-progress
  • in-progress -> completed
  • in-progress -> stopped

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.

Activity Flow State Transition Capabilities

Update

Given a draft or active request, update the request

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)

Suspend

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)

Resume

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)

Plan

Given an active proposal, plan the proposal

Request requestApi.beginPlan(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.endPlan(Request inputPlan)
    check inputPlan.basedOn is not null
    var basedOnProposal = engine.get(inputPlan.basedOn)
    check basedOnProposal.intent = proposal
    check basedOnProposal.status = active
    check inputPlan.status in { draft | active }
    check inputPlan.intent = plan
    set basedOnProposal.status = completed
    try
        engine.save(inputPlan)
        engine.save(basedOnProposal)
    commit

Reject

Given an active request, reject the request, with or without a reason

requestApi.reject(Request inputRequest, String inputReason)
    check inputRequest.status = active
    set inputRequest.status = revoked
    set inputRequest.statusReason = inputReason
    engine.save(inputProposal)

Order

Given an active proposal or plan, order the proposal

Request requestApi.beginOrder(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.endOrder(Request inputOrder)
    check inputOrder.basedOn is not null
    var basedOn = engine.get(inputOrder.basedOn)
    check basedOn.intent in { proposal | plan }
    check basedOn.status = active
    check inputOrder.status in { draft | active }
    check inputOrder.intent = order
    set basedOn.status = completed
    try
        engine.save(inputOrder)
        engine.save(basedOn)
    commit

Entered In Error

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)

Perform

Given an active order, perform the event

Event requestApi.beginPerform(Request inputRequest)
    check inputRequest.intent = order
    check inputRequest.status = active
    var result = new Event(copy from inputRequest)
    result.status = preparation
    result.basedOn = referenceTo(inputRequest)

requestApi.endPerform(Event inputEvent)
    check inputEvent.basedOn is not null
    var basedOn = engine.get(inputEvent.basedOn)
    check basedOn.intent = order
    check basedOn.status = active
    check inputEvent.status in { preparation | in-progress }
    set basedOn.status = completed
    try
      engine.save(basedOn)
      engine.save(inputEvent)
    commit

Start

Given a preparation event, start the event

requestApi.start(Event inputEvent)
    check inputEvent.status = preparation
    set inputEvent.status = in-progress
    engine.save(inputEvent)

Not Done

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)

Stop

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)

Complete

Given an in-progress event, complete the event

requestApi.complete(Event inputEvent)
    check inputEvent.status = in-progress
    set inputEvent.status = completed
    engine.save(inputEvent)

Activity Lifecycle - Request Phases (Proposal, Plan, Order)

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.

  • The instatiates Element column is the name of the element in the resource type that provides the link from the proposal to the definition
  • The basedOn 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 plan
  • The status Element column is the name of the status element in the resource type
  • Each of the status value columns (Draft, Active, etc.) give the status values for each request resource (i.e. proposal, plan, order)
Activity Resource Type instantiates Element basedOn Element status Element Draft Active On-hold Revoked Completed Entered-in-error
Send Message CPGCommunicationRequest instantiatesCanonical basedOn status draft active on-hold revoked completed entered-in-error
Collect information CPGQuestionnaireTask instantiatesCanonical basedOn status draft in-progress on-hold failed completed entered-in-error
Order a medication CPGMedicationRequest instantiatesCanonical basedOn status draft active on-hold stopped completed entered-in-error
Dispense a medication CPGDispenseMedicationTask instantiatesCanonical basedOn status draft in-progress on-hold failed completed entered-in-error
Administer a medication CPGAdministerMedicationTask instantiatesCanonical basedOn status draft in-progress on-hold failed completed entered-in-error
Document a medication CPGDocumentMedicationTask instantiatesCanonical basedOn status draft in-progress on-hold failed completed entered-in-error
Recommend an immunization CPGImmunizationRequest instantiatesCanonical basedOn status draft active on-hold stopped completed entered-in-error
Order a service CPGServiceRequest instantiatesCanonical basedOn status draft active on-hold revoked completed entered-in-error
Enroll a patient CPGEnrollmentTask instantiatesCanonical basedOn status draft in-progress on-hold failed completed entered-in-error
Generate a report CPGGenerateReportTask instantiatesCanonical basedOn status draft in-progress on-hold failed completed entered-in-error
Propose a diagnosis CPGProposeDiagnosisTask instantiatesCanonical basedOn status draft in-progress on-hold failed completed entered-in-error
Record a detected issue CPGRecordDetectedIssueTask instantiatesCanonical basedOn status draft in-progress on-hold failed completed entered-in-error
Record an inference CPGRecordInferenceTask instantiatesCanonical basedOn status draft in-progress on-hold failed completed entered-in-error
Report a flag CPGReportFlagTask instantiatesCanonical basedOn status draft in-progress on-hold failed completed entered-in-error

Activity Lifecycle - Event Phase

The 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.

  • The 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 on
  • The status Element column is the name of the status element in the resource type
  • Each of the status value columns (Preparation, In-progress, etc) give the value of the status element for that status
Activity 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