Regional Shared Medications with FHIR

Let’s wrap up this ‘mini-series on medications’ by moving up a notch and considering how we could build a regional repository of patient medications, which would be shared amongst all those involved in a patients care. The idea is that the repository is the ‘single source of truth’ for patient medications. Other systems – such as a GP (or Primary/Ambulatory Care system) , or a hospital on admission/discharge – would access that repository (via FHIR interfaces) when viewing/updating medications rather than their own databases (though they would likely synchronize with rather than replace their local data source – at least initially).

The repository could also support Patient and Provider portals, as well as being ideal for mobile devices.

The picture below shows the ‘big picture’ for what I’m talking about (thanks to Orion Health for the picture):

medman

It shows a single repository of data that is intended to be utilized by all providers – and also the patient and their care givers. The repository would contain a number of different types of medication related data, for example:

  • The current list of medications (modelled as a FHIR List)
  • The MedicationPrescription resources referenced by that List
  • Dispensing (MedicationDispense) resources.

There are also a few supporting resources as detailed below. And there are many other clinical resources (eg allergies) that could be added once the infrastructure was in place.

Use cases

We’ll support the following high-level Use Cases:

  • Store dispensing records from a pharmacy. Each time a pharmacy dispenses a medication, they construct a MedicationDispense resource and save it in the repository.
  • Retrieve dispensing data for a patient over a time period. Used by a clinician when reconciling the patients’ medication list.
  • Get the patients’ current list of medications. Used by anyone involved with the patients’ care – including the patient & their care givers – such as a rest home, GP or ED department.
  • Get the history of changes to the List, and previous versions of that list.
  • Update the patients’ current list of medications.

Note that our Use Cases are related to recording medication information only – specifically we are not (yet) including any ordering functionality (though the use of the MedicationPrescription resource will allow us to do so in the future).

Security

All communication with the system will be over an SSL connection. We’ll use oAuth to identify and authenticate the user. To keep things simple, we will assume that any registered user can access the records of any patient (we’ll have an audit record of course). We’d apply more robust privacy and security rules in a real implementation of course – especially around the updating of medication data – but this is a very large topic that we can’t go into here.

It is worth noting that FHIR has security ‘baked in’ to its design – so we can have confidence that we will be able to do this when we need to.

FHIR Interfaces / end points

The following section lists the FHIR interfaces that we will expose.

It’s not always appreciated that a FHIR server doesn’t have to support all resources – and can apply whatever business logic it needs at the interfaces. In fact, we’re only going to support the endpoints that we need to meet the use cases described above (for the moment).

The following section lists the resources and the end points that our solution will need to expose.

Patient

The Patient will need an identity on our server so that we can find them, and reference the other resources to them. We might maintain this ourselves (hard) or just provide a FHIR façade to an existing identity service. The queries we support are all about getting the patient resource, and include:

  • Find Patient (eg GET /Patient?name=eve)
  • Get Patient by identifier (eg GET /Patient?identifier=PRP1660)

Practitioner

The Practitioner resource is similar to the Patient resource – we need it in a number of places, but we don’t want the responsibility of maintaining the register. So, like Patient, we’ll just provide a façade to the appropriate identity service, with the following endpoints:

  • Find Practitioner (eg GET /Practitioner?name=smith)
  • Get Practitioner by identifier (eg GET /Practitioner?identifier=PRP1660)

MedicationDispense

The MedicationDispense resource is going to be useful when we are assembling the patients Medication List. We’ll take in a feed from pharmacies, and then a client can use that as they check that the list is correct (often termed ‘reconciling’ the list) – e.g. does the list include the medications that the patient has been dispensed?

We will assume that the submitting system has looked up the patient ID when they assemble and send the resource (for example they may use the /Patient endpoint described above to do so).

So we have:

  • Submit a dispense resource (POST /MedicationDispense)
  • Get dispense records in the past (say) month (GET / MedicationDispense?patient={patientID}&whenHandedOver < {1 month ago}

Given the volume of dispensing records, we may also want to support batch insertions of MedicationDispense resources as well.

As an aside, both MedicationDispense and MedicationPrescription resources refer to a Medication resource, which holds the details of the actual drug. The medication resource has a code property that identifies the specific drug within the specified drug terminology. For example in New Zealand we have the ULM (Universal List of Medications) – a terminology based on SNOMED – thus the code 44362701000116107 refers to a 100mg tablet of aspirin.

We’re assuming that the client system will be doing any searching/lookup against that terminology, so all we need is the code and the code system. For this reason our MedicationPrescription and MedicationDispense resources will contain the  Medication resource, rather than referencing  separate resource. There are tradeoffs in this decision as discussed in this post, but it does simplify our architecture, and we can easily change later if we need to without any migration cost.

MedicationPrescription

We’re using the MedicationPrescription resource to record the details of each medication the patient is taking, as it contains details like the drug, dosage information, reason for prescription and suchlike. We’ll use the ‘transaction’ based method of updating this resource that we described in the last post, which means that the only endpoint we need is to retrieve the resource based on the resource ID (which we’ll get from the List)– i.e.

  • Get a single MedicationPrescription (GET /MedicationPrescription/{ID})

List

We’ve talked in the last couple of posts about how to use the List resource to record the patients’ medication list, so lets not repeat all that here. The endpoints we’ll need are:

  • Get a patients list of medications (GET /Patient/{patientID}/List?code=10160-0)
  • Update a patients list of medications. This will be a transaction update as described earlier.

To get the history of changes to the List, we will use FHIR’s versioning abilities. First, the history of changes (assuming the listID is the ID of the list):

  • GET  /List/{listID}/_history

This will return a bundle of resources – each being an older version of the list. Once we have the versionID’s, we can perform a vread of the List as follows:

  • GET  /List/{listID}/_history/{versionID}

This will give a client application the ability to display the changes to the List over time.

SecurityEvent

We haven’t talked about SecurityEvent so far. Based on the IHE ATNA profile, the SecurityEvent is used to maintain an audit log of events that are of significance clinically or legally. We will create a new SecurityEvent resource automatically under the following situations:

  • When someone gets the list of medications for a patient
  • When someone updates the list of medications for a patient

The SecurityEvent will then be available so that we can see who has accessed a patients record – and we intend to make this available to the patient as well via a patient portal. The external endpoint will be quite simple:

  • Get a bundle of SecurityEvent resources for a patient over a given time period (GET /SecurityEvent?patientId={patientID}&date > {startDate} & date < {endDate}

 Notes:

We have had to expose a number of interfaces to support this functionality – but the benefits of doing so would justify the expense in providing a single place where medications are recorded for a patient and accessible by anyone who needs to do so (in the interest of the patient). As mentioned above, security & privacy mechanisms will need to be put in place in a real deployment.

It is worth noting that there are significant benefits to this architecture over a more simplistic approach like simply storing a series of documents – especially when it comes to population based analysis and research. It’s much easier to get at the information when stored in this ‘organized’ way than having to troll through millions of documents every time you wanted to find out specific information – such as who had received a specific drug, or how many patients with a Condition of Diabetes have not had an HBA1c performed in the past 6 months.

Version management also makes timeline changes straightforward, and FHIR is, of course, much easier for mobile devices.

However, I’m the first to admit that it represents quite a leap over how information is managed today! Still, one can dream…

And finally, being good FHIR citizens, our conformance resource is attached…

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
 &lt;Conformance xmlns=&quot;http://hl7.org/fhir&quot;&gt;
   &lt;text&gt;
     &lt;status value=&quot;generated&quot;/&gt;
     &lt;div xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
       &lt;p&gt;This conformance statement supports the Shared Medication repository, and specifies the following endpoints&lt;/p&gt;
       &lt;p&gt;Person: Read and Search on name and identifier&lt;/p&gt;
       &lt;p&gt;Practitioner: Read and Search on name and identifier&lt;/p&gt;
       &lt;p&gt;MedicationDispense. Create, and search on patient,whenHandedOver&lt;/p&gt;
       &lt;p&gt;MedicationPrescription. Read. &lt;/p&gt;
       &lt;p&gt;List. Create and search on code,patient. Version read.&lt;/p&gt;
       &lt;p&gt;SecurityEvent. Search on patient,date&lt;/p&gt;
       &lt;p&gt;Transaction interfaces to update the Medication List&lt;/p&gt;
     &lt;/div&gt;
   &lt;/text&gt;

   &lt;identifier value=&quot;68D043B5-9ECF-4559-A57A-396E0D452311&quot;/&gt;
   &lt;version value=&quot;.1&quot;/&gt;
   &lt;name value=&quot;My List Of Medicines (MLOM) Conformance Statement&quot;/&gt;
   &lt;publisher value=&quot;Elbonian MOH&quot;/&gt;
   &lt;telecom&gt;
     &lt;system value=&quot;email&quot;/&gt;
     &lt;value value=&quot;wile@elbonia.govt&quot;/&gt;
   &lt;/telecom&gt;
   &lt;description value=&quot;The FHIR endpoints required to support a regional Medication repository - My List Of Medicines&quot;/&gt;
   &lt;date value=&quot;2012-10-14&quot;/&gt;
   &lt;software&gt;
     &lt;name value=&quot;MLOM&quot;/&gt;
     &lt;version value=&quot;0.34.76&quot;/&gt;
   &lt;/software&gt;
   &lt;fhirVersion value=&quot;0.12&quot;/&gt;
   &lt;acceptUnknown value=&quot;false&quot;/&gt; &lt;!--   this system does not accepts unknown content in the resources   --&gt;

   &lt;!--   this system can do either xml or json. (Listing both implies full support for either, with interconversion)   --&gt;
   &lt;format value=&quot;xml&quot;/&gt;
   &lt;format value=&quot;json&quot;/&gt;
   &lt;!-- We only support REST interfaces at this time. This includes transaction to the server root to update the List--&gt;
   &lt;rest&gt;
     &lt;mode value=&quot;server&quot;/&gt;

     &lt;!-- SecurityEvent record --&gt;
     &lt;resource&gt;
       &lt;type value=&quot;SecurityEvent&quot;/&gt;
       &lt;operation&gt;
         &lt;code value=&quot;read&quot;/&gt;
       &lt;/operation&gt;
       &lt;searchParam&gt;
         &lt;name value=&quot;patient&quot;/&gt;
         &lt;type value=&quot;reference&quot;/&gt;
         &lt;documentation value=&quot;Lookup by patient.&quot;/&gt;
       &lt;/searchParam&gt;
       &lt;searchParam&gt;
         &lt;name value=&quot;date&quot;/&gt;
         &lt;type value=&quot;date&quot;/&gt;
         &lt;documentation value=&quot;Lookup by date the event occurred.&quot;/&gt;
       &lt;/searchParam&gt;
     &lt;/resource&gt;

     &lt;!-- MedicationDispense record --&gt;
     &lt;resource&gt;
       &lt;type value=&quot;MedicationDispense&quot;/&gt;
       &lt;operation&gt;
         &lt;code value=&quot;create&quot;/&gt;
       &lt;/operation&gt;
       &lt;operation&gt;
         &lt;code value=&quot;read&quot;/&gt;
       &lt;/operation&gt;
       &lt;searchParam&gt;
         &lt;name value=&quot;patient&quot;/&gt;
         &lt;type value=&quot;reference&quot;/&gt;
         &lt;documentation value=&quot;Lookup by patient.&quot;/&gt;
       &lt;/searchParam&gt;
       &lt;searchParam&gt;
         &lt;name value=&quot;whenHandedOver&quot;/&gt;
         &lt;type value=&quot;date&quot;/&gt;
         &lt;documentation value=&quot;Lookup by date the medication was given to the patient.&quot;/&gt;
       &lt;/searchParam&gt;
     &lt;/resource&gt;

     &lt;!-- MedicationPrescription resource. The prescription records are all created through the 'transaction' process so read-only --&gt;
     &lt;resource&gt;
       &lt;type value=&quot;MedicationPrescription&quot;/&gt;
       &lt;operation&gt;
         &lt;code value=&quot;read&quot;/&gt;
       &lt;/operation&gt;
     &lt;/resource&gt;

     &lt;!-- List resource. Used to support the List of Medications. --&gt;
     &lt;resource&gt;
       &lt;type value=&quot;List&quot;/&gt;
       &lt;operation&gt;
         &lt;code value=&quot;create&quot;/&gt;
       &lt;/operation&gt;
       &lt;operation&gt;
         &lt;code value=&quot;read&quot;/&gt;
       &lt;/operation&gt;
       &lt;operation&gt;
         &lt;code value=&quot;vread&quot;/&gt;
       &lt;/operation&gt;
       &lt;searchParam&gt;
         &lt;name value=&quot;patient&quot;/&gt;
         &lt;type value=&quot;reference&quot;/&gt;
         &lt;documentation value=&quot;Lookup by patient.&quot;/&gt;
       &lt;/searchParam&gt;
       &lt;searchParam&gt;
         &lt;name value=&quot;code&quot;/&gt;
         &lt;type value=&quot;token&quot;/&gt;
         &lt;documentation value=&quot;Lookup by code - this will be for the MLOM&quot;/&gt;
       &lt;/searchParam&gt;
     &lt;/resource&gt;

       &lt;!-- The Practitioner resource endpoint --&gt;
       &lt;resource&gt;
         &lt;type value=&quot;Practitioner&quot;/&gt;
         &lt;operation&gt;
           &lt;code value=&quot;read&quot;/&gt;
         &lt;/operation&gt;
         &lt;searchParam&gt;
           &lt;name value=&quot;name&quot;/&gt;
           &lt;type value=&quot;string&quot;/&gt;
           &lt;documentation value=&quot;Lookup by practitioner name. All parts of the name are searched.&quot;/&gt;
         &lt;/searchParam&gt;
         &lt;searchParam&gt;
           &lt;name value=&quot;identifier&quot;/&gt;
           &lt;type value=&quot;token&quot;/&gt;
           &lt;documentation value=&quot;Lookup by identifier. Both active and inactive practitioners will be returned.&quot;/&gt;
         &lt;/searchParam&gt;
       &lt;/resource&gt;

     &lt;!-- The Patient resource endpoint --&gt;
     &lt;resource&gt;
       &lt;type value=&quot;Patient&quot;/&gt;
       &lt;operation&gt;
         &lt;code value=&quot;read&quot;/&gt;
       &lt;/operation&gt;
       &lt;searchParam&gt;
         &lt;name value=&quot;name&quot;/&gt;
         &lt;type value=&quot;string&quot;/&gt;
         &lt;documentation value=&quot;Lookup by patient name. Only active patients will be returned. All parts of the name are searched.&quot;/&gt;
       &lt;/searchParam&gt;
       &lt;searchParam&gt;
         &lt;name value=&quot;identifier&quot;/&gt;
         &lt;type value=&quot;token&quot;/&gt;
         &lt;documentation value=&quot;Lookup by identifier. Both active and inactive patients will be returned.&quot;/&gt;
       &lt;/searchParam&gt;
       &lt;searchParam&gt;
         &lt;name value=&quot;birthDate&quot;/&gt;
         &lt;type value=&quot;date&quot;/&gt;
         &lt;documentation value=&quot;Lookup by patient birts date. Supports the :before and :after modifiers to allow for age ranges&quot;/&gt;
       &lt;/searchParam&gt;
     &lt;/resource&gt;
   &lt;/rest&gt;
 &lt;/Conformance&gt;

About David Hay
I'm an independent contractor working with a number of Organizations in the health IT space. I'm an HL7 Fellow, Chair Emeritus of HL7 New Zealand and a co-chair of the FHIR Management Group. I have a keen interest in health IT, especially health interoperability with HL7 and the FHIR standard. I'm the author of a FHIR training and design tool - clinFHIR - which is sponsored by InterSystems Ltd.

One Response to Regional Shared Medications with FHIR

  1. Pingback: Medication lists revisited | Hay on FHIR

Leave a Reply

%d