-
Notifications
You must be signed in to change notification settings - Fork 4
Home
- 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
- User has signed up with an app
- User has completed informed consent
- User wants to shared clinical + imaging data with App
-
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 OAuthauthorize
endpoint, and OAuthtoken
endpoint. -
GET $imagingBaseUrl/metadata
--> FHIR Conformance statement SMART OAuth extensions identifying OAuthauthorize
endpoint, and OAuthtoken
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
- FHIR Base URL for Clinical:
-
App redirects user to https://portal.mt-sinai.org/authorize
- user signs into portal
- user approves access (or not)
- portal redirects user back to https://app/redirect?code=abc123
- App calls https://portal.mt-sinai.org/token (passing code and a client secret) -->
{
"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
-
GET https://imaging-api.mt-sinai.org/ImagingStudy?patient=123[&_lastUpdated=gt2016-04-17T04:00:00.000] Authorization: Bearer access-token-value-unguessable
-
FHIR Broker calls Token Introspection API
POST https://introspection.internal.mt-sinai.org/introspect
token=access-token-value-unguessable
patient=123
- Introspection API needs to make a call. GET https://clinical-api.mt-sinai.org/Patient/123 Authorization: Bearer access-token-value-unguessable
{
"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]]
-
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