Tuesday, August 28, 2012

The Design of FHIR Prescription Resource

Below is the summary of the recent discussion wrt FHIR Prescription resource, mainly centered on the following design considerations

  • Granularity of resource and transaction scope
  • How should resources be aggregated for batch PUT submission

Pls bear in mind that current Prescription resource design is not final, there will be further discussion during the upcoming HL7 WGM and the Connectathon.

I put up the key points and my personal opinions here to facilitate further discussion if needed.

 1.  Granularity of resources and transaction scope
 In the figure below copied from FHIR v0.0.5, each  Prescription resource contains only one medicine, whereas in both HL7 v3 and IHE pharmacy it is following the common practice - one prescription contain multiple medicines.




Based on FHIR design principles explained in FHIR overview, resources are the smallest unit of operation and a transaction scope of their own, so in Prescription resource design, each prescription contains only one medicine since each medicine can have its own life cycle, resource is kept at medicine level is also easier for REST processing.

For the above design, I have two main concerns

  1. One of my concerns for the above design is that we are forcing implementers to send 'patient' and 'prescriber' repeatedly if a doctor prescribes multiple medications at one go. 
  2. Another concern is that the XML payload becomes bigger due to repeated data elements, and more critically it leads to processing inefficiency and overhead in REST PUT.

After clarification with key designers of FHIR, I came to know that we can potentially use aggregation mechanism to combine multiple Prescription resources if there are multiple medicines prescribed at one go as shown in below pseudo-XML. Yello-color highlighted XML content is repeated if we need to aggregate multiple prescription resources at one go.

<?xml version="1.0" encoding="UTF-8"?>
<CombinedMedicationPrescription>

    <prescriptionId><id>1.2.36.146595217.4.19.1.3141.20121202001</id></prescriptionId>
    <patient>  
        <type>Patient</type> <id>23453</id>
    </patient>
    <prescriber>
        <type>Agent</type> <id>567</id>
   </prescriber>


   <prescriptionReference>    <!-- Reference to first prescription --> </prescriptionReference>
   <prescriptionReference>    <!-- Reference to seond prescription --> </prescriptionReference>

   <prescription>
      <prescriptionItemId><id>1.2.
36.146595217.4.19.1.3141.1.1</id></prescriptionItemId>
      <patient>
            <type>Patient</type> <id>23453</id>
      </patient>
      <prescriber>
            <type>Agent</type> <id>567</id>
      </prescriber>
      <prescribed>2011-03-04T11:45:33+01:00</prescribed>
      <dispense>
          <dispenser>
                <type>Organization</type> <id>784</id>
          </dispenser>
      </dispense>

      <medicine> .... . </medicine>
  </prescription>
   <prescription>
    <prescriptionItemId><id>1.2.
36.146595217.4.19.1.3141.1.2</id></prescriptionItemId>
      <patient>
            <type>Patient</type> <id>23453</id>
      </patient>
      <prescriber>
            <type>Agent</type> <id>567</id>
      </prescriber>
      <prescribed>2011-03-04T11:45:33+01:00</prescribed>
      <dispense>
          <dispenser>
                <type>Organization</type> <id>784</id>
          </dispenser>
      </dispense>

      <medicine> .... . </medicine>
  </prescription>
</
CombinedMedicationPrescription>

Use the above pseudo-XML as an example, however there will number of fine grained HTTP round trip  traffic to process the complete data in the current design where each resource is submitted one by one.

Each medication prescription has <prescriptionItemId> value for tracking individual medication prescribed.  The <CombinedMedicationPrescription> aggregate resource also has <prescriptionId> to identify the prescription number, and contains the references to the two prescription resources. (CombinedMedicationPrescription resource does not existing in current FHIR, this is resource I make up to illustrate the point).

