opensrp / fhircore

FHIR Core / OpenSRP 2 is a Kotlin application for delivering offline-capable, mobile-first healthcare project implementations from local community to national and international scale using FHIR and WHO Smart Guidelines on Android.
https://opensrp.io
Apache License 2.0
56 stars 59 forks source link

Report adverse events to the patient profile page and track it using the Immunization resource as a reaction #227

Closed f-odhiambo closed 3 years ago

f-odhiambo commented 3 years ago

Once a patient has received the 1st dose of the vaccine, we can start tracking any reactions/symptoms that they exhibit post getting either the first shot or the second shot for a dual dose vaccine. The report adverse event will be recorded/updated onto the Immunization resource as a reaction i.e. Details of a reaction that follows the immunization.

  1. A list of adverse effects can also be found here
  2. What to Do if You Have an Allergic Reaction After Getting A COVID-19 Vaccine
  3. SNOMED CT Browser for codable concepts/ condition search

The reaction field has a cardinality of 0..*

This will be captured using the following fields

  1. Date - When reaction started as a DateTime field
  2. Detail
  3. Reported - Boolean - Indicates self-reported reaction

Acceptance criteria

Add Reaction

View Reactions

f-odhiambo commented 3 years ago

@rowo We can have a follow up discussion about the design to support this implementation

shoaibmushtaq25 commented 3 years ago

There are few questions after reading and digesting it. @f-odhiambo

  1. Is this the final design (attached screenshot) for this issue or do we still need to modify/improve it?
  2. Where is the design for the item "Add a record adverse reaction page" in the acceptance criteria mentioned above?
shoaibmushtaq25 commented 3 years ago

Right now, Exploring Immunization resource and how to use add adverse effects as reaction of Immunization resource.

shoaibmushtaq25 commented 3 years ago

Update Explored Immunization resource to use it to track reverse effects of vaccinations. Now, waiting for respective designs to be ready. Meanwhile, I will be syncing up with @ekigamba around progress of extraction of multiple resources as we have multiple resources scenario in this Immunization case as well.

rowo commented 3 years ago

June 21 discussion with Francis

  1. Does adverse reaction need to be associated with specific dose? No.
  2. Is adverse reaction form specific to a vaccine (J&J vs Pfizer)? No.
  3. One immunization/dose can have multiple reactions.
  4. Does adverse reaction show forever? Yes.
  5. Do we need to display if someone has had an adverse reaction? Yes and read only. Doesn't impact ability to do second dose.
  6. What's on the form? 1. Date. 2. Detail (select single and an other option) 3. Reported by (self or nurse).

two additional images needed from @rowo: form and way to see adverse reaction on patient.

shoaibmushtaq25 commented 3 years ago

Here are the design for this feature https://www.figma.com/file/Ck46ofqC6kE6ISBC2YmwiI/COVID19-FHIR?node-id=1568%3A0

Screen Shot 2021-06-23 at 11 03 04 PM
shoaibmushtaq25 commented 3 years ago

Hey @f-odhiambo , Do we save these adverse effects of vaccination against a patient only on local database/ preferences or do we need to send it to server as well?

f-odhiambo commented 3 years ago

Hey @f-odhiambo , Do we save these adverse effects of vaccination against a patient only on local database/ preferences or do we need to send it to server as well?

We need to update the Immunization resource being used to track the Vaccination . Will add the foreign keys of the reactions saved as corresponding observations .

The Immunization resource will then be synced to HAPI to update the server copy

shoaibmushtaq25 commented 3 years ago

As per the conversation with @f-odhiambo , we can use Adverse Event for the purpose of tracking Adverse Events of Vaccines and link them to the Patient resource. We can track the adverse event details as follows,

  1. Date - When the event occured as a DateTime field
  2. Resulting Condition - Which is Reference to Condition
  3. We can track the conditions as code field (which is CodeableConcept) of Condition. @f-odhiambo to add these codes for different conditions.
