Stream: questionnaire
Topic: SDC Workflows
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"
}
]
}
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"
}
]
}
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:
- "http://hapi.fhir.org/baseR4/PlanDefinition/screening-1-2-yo"
- "http://hapi.fhir.org/baseR4/PlanDefinition/screening-2-3-yo"
- "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?
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"
}
]
}
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
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/"
}
]
}
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
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?
Ozair Bajwa (Aug 14 2021 at 23:22):
I would think the owner is the Organization
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?
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?
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
Grey Faulkenberry (Aug 14 2021 at 23:28):
Will the flags be inside the Task?
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
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
Ozair Bajwa (Aug 14 2021 at 23:31):
Sorry I meant part of the query
Grey Faulkenberry (Aug 14 2021 at 23:31):
Could you post an example of that?
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
Ozair Bajwa (Aug 14 2021 at 23:37):
Looking for all Tasks with status (accepted), intent (order) and requested by a Practitioner
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
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
Ozair Bajwa (Aug 14 2021 at 23:45):
Again this is my understanding
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.
Grey Faulkenberry (Aug 15 2021 at 16:00):
We had also discussed using RequestGroup instead of an overall Task, would that make more sense?
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.
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
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
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
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
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.
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
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.
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
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.
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)
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.
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?)
Lloyd McKenzie (Aug 16 2021 at 16:39):
@Bryn Rhodes
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
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.
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?
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.
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?)
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