When the system receives the REST PUT from client end, since it can't create the <CombinedMedicationPrescription> resource without the resource reference to the individual prescription. So instead the client needs  to submit multiple HTTP PUT first to create the <prescription> child resource for each medication prescribed,  and then the final HTTP PUT to create the <CombinedMedicationPrescription> aggregate resource with attributes such as prescriptionId and resource references to the previously created <prescription> resource.

So the number of network level transactions involved for prescription is N+1 where N is the number of medicine prescribed.

 
For this issue, it is good to hear that FHIR will consider a batch put after Connectathon. so this solves one part of my concerns.



2. How should resources be aggregated for Batch PUT submission

Batch PUT solves one part of the problems, it reduces network traffic, overall transaction will be more efficient and easier to perform business validation since all the data is contained in one transaction instead of being split out into different transactions.

However we still have not solved the data duplication issue yet, how we can solve? One approach to use the default Context Conduction mode used in HL7 CDA - inherit from certain attributes from parent unless being overridden at child level.

Let me try to illustrate the point below using my earlier example for HTTP PUT, instead of specifying resource reference such as patient and prescriber, instead we choose to allow these XML element to be null, or we can create another code for "dataAbsent" XML attribute to indicate it is not overridden at this level.

<?xml version="1.0" encoding="UTF-8"?>
<
CombinedMedicationPrescription>
    <prescriptionId><id>1.2.36.146595217.4.19.1.3141.20121202001</id></prescriptionId>
    <patient>  
        <type>Patient</type> <id>23453</id>
    </patient>
    <prescriber>
        <type>Agent</type> <id>567</id>
   </prescriber>
   <prescriptionReference/>  
   <prescriptionReference/>   

   <prescription>
      <prescriptionItemId/>

      <patient/>
      <prescriber/>
      <dispense>
          <dispenser/>
      </dispense>

      <medicine> .... . </medicine>
  </prescription>
   <prescription>
    <prescriptionItemId/>
       <patient/>
      <prescriber/>
      <dispense>
          <dispenser/>
      </dispense>

      <medicine> .... . </medicine>
  </prescription>
</
CombinedMedicationPrescription>

With the above design, then it will be very straightforward for client to compose the aggregated resource for batch PUT, for the common data elements such as patient, prescriber, date of prescription etc are specified once at aggregate resource level.

From FHIR core designers' perspective, they felt that the benefits of managing orders individually outweighs the overhead of repeating, and Context Conduction is kind of disaster in HL7v3.

I agreed that context conduction is over-complicated esp after the May 2011 ballot, but is it really possible to completely get rid of context conduction, esp the default one "OP" -  Inherit certain attribute from parent unless being overridden at child level? As a matter of fact it is very common in non-HL7v3 design environment.

Lets visualize how server side is going to process the request once it receives the batch PUT resource if the certain data elements such as prescriber and patient are repeated. When the process reaches resource reference such as prescriber at individual Prescription resource level, if the backend data model is one-to-one between prescription and medication,  then it is straightforward, it simply persists the cuurent resource data.

However if the data model is one-to-many where the prescriber is by default associated at parent level, then it needs to navigate up to batch level to check whether the prescriber at batch level is the same as the one in the current individual Prescription resource level. If prescriber value is the same, then it can safely persist the data. However if it is different, then it needs to create a new parent (primary key table) in the data model, and then persists the current resource data as its child (foreign key table), or it might just reject the whole message in this situation if business rule does not allow this kind of request where the prescriber is different between parent and child, but nevertheless it still needs to perform the above validation to ensure the received data comforms to the business validation rules.
So in nut shell, the server side still goes through the same processing mechanism similar to context conduction-"OP". Of course we can further simplify the context conduction, only propagation without the ability to override, then it is the main stream idea in typical relation database design such as order and order line item.

It is true that how data is persisted is outside FHIR concern or any exchange format design, but the design of exchange format needs to enable the efficient processing of the data on server wide regardless of the data model. With the current design, the FHIR resource is more efficiently processed if the data model is one-to-one between prescription and medicine, bulky if it is one-to-many between prescription and medicine. 

So this part of my concern still remains, what is your view?