f-odhiambo commented 3 years ago

Based on the Selected Adverse Events Reported after COVID-19 Vaccination listed here I have have found out the following codable code for the adverse events reported :

Codable concepts for the listed conditions

  1. Anaphylaxis - Concept ID: 39579001
  2. Blood clots - Concept ID: 75753009
  3. Myocarditis/Pericarditis - Not same but different conditions
  4. Myocarditis - Concept ID: 50920009
  5. Pericarditis - Concept ID: 3238004
  6. Thrombosis with thrombocytopenia does not exist in SNOMED DB
  7. Thrombosis - Concept ID: 264579008
  8. Heparin-induced thrombocytopenia (disorder) Thrombosis (disorder) - Concept ID: 111588002

Let's use the below as an official list

  1. Anaphylaxis
  2. Blood clots
  3. Myocarditis
  4. Pericarditis
  5. Heparin-induced thrombocytopenia (disorder) Thrombosis (disorder)

For the category Other - Not sure how will do this? Any thoughts @shoaibmushtaq25

shoaibmushtaq25 commented 3 years ago

I am not sure about Category Other. Is it safe to use note under Condition for other category? WDYT @f-odhiambo

f-odhiambo commented 3 years ago

Sure that's sounds good otherwise other could make things quite complicated pretty fast

shoaibmushtaq25 commented 3 years ago

Update Had a call with Jing(Google), @ekigamba and Kashyap (IPRD) today around the implementation of Adverse Events. There were two approaches which was under discussion.

  1. Immunization with reaction
  2. AdverseEvent with resultingCondition

So out of these two approaches, we were agreed to go with the approach 1 because for the approach 2, AdverseEvent has the MaturityLevel of 0 so it is not safe to use AdverseEvent right now.

After we have a consensus on using approach 1 (Immunization with reaction), we analyzed it in the way that whether we use Defitinition based extraction or Structure map based extraction to save the data. We found that, it looks difficult or even impossible to use Definition based extraction for this use case and hence we are going about using Structure map based extraction for this use case.

Jing will ask a question on FHIR chat for the similar scenario to clear that if definition based extraction can serve this or not. Also @ekigamba discussed it with @rkodev , he also agreed upon using the structure map based extraction for it.

So I am going with structure map based extraction approach.

@ekigamba Please review it and add/modify anything If I missed it. cc: @f-odhiambo @pld

shoaibmushtaq25 commented 3 years ago

Update Working on updating JSON based on the Observation Reference (detail of reaction under Immunization). Also extracting these questionnaire responses into Immunization resource and update and save the resource into FHIR engine in order to load it from FHIR engine afterwards when to show adverse events data into list view.

Learning about Fhir-Mapping language in order to make a structure map for Immunization with reaction ( for adverse events).

shoaibmushtaq25 commented 3 years ago

Hey @ekigamba , Can you please review this Structure map for adverse reaction ? I have prepared it. Also please suggest me the way that how can I test that my structure map is correct or not? Thanks in advance.

Oh, I see there is a mechanism to test structure map in your PR#390 here, I can use this sort of mechanism to test my structure map. Hope, Your PR is about to merge as it received an approval as well.

