FHIR Chat · SDC Workflows · questionnaire

Stream: questionnaire

Topic: SDC Workflows


view this post on Zulip Grey Faulkenberry (Aug 14 2021 at 22:54):

I've been going through the SDC & workflow documentation, which has been really helpful, but it's missing some examples. To ensure I understand the flow as it's supposed to go, I've tried to create a couple of these examples. To start with, I have 3 questionnaires, each is named and structured the same way, as follows:

{
    "resourceType": "Questionnaire",
    "url": "http://hapi.fhir.org/baseR4/Questionnaire/quest1",
    "title": "quest1",
    "name": "quest1",
    "item": []
}

They are for children under 6 years old. The first is given to kids < 2 yo, the first 2 are given to kids < 4, and all of them if you're > 4. They are referenced using a PlanDefinition Resource:

{
  "resourceType": "PlanDefinition",
  "id": "screening-2-4-yo",
  "title": "Pediatric Screening for 2-4 year olds",
  "status": "active",
  "action": [
    {
      "title": "quest1",
      "participant": [
        {
          "type": "related-person",
          "role": {
            "coding": [
              {
                "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
                "code": "PRN",
                "display": "parent"
              }
            ]
          }
        },
        {
          "type": "patient"
        }
      ],
      "definitionUri": "http://hapi.fhir.org/baseR4/Questionnaire/quest1"
    },
    {
      "title": "quest2",
      "participant": [
        {
          "type": "related-person",
          "role": {
            "coding": [
              {
                "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
                "code": "PRN",
                "display": "parent"
              }
            ]
          }
        },
        {
          "type": "patient"
        }
      ],
      "definitionUri": "http://hapi.fhir.org/baseR4/Questionnaire/quest2"
    }
  ]
}

view this post on Zulip Grey Faulkenberry (Aug 14 2021 at 23:00):

So far looks ok? All of this is going to be triggered by a ServiceRequest. Because the order is going to come from an outside institution, we're going to record the order using a ServiceRequest (I probably could have just used a Task, but if we expand it in the future, or use it for official orders (with billing) we wanted to use a ServiceRequest. I think it would look like this:

{
    "resourceType": "ServiceRequest",
    "instantiatesCanonical": [
      "http://hapi.fhir.org/baseR4/PlanDefinition/screening-2-4-yo"
    ],
    "status": "active",
    "intent": "order",
    "priority": "routine",
    "subject": {
      "reference": "Patient/surveyPatient",
      "display": "PatientName"
    },
    "authoredOn": "2021-08-11T16:37:56.328247-04:00",
    "requester": {
      "reference": "Provider/orderingProvider",
      "display": "Organization Name"
    },
    "performer": [
      {
        "reference": "Patient/surveyPatient",
        "display": "PatientName"
      }
    ]
  }

view this post on Zulip Grey Faulkenberry (Aug 14 2021 at 23:07):

So I think my first specific question is how to pick the PlanDefinition for a specific age group, assuming we have the following:

  1. "http://hapi.fhir.org/baseR4/PlanDefinition/screening-1-2-yo"
  2. "http://hapi.fhir.org/baseR4/PlanDefinition/screening-2-3-yo"
  3. "http://hapi.fhir.org/baseR4/PlanDefinition/screening-4-5-yo"

Does that happen at this step, should it go in the PlanDefinition, or in a Task, which is about to be created?

view this post on Zulip Grey Faulkenberry (Aug 14 2021 at 23:15):

And from these a Task will be created. Now with this, is it better to create an Overarching task, with a smaller task for each individual questionnaire, or to put all questionnaires in a single task? Currently I'm keeping track of them as a single Task, like this:

{
  "resourceType": "Task",
  "status": "requested",
  "intent": "order",
  "requester": {
    "reference": "Practitioner/Alguien"
  },
  "input": [
    {
      "type": {
        "coding": [
          {
            "system": "http://hl7.org/fhir/uv/sdc/CodeSystem/temp",
            "code": "questionnaire"
          }
        ]
      },
      "valueCanonical": "http://hapi.fhir.org/baseR4/Questionnaire/quest1"
    },
    {
      "type": {
        "coding": [
          {
            "system": "http://hl7.org/fhir/uv/sdc/CodeSystem/temp",
            "code": "questionnaire"
          }
        ]
      },
      "valueCanonical": "http://hapi.fhir.org/baseR4/Questionnaire/quest2"
    }
  ]
}

view this post on Zulip Ozair Bajwa (Aug 14 2021 at 23:16):

I started the other way by creating a Task resource
I started off by creating a Task conforming to the http://build.fhir.org/ig/HL7/sdc/StructureDefinition-sdc-task.html

view this post on Zulip Ozair Bajwa (Aug 14 2021 at 23:18):

Here is my Task resource
{
"resourceType": "Task",
"id": "questionnairetask",
"meta": {
"profile": [
"http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-task"
]
},
"status": "requested",
"intent": "order",
"code": {
"coding": [{
"system": "http://hl7.org/fhir/uv/sdc/CodeSystem/temp",
"code": "complete-questionnaire"
}],
"text": "My Tasks"
},
"for": {
"reference": "Patient/2506029"
},
"authoredOn": "2016-03-10T22:39:32-04:00",
"lastModified": "2016-03-10T22:39:32-04:00",
"requester": {
"reference": "Practitioner/2506125"
},
"owner": {
"reference": "Patient/2506029"
},
"reasonCode": {
"text": "The Task is performed to render questionnaire and post the questionnaire response"
},
"input": [{
"type": {
"coding": [{
"system": "http://hl7.org/fhir/uv/sdc/CodeSystem/temp",
"code": "questionnaire"
}]
},
"valueUrl": "http://hapi.fhir.org/baseR4/Questionnaire/2506046/"
},
{
"type": {
"coding": [{
"system": "http://hl7.org/fhir/uv/sdc/CodeSystem/temp",
"code": "response-endpoint"
}]
},
"valueUrl": "http://hapi.fhir.org/baseR4/"
}
]
}

view this post on Zulip Ozair Bajwa (Aug 14 2021 at 23:20):

I was thinking of querying the Task resource for a particular patient from my client
http://hapi.fhir.org/baseR4/Task?status=requested&intent=order&requester:Practitioner.identifier=12345678901

view this post on Zulip Grey Faulkenberry (Aug 14 2021 at 23:21):

Actually that does remind me of another question. Who is the owner? I know officially it's: "Individual organization or Device currently responsible for task execution." But does that mean the patient who is completing it? If it's a child would it be the parent? If we're providing this task as a service, would WE be the owner? Would it be whoever ordered it?

view this post on Zulip Ozair Bajwa (Aug 14 2021 at 23:22):

I would think the owner is the Organization

view this post on Zulip Grey Faulkenberry (Aug 14 2021 at 23:24):

Ozair Bajwa said:

I was thinking of querying the Task resource for a particular patient from my client
http://hapi.fhir.org/baseR4/Task?status=requested&intent=order&requester:Practitioner.identifier=12345678901

So this search should find all tasks where that Practitioner is the one who requested it, but what if the Practitioner ordered a questionnaire to be completed and a lipid panel to be done? How do you think it's best to differentiate between the two?

view this post on Zulip Grey Faulkenberry (Aug 14 2021 at 23:25):

Also, how does your task know which Questionnaire to include? How is that information passed to it?

view this post on Zulip Ozair Bajwa (Aug 14 2021 at 23:27):

Basically I was thinking there will be multiple Tasks for each questionnaire and patient. which is owned by an Organization etc. and each user/patient will poll for the Task resources assigned to it by different flags, once the task is retrieved the status of the Task can be updated to "Accepted" and the QuestionnaireResponse will be be generated and the Task will be updated (Task.output) to link to the QuestionnaireResponse

view this post on Zulip Grey Faulkenberry (Aug 14 2021 at 23:28):

Will the flags be inside the Task?

view this post on Zulip Ozair Bajwa (Aug 14 2021 at 23:28):

I am sure how to define the PlanDefinition, Actions (threshold, timing etc.) and tie them to my Tasks. May be you have done that part already

view this post on Zulip Ozair Bajwa (Aug 14 2021 at 23:29):

The flags will be put of the query and we can use all searchable parameters as part of the Task resource

view this post on Zulip Ozair Bajwa (Aug 14 2021 at 23:31):

Sorry I meant part of the query

view this post on Zulip Grey Faulkenberry (Aug 14 2021 at 23:31):

Could you post an example of that?

view this post on Zulip Ozair Bajwa (Aug 14 2021 at 23:37):

Here is what I tried
http://hapi.fhir.org/baseR4/Task?status=accepted&intent=order&requester:Practitioner.identifier=12345678901

view this post on Zulip Ozair Bajwa (Aug 14 2021 at 23:37):

Looking for all Tasks with status (accepted), intent (order) and requested by a Practitioner

view this post on Zulip Grey Faulkenberry (Aug 14 2021 at 23:39):

But then you still have to look through all of the tasks to see if they're appropriate for your service

view this post on Zulip Ozair Bajwa (Aug 14 2021 at 23:45):

Yeah I would think so. Task is a sort of a shared resource, can be update by multiple systems. One would have to poll the Task Queue to determine the tasks that it can execute. Once the Task has been posted it can be cancelled, suspended by the owner so there would have to be a polling mechanism

view this post on Zulip Ozair Bajwa (Aug 14 2021 at 23:45):

Again this is my understanding

view this post on Zulip Lloyd McKenzie (Aug 15 2021 at 15:08):

I would definitely recommend a separate Task for each Questionnaire - as the status for each of them could be different. You could, if there was value, have a parent Task that grouped all of the others. The owner of the Task should be the individual who's supposed to do it. That might just be a contained RelatedPerson that says "some parent of Patient xyz", though searching for those won't be easy. Assigning it to a specific individual is easier to search, but then you're picking one person when you might not care which parent/guardian completes the form. The third option is to assign it to a Group which includes all guardians for the child, presuming you expect people to be able to search for the group.

view this post on Zulip Grey Faulkenberry (Aug 15 2021 at 16:00):

We had also discussed using RequestGroup instead of an overall Task, would that make more sense?

view this post on Zulip Lloyd McKenzie (Aug 15 2021 at 17:00):

RequestGroup is for when there's a complex action that has a single status and where the parts are inseparable. I don't think that would make sense here as the status for each of the Questionnaires could be different. It's more for orders where if you cancel one part, you must also cancel the other part.

view this post on Zulip Grey Faulkenberry (Aug 16 2021 at 02:26):

Here are two ER diagrams that we have been working with. Again, trying to put here to post examples that may be helpful. NJInCK-Portal-Specification-ED-Order-v1.png NJInCK-Portal-Specification-ED-Order-v2.png

view this post on Zulip Ozair Bajwa (Aug 16 2021 at 03:19):

I am looking at the PlanDefinition. It is still a little vague to me. The Guide does not have many relevant examples. I was thinking of going with the approach of Different Tasks for each Questionnaire. So 5 tasks for 5 questionnaires. How will that map to the PlanDefiniition, looking at your Diagram it says 1 to many relationship to the Questionnaires

view this post on Zulip Ozair Bajwa (Aug 16 2021 at 03:23):

On the PlanDefinition page http://hl7.org/fhir/R4/plandefinition.html
Under Applying a PlanDefinition Section it says
Questionnaire: Set the resource element of the action to the Questionnaire, indicating that the activity to be performed is filling out the given questionnaire

view this post on Zulip Ozair Bajwa (Aug 16 2021 at 03:29):

Under the action there are trigger and condition attributes. Can we use those to trigger/start the process

view this post on Zulip Lloyd McKenzie (Aug 16 2021 at 13:30):

@Grey Faulkenberry A few comments:

  • Person is never allowed to be owner of Task. (In fact, Person isn't allowed to be referenced anywhere - Person is used to link resources, it can't ever be an actor. Human/animal actors are always one of Patient, RelatedPerson or Practitioner.)
  • The link from Task to Questionnaire is going to be 1..1. If you want multiple Questionnaires to be completed, you'll need multiple Tasks. (Because completion of each response will be tracked independently. One could be completed while another is refused.)
  • RequestGroup means that the individual ServiceRequests can't have an independent status. I.e. they can't be cancelled, put on hold or marked as complete except as a group - that seems unusual?
  • The use of ServiceRequest is optional. You can ask people to fill out forms without there being a formal authorization (i.e. a ServiceRequest). It's fine to support it, but be sure you need it before making it mandatory
  • You might want to point to ActivityDefinitions rather than PlanDefinition so that you can refer to the specific aspects of the PlanDefinition that refer to the step for that particular form. However, that's also not critical because the Task will indicate the Questionnaire.

view this post on Zulip Grey Faulkenberry (Aug 16 2021 at 16:08):

