Skip to content
Josh Mandel edited this page Jul 24, 2017 · 9 revisions

Pass through the system

TODOs

  • Review syntax for clients to request a Transfer Syntax
  • Decide whether we need to support transcoding of Transfer Syntax
  • Decide whether/how to map Patient fields into ImagingStudy response
  • Determine whether 503 is the right/best/okay response code for "try again later"
  • Review WADO specs to determine whether there's a better approach to bulk data

Pre-conditions

  • User has signed up with an app
  • User has completed informed consent
  • User wants to shared clinical + imaging data with App

User identifies Site to share data from

  • App has a database of provider Sites --> (FHIR Base URL for Clinical, FHIR Base URL for Imaging)

  • GET $clincalBaseUrl/metadata --> FHIR Conformance statement SMART OAuth extensions identifying OAuth authorize endpoint, and OAuth token endpoint.

  • GET $imagingBaseUrl/metadata --> FHIR Conformance statement SMART OAuth extensions identifying OAuth authorize endpoint, and OAuth token endpoint.

  • We expect for out deploymnet that the OAuth URLs returned by these two services will be the same

    e.g. user picks Mt Sinai -->

    • FHIR Base URL for Clinical: https://clinical-api.mt-sinai.org
    • FHIR Base URL for Imaging: https://imaging-api.mt-sinai.org
    • Authorize URL https://portal.mt-sinai.org/authorize
    • Token URL https://portal.mt-sinai.org/token
  • App redirects user to https://portal.mt-sinai.org/authorize

In the portal...

Back in app..

   {
     "expires_in": 3600,
     "access_token": "access-token-value-unguessable",
     "refresh_token": "refresh-token-value-unguessable-and-long-lasting",
     "patient": "123" # FHIR Patient ID ==> https://api.mt-sinai.org/Patient/123
   }
  • Now app has an access token that it can use for clinical + imaging APIs

App tries to get imaging studies

   POST https://introspection.internal.mt-sinai.org/introspect
   token=access-token-value-unguessable
   patient=123
  {
    "resourceType": "Patient",
    "id": "123",
    "identifier": [{
      "system": "something that mean MRN",
      "value": "mrn-for-patient-123"
    }],
    "name": []
  }
  • Token introspection server returns to the FHIR Broker
  {
      "active": true,
      "client_id":  // we have no way to learn this :(  "l238j323ds-23ij4",
      "username": // we have no way to learn this :("jdoe",
      "scope": "Patient/*.read", # hard coded
      "sub": // we have no way to learn this :( "Z5O3upPC88QrAjx00dis",
      "aud":  // we have no way to learn this :( "https://protected.example.net/resource",
      "iss": // fixed value meaning "the epic server",
      "exp": // we have no way to learn this :( 1419356238,
      "iat": // we have no way to learn this :( 1419350238,
      "patient_fhir_id": "123",
      "patient_mrn": "mrn-for-patient-123",
      "other_extension_field": // if needed...
   }
  • FHIR Broker Proceeds with request, since the token was good...

  • FHIR Broker issues QIDO-RS Query https://rs-broker.internal.mt-sinai.org/qido-rs/studies?PatientID=mrn-for-patient-123

Gets results synchronously and translates to a FHIR Bundle, filtering by starttime if client asked for _lastUpdated:

  {
    "resourceType": "ImagingStudy",
    "id": "" // Determine how to generate this in a stable way
    "patient": "Patient/123",
    "identifier": [{
      "system": "something that mean MRN",
      "value": "mrn-for-patient-123"
    }],
    "started": <StudyDate + StudyTime + Timezone Offset>,
    "accession": <Accession Number>,
    "availability": <Instance Availability>,
    "modalityList": <Modalities in Study>,
    "referer" : "Practitioner/abc" // Q. maybe ignore or use "contained"
    "endpoint": "Endpoint/abc" // Q. maybe use "contained"
                               // connectionType = dicom-wado-rsi
                               // address = https://imaging-api.mt-sinai.org/$wado-rs/Patient/123
    "uid": "example-study-uid" <Study Instance UID>
    TODO: map patient fields if needed
  }
  • App now knows a list of ImagingStudies! Let's get data with a set of requests like:
   GET https://imaging-api.mt-sinai.org/$wado-rs/Patient/123/studies/example-study-uid
   Accept: multipart/related; type=application/dicom
   Authorize: Bearer access-token-value-unguessable
  • FHIR Broker calls Token Introspection API, gets back a response where active=true and patient_fhir_id=123 FHIR Broker ensures that Study UID example-study-uid belongs to patient 123 via https://rs-broker.internal.mt-sinai.org/qido-rs/studies?PatientID=mrn-for-patient-123&StudyInstanceUID=example-study-uid if no match --> return Unauthorized

  • FHIR Broker calls Wado RS server with https://rs-broker.internal.mt-sinai.org/wado-rs/studies?PatientID=mrn-for-patient-123&StudyInstanceUID=example-study-uid

  • RS Broker triggers a C-MOVE "to rs broker" Respond with 503 // TODO investigate whether 503 is the best code Retry-After: 300

  • FHIR Broker passes the response through to the app 503 Retry-After: 300

  • C-MOVE happens in the background

  • App queries again

    GET https://imaging-api.mt-sinai.org/$wado-rs/Patient/123/studies/example-study-uid
    Accept: multipart/related; type=application/dicom
    Authorize: Bearer access-token-value-unguessable
  • FHIR Broker validates as before, and passes through to RS Broker, as before.

  • RS Broker returns

200
Content-type: multipart/related; type=application/dicom
[[DICOM DATA BINARY PAYLOAD]]
  • FHIR Broker passes the response through to the app
200
Content-type: multipart/related; type=application/dicom
[[DICOM DATA BINARY PAYLOAD]]

App tries to get imaging reports

  • Queries FHIR Broker https://imaging-api.mt-sinai.org/DocumentReference?patient=123

  • FHIR Broker does the usual validation with Token Introspection Server

  • FHIR Broker issues a query to the Edge Server

  • Edge Server looks up reports in its internal database are turns a FHIR Bundle of DiagnosticReport resources:

{
  "resourceType": "DiagnosticReport",
  "subject": "Patient/123",
  "identifier":,
  "code": {
    // Pick a good loinc code for Imaging Report
  },
  "author",
  "description",
  "imagingStudy": ["ImagingStudy/abc"] // TODO figure out how to generate this deterministically
                                       // Possibilities are: 
                                       // 1. Have Edge Server issue QIDO Query --> C-FIND (preferred)
                                       // 2. Omit this link entirely (if we run out of time)
  "codedDiagnosis",
  "conclusion",
  "presentedform": [{
    "contentType": PDF or RTF or HTML or ...,
    "data": b64-encoded binary data
  }]
}
  • FHIR Broker passes this response through to the app
Clone this wiki locally