map "http://hl7.org/fhir/StructureMap/AdverseReaction" = 'Adverse Reaction of vaccine'

  uses "http://hl7.org/fhir/StructureDefinition/QuestionnaireReponse" as source
  uses "http://hl7.org/fhir/StructureDefinition/Bundle" as target
  uses "http://hl7.org/fhir/StructureDefinition/Observation as source
  uses "http://hl7.org/fhir/StructureDefinition/Immunization as target

  group AdverseReaction(source src : QuestionnaireResponse, target bundle: Bundle) {
      src -> bundle.id = uuid() "rule_c";
      src -> bundle.type = 'collection' "rule_b";
      src -> bundle.entry as entry, entry.resource = create('Immunization') as immunization then
          ExtractImmunization(src, bundle, immunization) "rule_i";
  }

  group ExtractImmunization(source src: QuestionnaireResponse, target bundle: Bundle, target immunization: Immunization) {
      src -> immunization.id = uuid() "rule_j";

      src.item as item where(linkId = 'adverse-event-reaction') -> immunization.reaction = create('BackboneElement') as immunizationReaction then {

        item.item as inner_item where (linkId = 'adverse-event-date') then {
          inner_item.answer first as ans then {
            ans.value as val -> immunizationReaction.date = val "rule_a";
          };
        };

        item.item as reaction_detail_item where (linkId = 'adverse-event-codes') -> bundle.entry as entry, entry.resource = create('Observation') as observation then {
          reaction_detail_item -> observation.id = uuid() "rule_obs_1";
          reaction_detail_item -> observation.code = evaluate(reaction_detail_item, ${"$"}this.item.answer.value) "rule_obs_2";
        };

        observation -> immunizationReaction.detail = create('Reference') as observationReference then {
         observation.id as theObservationId -> observationReference.reference = theObservationId "rule_obs_3";
         observation -> observationReference.type = "Observation" "rule_obs_4";
         } "rule_obs_5";
      }
  }
ekigamba commented 3 years ago

@shoaibmushtaq25

shoaibmushtaq25 commented 3 years ago

Hey @f-odhiambo cc: @ekigamba , Do we have flexibility to use DateTime in place of only Date on the screen below because we have date as dateTime type under reaction of Immunization resource? Actually, We are having some issues while converting dateType to dateTimeType in structure map based extraction using FHIRPath because FHIRPath doesn't support this conversion so far and they still need to implement the utility method for this conversion as we asked the question on fhir chat here.

f-odhiambo commented 3 years ago

@shoaibmushtaq25 We can change to DateTime format. Proceed

pld commented 3 years ago

Do we want users to select a time, or do we keep the UI the same so they're only entering a date but we store it as a date time?

On Sep 8, 2021, at 03:07, Francis Odhiambo Otieno @.***> wrote:

 @shoaibmushtaq25 We can change to DateTime format. Proceed

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe. Triage notifications on the go with GitHub Mobile for iOS or Android.

shoaibmushtaq25 commented 3 years ago

Do we want users to select a time, or do we keep the UI the same so they're only entering a date but we store it as a date time? On Sep 8, 2021, at 03:07, Francis Odhiambo Otieno @.***> wrote:  @shoaibmushtaq25 We can change to DateTime format. Proceed — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe. Triage notifications on the go with GitHub Mobile for iOS or Android.

I made the ui change, time to be entered by the users as shown below,

pld commented 3 years ago

This this make sense from a user perspective? Will they know the time that the adverse event took place?

On Sep 8, 2021, at 6:06 AM, Shoaib Mushtaq @.***> wrote:

Do we want users to select a time, or do we keep the UI the same so they're only entering a date but we store it as a date time? … <x-msg://1/#> On Sep 8, 2021, at 03:07, Francis Odhiambo Otieno @.***> wrote:  @shoaibmushtaq25 https://github.com/shoaibmushtaq25 We can change to DateTime format. Proceed — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe. Triage notifications on the go with GitHub Mobile for iOS or Android.

I made the ui change, time to be entered by the users as shown below, https://user-images.githubusercontent.com/12672919/132490208-104688ba-284f-4c54-b073-038b5c9aef22.jpg — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/opensrp/fhircore/issues/227#issuecomment-915102315, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAMMERET4YKSCCQ4XO5TF3UA4YUHANCNFSM46JM5YBA. Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

shoaibmushtaq25 commented 3 years ago

@pld Yeah, It's difficult to remember the exact time of the reaction. In that case, we have two options

  1. first one is showing both date and time on UI and user can enter the date and some random time of that date
  2. second one could be showing the same UI as showing before (user have to enter only the date) and we should store it as DateTime instead (as you mentioned this above)

If we wanna proceed with option 2, I may need some help on that in order to make this conversion. We are using this questionnaire for the adverse events.

QuestionnaireResponse is here, {"resourceType":"QuestionnaireResponse","item":[{"linkId":"adverse-event-reaction","item":[{"linkId":"adverse-event-codes","answer":[{"valueCoding":{"system":"https://www.snomed.org","code":"39579001","display":"Anaphylaxis"}}]},{"linkId":"adverse-event-date","answer":[{"valueDateTime":"2021-09-08T14:47:00+05:00"}]}]}]}

and my structure map for adverse events is below,

 `map "http://hl7.org/fhir/StructureMap/AdverseReaction" = 'AdverseReaction'

  uses "http://hl7.org/fhir/StructureDefinition/QuestionnaireReponse" as source
  uses "http://hl7.org/fhir/StructureDefinition/Bundle" as target
  uses "http://hl7.org/fhir/StructureDefinition/Observation" as source
  uses "http://hl7.org/fhir/StructureDefinition/Immunization" as target

  group AdverseReaction(source src : QuestionnaireResponse, target bundle: Bundle) {
      src -> bundle.id = uuid() "rule_c";
      src -> bundle.type = 'collection' "rule_b";
      src -> bundle.entry as entry, entry.resource = create('Immunization') as immunization then
          ExtractImmunization(src, bundle, immunization) "rule_i";
  }

  group ExtractImmunization(source src: QuestionnaireResponse, target bundle: Bundle, target immunization: Immunization) {
      src.id as srcId -> immunization.id = srcId "rule_j";

          src.item as item where(linkId = 'adverse-event-reaction') -> immunization.reaction = create('Immunization_Reaction') as immunizationReaction then {
            item.item as inner_item where (linkId = 'adverse-event-date') then {
          inner_item.answer first as ans then {
            ans.value as val -> immunizationReaction.date = val "rule_a";
          };
        };

        item.item as reaction_detail_item where (linkId = 'adverse-event-codes') -> bundle.entry as entry, entry.resource = create('Observation') as observation then {
          reaction_detail_item -> observation.id = uuid() "rule_obs_1";
          reaction_detail_item.answer as reactionAns -> observation.code = create('CodeableConcept') as codeableConcept then {
            reactionAns.value as reactionAnsValue -> codeableConcept.coding = reactionAnsValue "rule_obs_2_2";
          } "rule_ob_2";

         src -> immunizationReaction.detail = reference(observation) "rule_obs_3";
        };
      };
  };`

And this structure map is successfully transforming the properties into target entries (Immunization and Observation) as below, cc: @ekigamba {"resourceType":"Bundle","id":"6e331323-d41a-4f2c-9cf8-096a43140cbb","type":"collection","entry":[{"resource":{"resourceType":"Immunization","reaction":[{"date":"2021-09-08T14:47:00+05:00","detail":{"reference":"Observation/45d39df5-a5f7-4975-ae30-87c0e42e2e18"}}]}},{"resource":{"resourceType":"Observation","id":"45d39df5-a5f7-4975-ae30-87c0e42e2e18","code":{"coding":[{"system":"https://www.snomed.org","code":"39579001","display":"Anaphylaxis"}]}}}]}

pld commented 3 years ago

OK I see why this is complex, I think for now let's leave it as a DateTime and come back to it if we get push back from the users or partners on having to enter the time.

shoaibmushtaq25 commented 3 years ago

Just to clear my understanding on one thing, @f-odhiambo @pld @ekigamba We have 2 cases to report adverse events

  1. Patient who has received only first dose of vaccine (Partially vaccinated), we receive a list of immunization of size 1 in that case.
  2. Patient who has received two doses of vaccine (Fully vaccinated), we receive a list of immunization of size 2 in that case.

We show Report Adverse Event button after receiving the first dose of vaccine,

Question: What about the 2nd case , we are receiving two immunization resources with different immunization ids in that case, which one to edit for the adverse events? For example: (for 2nd case) Immunization Resource 1 Immunization id -> 74dee251-be1e-48ee-a727-e4204cd54ee7 Patient Reference -> Patient/9f2ec87c-93c4-4274-a73b-191b92bfe7ac

Immunization Resource 2 Immunization id -> 8e7fdf44-3ca6-4db0-8701-a320ed044efb Patient Reference -> Patient/9f2ec87c-93c4-4274-a73b-191b92bfe7ac

Note: We are tracking the adverse events as detail of reaction under the immunization resource.

pld commented 3 years ago

it'd make sense to me to edit the 2nd (later dated) immunization resources, if we're assuming that the adverse event is tied to the most recent immunization given, which seems reasonable

f-odhiambo commented 3 years ago

I think each adverse effect should be tagged to the immunization to which you received and reacted to. In the case of a single shot, a dual dose or a series of vaccinations, this may also apply. Not sure if this is what @pld is alluding to but tagging it to the most recent vaccine given may be erroneous. if indeed you are reacting to dose 1 and not dose 2/n

@shoaibmushtaq25 does this create complexity in querying and displaying a list of reactions i.e The reaction and which immunization you reacted to?

pld commented 3 years ago

Cool, yeah I agree with Francis, that's what I was (convolutedly) alluding to.

If the assumption that the adverse event is related to the last received dose is incorrect, then I think we'd need a UI element to select the specific dose to attach the adverse event to

On Sep 15, 2021, at 16:29, Francis Odhiambo Otieno @.***> wrote:

 I think each adverse effect should be tagged to the immunisation to which you received and reacted. In the case of s single shot, a dual dose or a series of vaccinations, this may also apply. Not sure if this is what @pld is alluding to but tagging it to the most recent vaccine may be erroneous. if indeed you are reacting to dose 1 and dose 2/n

@shoaibmushtaq25 does this create complexity in querying and displaying a list of reactions i.e The reaction and which immunization you reacted to?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe. Triage notifications on the go with GitHub Mobile for iOS or Android.

shoaibmushtaq25 commented 3 years ago

Yeah, that's a good idea @pld to have a UI element for the selection of specific dose because adverse events can be reported against a specific dose. One more thing to consider here is that the patient/specific user can report multiple adverse events as reaction against each immunization/dose because cardinality of reaction is 0..*.

In the other case, If we doesn't introduce a ui element for the selection, then we will be querying all the attached immunization resources to check the adverse events and display them in the list.

shoaibmushtaq25 commented 3 years ago

@f-odhiambo , Can you please advise that what should we do in the case of Others category? We actually talked about this earlier but later on we have changed our approach from using AdverseEvent to reaction of Immunization to track our adverse reactions when a user doesn't select a adverse reaction from a pre-populated list given below but he selects Others

  1. Anaphylaxis
  2. Blood clots
  3. Myocarditis
  4. Pericarditis
  5. Heparin-induced thrombocytopenia (disorder) Thrombosis (disorder)

Should we skip others for now or whats the better approach to cater this?

f-odhiambo commented 3 years ago

I think we can skip the other category for now till we see how other IGs are using it. We can open another ticket to track this CC @shoaibmushtaq25

f-odhiambo commented 3 years ago

@RaaziaTarique Updated the main issue description CC @shoaibmushtaq25

f-odhiambo commented 3 years ago

@RaaziaTarique @shoaibmushtaq25 Any update on this?

shoaibmushtaq25 commented 3 years ago

Hey @f-odhiambo , As @RaaziaTarique was busy with other tasks in the last few days, We will be having this knowledge transfer session today in order to facilitate her to accommodate design changes in it. Will keep you posted here.

shoaibmushtaq25 commented 3 years ago

@f-odhiambo , me and @RaaziaTarique just had a knowledge transfer session around this issue, She will be working on design changes on top of the PR #500 .