Creating and Updating Participant Data

Resource Versioning

When updating a resource via PUT, the RDR API requires a client to provide an HTTP “If-Match” header that points to the current version of a resource. This prevents a client from blindly overwriting data that it hasn’t had the opportunity to see yet. The client uses the value from a resource’s “ETag” header, following RFC7232 (or, for a more readable tutorial, see this article). Concretely, a request looks like:

PUT /rdr/v1/Participant/P123456789
If-Match: W/"98172982174921"

{
  "providerLink": [{
    "primary": true,
    "site": "Organization/PITT",
  }]
}

And this request either fails (if the supplied ETag does not match the current resource version), or it succeeds in updating the resource and returns a new ETag in a header like like:

ETag: W/"99817291822"

Note

ETag values are also returned in a meta.versionId property within each resource, following FHIR’s convention.

Workflows

Create Participant Questionnaire Response

Create a new QuestionnaireResponse in the RDR. Body is a FHIR DSTU2 QuestionnaireResponse resource which must include:

  • subject: a reference to the participant, in the form Patient/:pid. The :pid variable of this refernce must match the participant ID supplied in the POST URL.

Note

Note the use of the word “Patient” here, which comes from the FHIR spec.

  • questionnaire: a reference to the questionnaire for which this response has been written, in the form Questionnaire/:qid or Questionnaire/:qid/_history/:version (the latter indicating the version of the questionnaire in use)

  • linkId for each question, corresponding to a linkId specified in the questionnaire.

Request:

POST /rdr/v1/Participant/P999999999/QuestionnaireResponse
Body:

{
  "subject": {
    "reference":"Patient/P999999999"
  },
  "questionnaire": {
    "reference": "Questionnaire/33/_history/1"
  },
  linkId: "38622"
}

Create Participant Physical Measurements

We use the FHIR Document model to represent a set of physical measurements recorded at a PMI visit. This stores a Bundle of resources, with a Composition as the first entry (listing basic metadata for the document, including a document type, creation time, author, and an index of contents), and a set of Observation as subsequent entries (recording, for example, individual blood pressure or weight measurements).

Request:

POST /Participant/P999999999/PhysicalMeasurements
Body:

{
  "status":"final",
  "code":{
     "text":"text",
     "coding":[
        {
           "code":"62409-8",
           "display":"measurement",
           "system":"http://loinc.org"
        },
        {
           "code":"hip-circumference-1",
           "display":"measurement",
           "system":"http://terminology.pmi-ops.org/CodeSystem/physical-measurements"
        }
     ]
  },
  "resourceType":"Observation",
  "related":{
    "type":"qualified-by",
    "target":{
      "reference":"urn:example:protocol-modifications-hip-circumference"
    }
  },
  "valueQuantity":{
     "value":146.2,
     "code":"cm",
     "system":"http://unitsofmeasure.org",
     "unit":"cm"
  },
  "effectiveDateTime":"2019-05-29T16:51:23.461736",
  "subject":{
     "reference":"Patient/P999999999"
  }
}

If these measurements are an amendment of previously submitted measurements, that can be indicated in the request body with the following extension:

"extension": [{
"url": "http://terminology.pmi-ops.org/StructureDefinition/amends",
"valueReference": {
    "reference": "PhysicalMeasurements/:measurements_id"
  }
}

Cancellation/Amending/Restoring Physical Measurements

Cancelled

PATCH /Participant/:pid/PhysicalMeasurements/:id

{
  "cancelledInfo": {
    "author": {
      "system": "https://www.pmi-ops.org/healthpro-username",
      "value": "name@pmi-ops.org"
    },
    "site": {
      "system": "https://www.pmi-ops.org/site-id",
      "value": "hpo-site-somesitename"
    }
  },
  "reason": "text field for justification",
  "status": "cancelled"
}

Restored

PATCH /Participant/:pid/PhysicalMeasurements/:id

{
  "reason": "Fixed something...",
  "restoredInfo": {
    "author": {
      "system": "https://www.pmi-ops.org/healthpro-username",
      "value": "name@pmi-ops.org"
    },
    "site": {
      "system": "https://www.pmi-ops.org/site-id",
      "value": "hpo-site-monroeville"
    }
  },
  "status": "restored"
}

Amendment uses the FHIR amends extension to identify amended measurements

PATCH /Participant/:pid/PhysicalMeasurements/:id

{
  "extension": [{
    "url": "http://terminology.pmi-ops.org/StructureDefinition/amends",
    "valueReference": {
      "reference": "PhysicalMeasurements/%(physical_measurement_id)s"
    }
  }]
}

This will change the status to CANCELLED/RESTORED/AMENDED as appropriate. When syncing against the PhysicalMeasurements/_history api check for this field specifically. Other fields of interest on edited measurements are:

cancelled_username
cancelled_site_id
cancelled_time
reason

An amended PhysicalMeasurement will have an amended_measurement_id that points to the original measurement. These are defined by the enum PhysicalMeasurementsStatus.

BioBank Orders

The BioBank Order API maintains records of orders placed from HealthPro to the Biobank. Each order is a resource as documented here, including:

  • subject: a reference to the participant, in the form Patient/:pid. The :pid variable of this refernce must match the participant ID supplied in the POST URL.

Note

Note the use of the word “Patient” here, which comes from FHIR.

  • identifier: an array of Identifiers, each with a system and value. These should include the HealthPro identifier for this order as well as the biobank identifier for this order.

Create a BioBank Order

Create a new BiobankOrder for a given participant. Request body is a BiobankOrder resource to be created. Response is the resource as stored.

Request:

POST /Participant/P124820391/BiobankOrder

{
  "subject": "Patient/P124820391",
  "identifier": [
    {
      "system": "http://health-pro.org",
      "value": "healthpro-order-id-123"
    },
    {
      "system": "https://orders.mayomedicallaboratories.com",
      "value": "mayolink-order-id-456"
    }
  ],
  "created": "2016-01-04T09:40:21Z",
  "samples": [
    {
      "test": "1ED10",
      "description": "EDTA 10 mL (1)",
      "processingRequired": false,
      "collected": "2016-01-04T09:45:49Z",
      "finalized": "2016-01-04T10:55:41Z"
    },
    {
      "test": "1PST8",
      "description": "Plasma Separator 8 mL",
      "collected": "2016-01-04T09:45:49Z",
      "processingRequired":true,
      "processed": "2016-01-04T10:28:50Z",
      "finalized": "2016-01-04T10:55:41Z"
    },
    {
      <<as above, etc through sample #8>>
    }
  ],
  "notes": {
    "collected": "Only got 7mL in the ED10 tubes",
    "processed": "Centrifuge was not cooled to the proper temperature",
    "finalized": "Prepped samples in 4C fridge, Room 520A"
  }
}

Edit a BioBank Order

Cancel or restore a BiobankOrder by id.

An edited biobank order (cancel/restore/amend) has a payload as follows.

Request:

PATCH /Participant/:pid/BiobankOrder
Body:

{
  "amendedReason": "Text justification",
  "cancelledInfo": {
    "author": {
      "system": "https://www.pmi-ops.org/healthpro-username",
      "value": "name@pmi-ops.org"
    },
    "site": {
      "system": "https://www.pmi-ops.org/site-id",
      "value": "hpo-site-somesite"
    }
  },
  "status": "cancelled"
}

Deceased Reports

If a participant passes away, the deceased report API is how the RDR is updated with the relevant information.

Endpoints are available for creating and reviewing deceased reports, as well as retrieving lists of reports for one or more participants.

Creating and reviewing a deceased report

The API takes deceased report data structured as a FHIR Specification 4.0 Observation (http://hl7.org/fhir/observation.html). Listed below is an outline of each field, what it means for a deceased report, and any requirements for the field.

{
    // For creating a deceased report, the status must be given as preliminary
    // REQUIRED
    status: "preliminary",

    // CodeableConcept structure defining the observation as a deceased report for the RDR API
    // REQUIRED
    code: {
        text: "DeceasedReport”
    },

    // The date of death of the participant
    // OPTIONAL
    effectiveDateTime: "2020-01-01",

    // Details for how the user creating the report has become aware of the participant's deceased status
    // REQUIRED
    encounter: {
        // Must be one of the following: EHR, ATTEMPTED_CONTACT, NEXT_KIN_HPO, NEXT_KIN_SUPPORT, OTHER
        reference: "OTHER",

        // Required if reference is given as OTHER
        display: "Some other reason"
    },

    // The user that has created the deceased report
    // REQUIRED
    performer: [
        {
            type: "https://www.pmi-ops.org/healthpro-username",
            reference: "user.name@pmi-ops.org"
        }
    ],

    // The timestamp of when the user created the report
    // REQUIRED
    issued: "2020-01-31T08:34:12Z",  // assumed to be UTC if no timezone information is provided

    // Text field for providing the cause of death
    // OPTIONAL
    valueString: "Heart disease",

    // Array providing a single extension with a HumanName value providing information on the person
    //  that has reported that the participant has passed away
    // REQUIRED unless the encounter specifies EHR or OTHER
    extension: [
        {
            url: "https://www.pmi-ops.org/deceased-reporter",
            valueHumanName: {
                text: "John Doe",
                extension: [
                    {
                        // REQUIRED
                        url: "http://hl7.org/fhir/ValueSet/relatedperson-relationshiptype",
                        valueCode: "SIB"
                    },
                    {
                        // OPTIONAL
                        url: "https://www.pmi-ops.org/email-address",
                        valueString: "jdoe@yahoo.com"
                    },
                    {
                        // OPTIONAL
                        url: "https://www.pmi-ops.org/phone-number",
                        valueString: "123-456-7890"
                    }
                ]
            }
        }
    ]
}

Any participants that are are not paired to an HPO are automatically finalized, otherwise the reports remain in the preliminary state until they are reviewed by an additional user. A review request can set a report as final or cancelled. Here’s a description of the relevant fields for reviewing a report:

{
    // Review status for the deceased report. Can be "final" to finalize a report, or "cancelled" to deny it
    // REQUIRED
    status: "final",

    // REQUIRED
    code: {
        text: "DeceasedReport”
    },

    // Information for the user that has reviewed the report.
    // REQUIRED
    performer: [
        {
            type: "https://www.pmi-ops.org/healthpro-username",
            reference: "user.name@pmi-ops.org"
        }
    ],

    // The date of death of the participant. Will replace what is currently on the report.
    // OPTIONAL
    effectiveDateTime: "2020-01-01",

    // The timestamp of when the user reviewed the report
    issued: "2020-01-31T08:34:12Z"  // assumed to be UTC if no timezone information is provided

    // Additional information for defining why the report is cancelled if cancelling the report
    // REQUIRED if providing a status of "cancelled"
    extension: [
        {
            url: "https://www.pmi-ops.org/observation-denial-reason",
            valueReference: {
                // Must be one of the following: INCORRECT_PARTICIPANT, MARKED_IN_ERROR,
                //  INSUFFICIENT_INFORMATION, OTHER
                reference: "OTHER",

                // Text description of the reason for cancelling
                // REQUIRED if reference gives OTHER
                display: "Another reason for denying the report"
            }
        }
    ]
}

Retrieving deceased reports

Deceased reports can be listed for for individual participants, or all of the reports matching a given status (PENDING, APPROVED, OR DENIED) and/or organization id (such as UNSET). Reports will be listed by date of the last action taken on them (authored or reviewed) with the most recent reports appearing at the top.

The FHIR Observation fields used for the deceased reports coming from the API are the same as for structures sent to the API when creating and reviewing reports with the exceptions outlined below:

  • Participant ID

    The subject field will be populated with the ID of deceased report’s participant.

    {
        ...
        "subject": {
            "reference": "P000000000"
        },
        ...
    }
    
  • Creator and reviewer

    For reviewed reports, the performer array will contain both the author of the report and the reviewer along with the dates that they took their actions.

    {
        ...
        "performer": [
            {
                "type": "https://www.pmi-ops.org/healthpro-username",
                "reference": "user.name@pmi-ops.org"
                "extension": [
                    {
                        "url": "https://www.pmi-ops.org/observation/authored",
                        "valueDateTime": "2020-01-31T08:34:12Z"
                    }
                ]
            },
            {
                "type": "https://www.pmi-ops.org/healthpro-username",
                "reference": "another.user@pmi-ops.org"
                "extension": [
                    {
                        "url": "https://www.pmi-ops.org/observation/reviewed",
                        "valueDateTime": "2020-02-05T09:00:27Z"
                    }
                ]
            }
        ],
        ...
    }
    

Effects on Participant Summary

These are the three fields from the Participant Summary that are affected by deceased reports, and explanations of what they will provide and when:

  • deceasedStatus

    Will be UNSET for any participants that have no deceased reports (or only reports that have been denied). Is set to PENDING when a participant has a deceased report with a status of preliminary. And will be APPROVED for participants that have a final deceased report.

  • deceasedAuthored

    The most recent issued date received for an active deceased report. So for participants with a PENDING deceased status this will be the time that an external user created a deceased report for the participant. And for participants with an APPROVED status, this will be the time that the report was finalized.

  • dateOfDeath

    Date that the participant passed away if it was provided when creating or reviewing the report (using the date from the reviewing request if both requests provided the field).