onaio / fhir-tooling

A command line utility to support FHIR Core content authoring
Other
2 stars 1 forks source link

Add a `retcon` web service that processes specific QRs on submission to modify and generate resources that would have been created if they had submitted on a device with the appropriate context #67

Open pld opened 10 months ago

pld commented 10 months ago

Building on this server-side reconciliation discussion, when I am a HCW who submits a info recording form with limited details for a patient that I do not have on my device, I want the appropriate information to be created when I sync this form to the server where the correct details exist.

This issue is to create a new web service to make a submitted QR "retroactively consistent", hence the name retcon with all the actions that would have happened were the action taken in the standard fashion with the patients data available.

High level steps:

  1. Create a new folder retcon in the root of this repo, for all the web service files to live in
  2. Create code to read QRs and modifies/creates other resources that runs once on execution as a script
  3. Add an open channel to receive a QR and execute when received

NB: you are going to need helper and sub functions, the pseudocode is not comprehensive and will need to be restructured

Details on 2: main code to read QRs and modify/create other resources

  1. Hard code config properties for
    • FHIR API root endpoint
    • FHIR API credentials
  2. Create a function loadQuestionnaireResponse(string: path) that reads a QR from disk (we'll figure out how to extend this later) and calls processQuestionniareReponse([JSON of the QR])
  3. Create a function processQuestionnaireResponse(json: questionnaireReponseJson) that
    • fetch the ZEIR ID from the QR
      • construct a Query against the FHIR API to fetch the Patient resource with this ZEIR ID
      • if the API returns 0 or >1 records
        • output a log message with the number of records returned
        • update QR.status to be entered-in-error
        • PUT the updated QR to the FHIR API
        • return from this function
      • else
        • store the single Patient in a var
        • fetch all the Tasks associated with this Patient and put in a var
        • fetch all the active CarePlans associated with this Patient and put in a var
    • load the Questionnaire from them FHIR API based on the ID in the QR
    • for each answer in the "Which vaxes were provided" question of the QR
      • fetch the SNOMED code for this answer from the Questionnaire for this option
      • search task var for all the Tasks that are in an active state and with this code, for each of them
        • set the status to completed, make sure this is stored in task var too
        • PUT the updated Task to the FHIR API
    • for each CarePlan in the careplan var
      • find all it's linked tasks from the task var
      • if all of them are in the completed state
        • update the careplan to be in the completed state
        • PUT the update CarePlan to FHIR API
f-odhiambo commented 10 months ago

Here is a sample Questionnaire and QR for the Out of service

{
  "resourceType": "Questionnaire",
  "language": "nb-NO",
  "status": "draft",
  "publisher": "NHN",
  "meta": {
    "profile": [
      "http://ehelse.no/fhir/StructureDefinition/sdf-Questionnaire"
    ],
    "tag": [
      {
        "system": "urn:ietf:bcp:47",
        "code": "nb-NO",
        "display": "Bokmål"
      }
    ],
    "security": [
      {
        "code": "3",
        "display": "Helsehjelp (Full)",
        "system": "urn:oid:2.16.578.1.12.4.1.1.7618"
      }
    ]
  },
  "contact": [
    {
      "name": "http://www.nhn.no"
    }
  ],
  "subjectType": [
    "Patient"
  ],
  "extension": [
    {
      "url": "http://helsenorge.no/fhir/StructureDefinition/sdf-sidebar",
      "valueCoding": {
        "system": "http://helsenorge.no/fhir/ValueSet/sdf-sidebar",
        "code": "1"
      }
    },
    {
      "url": "http://helsenorge.no/fhir/StructureDefinition/sdf-information-message",
      "valueCoding": {
        "system": "http://helsenorge.no/fhir/ValueSet/sdf-information-message",
        "code": "1"
      }
    },
    {
      "url": "http://helsenorge.no/fhir/StructureDefintion/sdf-itemControl-visibility",
      "valueCodeableConcept": {
        "coding": [
          {
            "system": "http://helsenorge.no/fhir/CodeSystem/AttachmentRenderOptions",
            "code": "hide-help",
            "display": "Hide help texts"
          },
          {
            "system": "http://helsenorge.no/fhir/CodeSystem/AttachmentRenderOptions",
            "code": "hide-sublabel",
            "display": "Hide sublabel texts"
          }
        ]
      }
    }
  ],
  "id": "01dddee0-1c10-47ac-8b75-5fbea790a15a",
  "item": [
    {
      "linkId": "3ec7e49b-b60f-4e67-f5ed-bd7d18cf3943",
      "type": "string",
      "text": "ZEIR ID",
      "required": false
    },
    {
      "linkId": "7a27ab63-6a6f-499d-8a70-a356cf23da38",
      "type": "date",
      "text": "Date of Service",
      "extension": [
        {
          "url": "http://ehelse.no/fhir/StructureDefinition/sdf-maxvalue",
          "valueString": "today()"
        }
      ],
      "required": false
    },
    {
      "linkId": "d9c2e3e3-8415-44bd-8317-f573586a4943",
      "type": "choice",
      "text": "Which vaccinations were provided?",
      "required": false,
      "answerOption": [
        {
          "valueCoding": {
            "id": "3869a41b-6978-4c43-979f-54ef77cfa83e",
            "code": "001",
            "system": "http://snomed.info/sct",
            "display": "OPV"
          }
        },
        {
          "valueCoding": {
            "id": "3e7d846b-b278-4bbf-c4f4-d13f083ebe5d",
            "code": "002",
            "system": "http://snomed.info/sct",
            "display": "BCG"
          }
        },
        {
          "valueCoding": {
            "id": "5746775c-bc71-4e11-85fd-ede99915671f",
            "code": "003",
            "system": "http://snomed.info/sct",
            "display": "OPV 1"
          }
        },
        {
          "valueCoding": {
            "id": "0ef61589-f051-4548-87e9-da54ef0d583d",
            "code": "004",
            "system": "http://snomed.info/sct",
            "display": "Penta 1"
          }
        },
        {
          "valueCoding": {
            "id": "803a834f-9f98-4842-9f02-473df681bb57",
            "code": "005",
            "system": "http://snomed.info/sct",
            "display": "PCV 1"
          }
        },
        {
          "valueCoding": {
            "id": "d8e53818-51ca-4d0c-8f03-a27e47d30271",
            "code": "006",
            "system": "http://snomed.info/sct",
            "display": "Rota 1"
          }
        },
        {
          "valueCoding": {
            "id": "5b2e0a9f-3bcd-4c56-cdf8-89bfa656ecbb",
            "code": "007",
            "system": "http://snomed.info/sct",
            "display": "OPV 2"
          }
        },
        {
          "valueCoding": {
            "id": "e75d4a12-836f-4aad-c46e-bdff4050b4fb",
            "code": "008",
            "system": "http://snomed.info/sct",
            "display": "Penta 2"
          }
        },
        {
          "valueCoding": {
            "id": "22e5c76e-1fee-4055-84d3-7dcce6cdc256",
            "code": "009",
            "system": "http://snomed.info/sct",
            "display": "PCV 2"
          }
        },
        {
          "valueCoding": {
            "id": "04ee6c59-90a2-4f70-b081-b1c7f23f074e",
            "code": "010",
            "system": "http://snomed.info/sct",
            "display": "Rota 2"
          }
        },
        {
          "valueCoding": {
            "id": "60ecaadd-8db1-4518-beb7-36105f9862db",
            "code": "011",
            "system": "http://snomed.info/sct",
            "display": "OPV 3"
          }
        },
        {
          "valueCoding": {
            "id": "d6530433-e4a7-4d72-8aef-8295957fbaeb",
            "code": "012",
            "system": "http://snomed.info/sct",
            "display": "PCV 3"
          }
        },
        {
          "valueCoding": {
            "id": "f4792b9f-f54c-4104-8011-9e3b7d8ad6ac",
            "code": "013",
            "system": "http://snomed.info/sct",
            "display": "Penta 3"
          }
        },
        {
          "valueCoding": {
            "id": "4449a8b2-b523-4326-9d38-7debb176bfe7",
            "code": "014",
            "system": "http://snomed.info/sct",
            "display": "IPV"
          }
        },
        {
          "valueCoding": {
            "id": "1c159f21-7370-4ea1-85f9-bc3bd8486a4f",
            "code": "015",
            "system": "http://snomed.info/sct",
            "display": "MR 1"
          }
        }
      ],
      "extension": [
        {
          "url": "http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl",
          "valueCodeableConcept": {
            "coding": [
              {
                "system": "http://hl7.org/fhir/ValueSet/questionnaire-item-control",
                "code": "check-box"
              }
            ]
          }
        }
      ]
    }
  ]
}

Here is a sample QR for the Out of service

{
   "resourceType": "QuestionnaireResponse",
   "id": "6fbf1a75-0220-4ca4-9fd4-d9ea7c570b64",
   "questionnaire": "Questionnaire/OutOfService",
   "status": "completed",
   "subject": {
      "reference": "Patient/b298f30a-5434-4ab6-a88e-10a15d3e74e7"
   },
   "authored": "2023-09-14T10:32:58+03:00",
   "item": [
      {
         "linkId": "3ec7e49b-b60f-4e67-f5ed-bd7d18cf3943",
         "text": "ZEIR ID",
         "answer": [
            {
               "valueString": "987239487"
            }
         ]
      },
      {
         "linkId": "7a27ab63-6a6f-499d-8a70-a356cf23da38",
         "text": "Date of Service",
         "answer": [
            {
               "valueDate": "2023-10-13"
            }
         ]
      },
      {
         "linkId": "d9c2e3e3-8415-44bd-8317-f573586a4943",
         "text": "Which vaccinations were provided?",
         "answer": [
            {
               "valueCoding": {
                  "code": "001",
                  "display": "OPV",
                  "system": "http://snomed.info/sct"
               }
            },
            {
               "valueCoding": {
                  "code": "002",
                  "display": "BCG",
                  "system": "http://snomed.info/sct"
               }
            }
         ]
      }
   ]
}

QR

{
   "resourceType": "QuestionnaireResponse",
   "id": "6fbf1a75-0220-4ca4-9fd4-d9ea7c570b64",
   "questionnaire": "Questionnaire/OutOfService",
   "status": "completed",
   "subject": {
      "reference": "Patient/b298f30a-5434-4ab6-a88e-10a15d3e74e7"
   },
   "authored": "2023-09-14T10:32:58+03:00",
   "item": [
      {
         "linkId": "3ec7e49b-b60f-4e67-f5ed-bd7d18cf3943",
         "text": "ZEIR ID",
         "answer": [
            {
               "valueString": "987239487"
            }
         ]
      },
      {
         "linkId": "7a27ab63-6a6f-499d-8a70-a356cf23da38",
         "text": "Date of Service",
         "answer": [
            {
               "valueDate": "2023-10-13"
            }
         ]
      },
      {
         "linkId": "d9c2e3e3-8415-44bd-8317-f573586a4943",
         "text": "Which vaccinations were provided?",
         "answer": [
            {
               "valueCoding": {
                  "code": "001",
                  "display": "OPV",
                  "system": "http://snomed.info/sct"
               }
            },
            {
               "valueCoding": {
                  "code": "002",
                  "display": "BCG",
                  "system": "http://snomed.info/sct"
               }
            }
         ]
      }
   ]
}