Skip to content

Instantly share code, notes, and snippets.

@p2
Last active May 16, 2018 14:22
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save p2/a169169345388f119101 to your computer and use it in GitHub Desktop.
Save p2/a169169345388f119101 to your computer and use it in GitHub Desktop.
SMART on FHIR Tech Overview

Implementation Details

We'll be addressing certain implementation details here.

Pregnancy & Breastfeeding

To be able to detect whether a woman is pregnant, we would expect a Condition resource with start date, end date and the Snomed-CT code for patient currently pregnant (77386006) or one if its many child codes. There is also a code for possible pregnancy (102874004) that we can consider using, if it makes sense from HCA's side.

We could do the same to indicate the breastfeeding state: create a Condition with start- and end dates and a SNOMED-CT code of 169750002 for mother currently breast-feeding.

SMART on FHIR Tech Overview

This document gives a quick SMART on FHIR overview for collaborators at HCA and Sarah Cannon on our Clinical Trials App pilot.

SMART on FHIR is an open specification to integrate apps with Electronic Health Records:

  • Authentication and Authorization via OAuth2 and OpenID
  • RESTful service URLs
  • FHIR data models

FHIR is currently a Draft Standard for Trial Use in the first phase (DSTU-1), with DSTU-2 to be ballotted May 2015. Our pilot implementation is targeting the DSTU-2 ballot spec.

Authorization

There are two ways a SMART app can be launched:

  • From within an EHR, by loading the app's specified launch URL plus launch context id in an iframe
  • Standalone, where the users visits the app's URL to start the session

In both cases, to request data from a SMART compliant server an OAuth2 token is needed. The SMART on FHIR server publishes a conformance statement which declares OAuth2 endpoints. The app reads the statement to extract the OAuth2 URLs to perform the OAuth2 exchange.

The server keeps track of launch contexts to (typically) link an app to the patient context it was launched in.

The app now uses its client_id, access scopes and launch context id to request a token and the server decides if access to the user + app + scope combination should be granted. In case no launch context is provided but the app needs patient context, the server typically provides a patient selector and has the user select a patient before continuing the OAuth exchange. At the end of the OAuth exchange the app receives an access token and the additional launch context information.

REST

FHIR defines a concise set of REST URLs for the various CRUD operations. Data that goes over the wire can be XML or JSON serialized, clients are required to specify the mime-type of the data they accept:

  • XML: application/xml+fhir
  • JSON: application/json+fhir

The frameworks we use currently only support the JSON format, not XML.

The Clinical Trials App only requires read access to certain data models, listed below. These are accessed using either the read or the search REST interactions. Servers can choose which of the interactions to make available and which resource types to support, but they must provide a conformance statement.

A read interaction returns the resource, with an additional resourceType key naming the resource, in the response body.

For the resources obtained by performing a FHIR search interaction a JSON Bundle is returned. In DSTU-2 this will become an actual resource, in DSTU-1 it has a custom format.

Data Models

SMART supports the standard FHIR data models.

Data models currently used in the clinical trials app, along with the query that we use to retrieve them, the coding systems and the minimally required properties, are:

read from /Patient/{patient-id}

  • name
  • gender
  • birthDate
  • address (to show town/state)
  • phote (if available)

search against /Condition?patient={patient-id}
The condition should be mapped to SNOMED-CT.

  • patient
  • onsetDateTime ¹
  • abatementDate ¹
  • code (SNOMED)
  • clinicalStatus
  • text (as human-readable overview, if available)
  • notes (if they are provided)

search against MedicationPrescription?patient={patient-id}
The actual medication should be a contained resource and mapped to RxNorm.

  • patient
  • medication (contained as Medication)
    • code (RxNorm)
    • text (human-readable medication description, not crucial)
  • status

search against Observation?subject={patient-id}
The lab test should be mapped to LOINC. The units should be UCUM.

  • subject
  • code ➔ code.coding (LOINC)
  • applies (either as “DateTime” or “Period”, see ¹)
  • value ²
    • "valueQuantity" as Quantity
    • "valueCodeableConcept" for gene mutations pos/neg
  • reliability (if available)
  • status
  • summary (human-readable, if available)
  • modifierExtension for observations describing a tumor gene mutation

search against AllergyIntolerance?patient={patient-id}
The actual substance should be a contained resource and mapped to NDF-RT ³. Adverse reactions are also described using this data model.

  • patient
  • substance (contained as Substance)
    • type ➔ type.coding (NDF-RT ³)
    • text (human-readable, if available)
  • criticality (if available)
  • status

The overall secondary elements, like vaccines and allergies, are not yet used in the app and we can add support for these at a later stage.


¹ FHIR allows “onset” and “abatement” (and others) to be of different types. The type is appended to the property name, CamelCased, and only one of these is allowed to be present (e.g. “onsetDateTime”). The app currently looks for the Date forms in Condition, which is an ISO-date.

² Observation covers a wide range of tests. What I have currently implemented is looking for a Quantity (“valueQuantity”). We may have other tests that are expressed differently (e.g. as “SampledData”) or as a specimen but I haven’t yet worked with those.

³ I have not yet implemented allergy and adverse reaction tests. Lilly delivers these as NDF-RT and I think this should work well, but we can discuss.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment