Skip to content

Instantly share code, notes, and snippets.

@jacksmith15
Last active September 23, 2022 15:11
Show Gist options
  • Save jacksmith15/d26e1cfa1ad08855f7fba82af359b011 to your computer and use it in GitHub Desktop.
Save jacksmith15/d26e1cfa1ad08855f7fba82af359b011 to your computer and use it in GitHub Desktop.

NDMS-1460

Background

Logical model

  • Each referral may have one responsible_clinician
  • Each referral may have many additional_clinicians

API structure

  • Currently clinicians are treated as an attribute of a referral.
  • Each clinician is created and edited and deleted in a single array on the referral objects.
  • The responsible clinician is distinguished from the additional clinicians by a clinician.role attribute.

This has the following impacts:

  • To link a given clinician to multiple referrals, their record must be duplicated once for each referral.
  • Retrieving the responsible clinician from a referral requires a full iteration of the list of clinicians on the document.
  • It is impossible to distinguish between editing a given clinician's details, and replacing a clinician entirely.

Before and After API Overview

Current

  • Every clinician is passed in full to an array on referral API
  • Referral clinician role is passed as a concept reference on clinician

/referral

{
    "priority_id": "af11fa07-f94f-414c-8b83-df94a51a08e3",
    "status_id": "11e22afa-f996-4a8b-9ed3-1d30b8a76c88",
    "clinical_indication_id": "5e77423a-f8f7-47a8-b015-762e263b14a6",
    "date_last_submitted": "2018-10-30",
    "clinicians": [
        {
            "clinician": {
                "forename": "Carla",
                "surname": "Camacho",
                "phone_number": "(130)817-6963",
                "email_address": "clinician@hospital.org",
                "professional_registration_number": 1234567890,
                "departmental_address": "22AB Baker Street",
                "role": "9252aac9-65d7-4851-8a53-d191527e19c9",  // Responsible vs additional
            },
            "organisation_id": "00eccc30-19c6-7f4b-8ec2-96c470e5db97",
        }
    ],
}

New

  • Clinicians are created/updated on clinician API
  • Clinicians are added to referral only by reference
  • Role is implicit in the attribute on referral (and so the clinician.role attribute is dropped)

/referral

{
    "priority_id": "af11fa07-f94f-414c-8b83-df94a51a08e3",
    "status_id": "11e22afa-f996-4a8b-9ed3-1d30b8a76c88",
    "clinical_indication_id": "5e77423a-f8f7-47a8-b015-762e263b14a6",
    "date_last_submitted": "2018-10-30",
    "responsible_clinician_id": "e4aab6c07c3b490783f70ddd606f69b5",
    "additional_clinicians": [
        {"clinician_id": "ae5b443fb79a495498935d09c9b888c2"}
    ]
}

/clinician

{
    "forename": "Carla",
    "surname": "Camacho",
    "phone_number": "(130)817-6963",
    "email_address": "clinician@hospital.org",
    "professional_registration_number": 1234567890,
    "departmental_address": "22AB Baker Street",
    "organisation_id": "00eccc30-19c6-7f4b-8ec2-96c470e5db97",
},

Example operations

Adding a new responsible clinician

Current

GET /referral/{id} to load the document to be updated

{
    ...
    "clinicians": [
        {
            "clinician": {
                "id": "9e492a34-98cb-43cf-8a92-a6ae76604395",
                "email_address": "clinician@hospital.org",
                "phone_number": "(130)817-6963",
                "surname": "Camacho",
                "professional_registration_number": "1234567890",
                "forename": "Carla",
                "departmental_address": "22AB Baker Street",
                "role": {
                    "codesystem_uri": "referral_clinician_role",
                    "display": "Additional report recipient",
                    "code": "additionalReportRecipient",
                    "uid": "f8ba143a-8df6-46b7-9d89-66acd38bda18"
                }
            }
        }
    ],
    ...
}

PATCH /referral/{id} with updated list of clinicians