@Lloyd McKenzie , does this look closer to how the resources should be linked? Fhir-Workflow-1.png

view this post on Zulip Lloyd McKenzie (Aug 16 2021 at 16:17):

I don't understand what 'Order' is. While you can have a Task that just says "instantiate plan XYZ", that's a level of sophistication that many fillers won't have. It's really a question of how much work do you expect the requesting system to do, vs. how much do you expect the filling system to do. For simple clients, just giving them the simple Tasks of "Fill out form 1", "Fill out form 2", etc. is going to work better than "Please instantiate protocol 123" and having them figure out that means generating sub-tasks to fill out each form. However, if your clients are sophisticated enough to manage the process, then yes, the layout you've described is viable.

view this post on Zulip Grey Faulkenberry (Aug 16 2021 at 16:20):

Sorry, the order is the request from outside the system that is going to trigger the workflow

view this post on Zulip Grey Faulkenberry (Aug 16 2021 at 16:22):

We're actually going to be the ones implementing this whole workflow, so we can make them more sophisticated where needed. I'm just trying to decide how to stay within the FHIR specs as much as possible, and ensure we're following the SDC workflow correctly.

view this post on Zulip Grey Faulkenberry (Aug 16 2021 at 16:25):

(I'm hoping that by having as much of the workflow as possible within the FHIR resources, it can make us more flexible when working with other systems)

view this post on Zulip Lloyd McKenzie (Aug 16 2021 at 16:33):

Request from outside can/should still be represented as a ServiceRequest.

SDC doesn't really get into linkage to PlanDefinition/ActivityDefinition at all. It's primarily focused on the detailed Task that says "please fill out form X" The higher level protocol stuff isn't really Questionnaire-specific.

view this post on Zulip Grey Faulkenberry (Aug 16 2021 at 16:38):

Is there somewhere else that would be better for me to look regarding this workflow? (or at least a different heading for this stream?)

view this post on Zulip Lloyd McKenzie (Aug 16 2021 at 16:39):

@Bryn Rhodes

view this post on Zulip Bryn Rhodes (Aug 16 2021 at 18:55):

The FHIR Clinical Guidelines IG provides several different profiles of PlanDefinition to support different process modeling, a pathway for longitudinal processes, a strategy for processes related to a particular focus (such as an encounter or a procedure), and a recommendation for rules such as decision support logic. There's a discussion of workflow in CPG here: https://hl7.org/fhir/uv/cpg/documentation-approach-12-06-cpg-common-pathway.html

view this post on Zulip Ozair Bajwa (Aug 16 2021 at 22:51):

My workflow is similar to @Grey Faulkenberry except the trigger for the Tasks.
I have multiple questionnaires each tied to a Task. I am thinking of a PlanDefiintion with multiple actions for each questionnaire. However the client/Form Filler will be a rendered a specific questionnaire based on a certain predefined criteria/threshold. Client will be interfacing with a Personal Health Device or access other resources at its disposal to gather the Vitals, Pulse etc. Now if one of the measurements generates a trigger (i.e. pulse is more than 100) then a specific questionnaire will be rendered and filled. The rest of the workflow should be similar. Where will the trigger conditions of the workflow defined? I see trigger and condition elements under action, is that where this is defined? I could not find any relevant examples.

view this post on Zulip Ozair Bajwa (Aug 16 2021 at 23:18):

if I am able to handle all trigger data from within the app (e.g. access to all measurements). Would it be acceptable to isolate that logic from within the workflow to the app itself?

view this post on Zulip Lloyd McKenzie (Aug 17 2021 at 01:26):

You don't have to represent the logic in a PlanDefinition. The only reason for doing that is if the logic needs to be shared to multiple other systems. You probably want a separate Task for each Questionnaire, as you'd want to monitor the completion of each independently.

view this post on Zulip Brian Postlethwaite (Jan 08 2022 at 08:54):

I'm creating a UI for Task at the moment and discovered that there is a lastModified property in it as well as the lastUpdated in the meta, what's the difference?
And when would you not update the lastModified - or is that for when you're distibuting the task between servers (and the lastModified is the lastUpdated from the source system?)

view this post on Zulip Lloyd McKenzie (Jan 09 2022 at 21:00):

I guess lastUpdated is server-specific, while lastUpdated would be across servers. Though I don't know that Tasks will typically live on multiple servers...


Last updated: Apr 12 2022 at 19:14 UTC