{
    ...
    "clinicians": [
        {
            "clinician": {
                "id": "9e492a34-98cb-43cf-8a92-a6ae76604395",
                "email_address": "clinician@hospital.org",
                "phone_number": "(130)817-6963",
                "surname": "Camacho",
                "professional_registration_number": "1234567890",
                "forename": "Carla",
                "departmental_address": "22AB Baker Street",
                "role": "f8ba143a-8df6-46b7-9d89-66acd38bda18"  // Additional
            }
        },
        {
            "clinician": {
                "forename": "David",
                "surname": "Harris",
                "phone_number": "(130)817-6963",
                "email_address": "david@hospital.org",
                "professional_registration_number": 1_234_567_890,
                "departmental_address": "22AB Baker Street",
                "role": "960fb392-a258-4626-a476-a50a89845169"  // Responsible
            }
        }
    ],
    ...
}

New

GET /referral/{id} to load the document to be updated

{
    ...
    "responsible_clinician_id": null,
    "additional_clinicians": [
        {"clinician_id": "9e492a34-98cb-43cf-8a92-a6ae76604395"}
    ],
    ...
}

POST /clinician to create the new clinician and retrieve its UUID Request Body:

{
    "forename": "David",
    "surname": "Harris",
    "phone_number": "(130)817-6963",
    "email_address": "david@hospital.org",
    "professional_registration_number": 1_234_567_890,
    "departmental_address": "22AB Baker Street",
    "organisation_id": "00eccc30-19c6-7f4b-8ec2-96c470e5db97",
}

Response:

{
    "id": "1d0c141e-df4f-4d75-8f5d-4b5ee0923946"
}

PATCH /referral/{id} to set the responsible_clinician_id attribute

{
    "responsible_clinician_id": "1d0c141e-df4f-4d75-8f5d-4b5ee0923946" // This is the ID retruned from request above.
}

Adding a new additional clinician

Current

This is the same as for adding a responsible clinician, but the role attribute is set as additional rather than responsible.

New

The process for adding an additional clinician is similar to adding a responsible clinician, but the final step is instead:

PATCH /referral

{
    "additional_clinicians": [
        {"clinician_id": "9e492a34-98cb-43cf-8a92-a6ae76604395"},
        {"clinician_id": "1d0c141e-df4f-4d75-8f5d-4b5ee0923946"}  // This is the ID from the clinician POST response
    ]
}

Editing an existing clinician on a referral e.g. changing the first name

Current

GET /referral/{id} to load the document to be updated

{
    ...
    "clinicians": [
        {
            "clinician": {
                "id": "9e492a34-98cb-43cf-8a92-a6ae76604395",
                "email_address": "clinician@hospital.org",
                "phone_number": "(130)817-6963",
                "surname": "Camacho",
                "professional_registration_number": "1234567890",
                "forename": "Carla",
                "departmental_address": "22AB Baker Street",
                "role": {
                    "codesystem_uri": "referral_clinician_role",
                    "display": "Additional report recipient",
                    "code": "additionalReportRecipient",
                    "uid": "f8ba143a-8df6-46b7-9d89-66acd38bda18"
                }
            }
        }
    ],
    ...
}

PATCH /referral/{id} with the new name

{
    "clinicians": [
        {
            "clinician": {
                "id": "9e492a34-98cb-43cf-8a92-a6ae76604395",
                "email_address": "clinician@hospital.org",
                "phone_number": "(130)817-6963",
                "surname": "Camacho",
                "professional_registration_number": "1234567890",
                "forename": "Yvonne",  // New name here
                "departmental_address": "22AB Baker Street",
                "role": "f8ba143a-8df6-46b7-9d89-66acd38bda18"
            }
        }
    ]
}

New

GET /referral/{referral_id} to retrieve the clinician ID

{
    ...
    "responsible_clinician_id": "1d0c141e-df4f-4d75-8f5d-4b5ee0923946",
    "additional_clinicians": [
        {"clinician_id": "9e492a34-98cb-43cf-8a92-a6ae76604395"}
    ],
    ...
}

OPTIONAL: GET /clinician/{clinician_id} using the selected clinician ID above

{
    "id": "9e492a34-98cb-43cf-8a92-a6ae76604395",
    "email_address": "clinician@hospital.org",
    "phone_number": "(130)817-6963",
    "surname": "Camacho",
    "professional_registration_number": "1234567890",
    "forename": "Carla",
    "departmental_address": "22AB Baker Street",
    "organisation_id": "517a8432-3d96-4007-8834-8cc325fa7af2"
}

PATCH /clinician/{clinician_id} with the new name

{
    "forename": "Yvonne"
}

Detaching a responsible clinician from a referral

Current

GET /referral/{id} to load the document to be updated

{
    ...
    "clinicians": [
        {
            "clinician": {
                "id": "9e492a34-98cb-43cf-8a92-a6ae76604395",
                "email_address": "clinician@hospital.org",
                "phone_number": "(130)817-6963",
                "surname": "Camacho",
                "professional_registration_number": "1234567890",
                "forename": "Carla",
                "departmental_address": "22AB Baker Street",
                "role": {
                    "codesystem_uri": "referral_clinician_role",
                    "display": "Additional report recipient",
                    "code": "additionalReportRecipient",
                    "uid": "f8ba143a-8df6-46b7-9d89-66acd38bda18"
                }
            }
        },
        {
            "clinician": {
                "id": "9e492a34-98cb-43cf-8a92-a6ae76604395",
                "email_address": "david@hospital.org",
                "phone_number": "(130)817-6963",
                "surname": "Harris",
                "professional_registration_number": "1234567890",
                "forename": "David",
                "departmental_address": "22AB Baker Street",
                "role": {
                    "codesystem_uri": "referral_clinician_role",
                    "display": "Responsible clinician",
                    "code": "responsibleClinician",
                    "uid": "960fb392-a258-4626-a476-a50a89845169"
                }
            }
        }
    ],
    ...
}

Iterate over the clinicians to locate the responsible clinician by matching on clinician.role.code == "responsibleClinician.

PATCH /referral/{id} with the matched clinician removed from the array

{
    ...
    "clinicians": [
        {
            "clinician": {
                "id": "9e492a34-98cb-43cf-8a92-a6ae76604395",
                "email_address": "clinician@hospital.org",
                "phone_number": "(130)817-6963",
                "surname": "Camacho",
                "professional_registration_number": "1234567890",
                "forename": "Carla",
                "departmental_address": "22AB Baker Street",
                "role": {
                    "codesystem_uri": "referral_clinician_role",
                    "display": "Additional report recipient",
                    "code": "additionalReportRecipient",
                    "uid": "f8ba143a-8df6-46b7-9d89-66acd38bda18"
                }
            }
        }
    ],
    ...
}

New

PATCH /referral/{id} to unset the responsible_clinician_id attribute

{
    "responsible_clinician_id": null
}

Detaching an additional clinician from a referral

Current

This is the same as removing a responsible clinician - but requires matching on a different role code and whatever other criteria are needed to drill down to the given additional clinician.

New

GET /referral/{referral_id} to retrieve the additional clinicians list

{
    ...
    "additional_clinicians": [
        {"clinician_id": "9e492a34-98cb-43cf-8a92-a6ae76604395"},
        {"clinician": "1d0c141e-df4f-4d75-8f5d-4b5ee0923946"}  // We want to detach this clinician from the referral
    ],
    ...
}

PATCH /referral/{referral_id} with the offending clinician removed

{
    "additional_clinicians": [
        {"clinician_id": "9e492a34-98cb-43cf-8a92-a6ae76604395"}
    ]
}

New error states

When creating or updating a referral, there are new error states:

  1. If the resultant referral would have the same clinician as both a responsible clinician and an additional clinician, then the application will respond with a 400 Bad Request - code: clinician_responsible_xor_additional
  2. If the resultant referral would have the same clinician appear twice in the list of additional clinicians, then the application will respond with a 400 Bad Request - code: clinician_unique_additional_relation
  3. If a UUID passed either to referral.responsible_clinician_id or additional_clinicians.clinician_id does not correspond to an existing clinician, then the application will respond with a 400 Bad Request
  4. If a value passed to either referral.responsible_clinician_id or additional_clinicians.clinician_id is not a valid UUID, then the application will respond with a 400 Bad Request

The /clinician API will use the same field level logic as the referral.clinicians.clinician sub-payload with the following exceptions:

  1. The clinician.role field will not be accepted (400 Bad Request)
  2. A new field will be accepted: clinician.organisation_id - following the same validation logic as referral.clinicians.organisation_id from the old payload.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment