From f90d7f3f8a0e242173e66b2c0d75427ece16dca1 Mon Sep 17 00:00:00 2001 From: David Wass Date: Tue, 13 Dec 2022 14:32:10 +0000 Subject: [PATCH] [ERSSUP-65227]-[]-[initial sandbox and get endpoint]-[DMW] --- .../responses/initialCommunication.json | 78 ++++++++++++ .../responses/AdviceRequestAttachment.json | 86 +++++++++++++ .../responses/basicQuestionnaireResponse.json | 79 ++++++++++++ .../responses/adviceRequestedAandG.json | 14 ++- .../responses/incompleteAandG.json | 4 +- .../responses/shortlistedAandG.json | 14 ++- .../responses/shortlistedAandGAttachment.json | 15 ++- .../requests/basicQuestionnaireResponse.json | 2 +- sandbox/src/routes/index.js | 18 ++- sandbox/src/routes/r4/postCommunication.js | 28 +++++ .../src/routes/r4/postDocumentReference.js | 28 +++++ .../routes/r4/postQuestionnaireResponse.js | 28 +++++ sandbox/src/routes/r4/postServiceRequest.js | 28 +++++ .../src/routes/r4/retrieveCommunication.js | 34 ++++++ .../routes/r4/retrieveDocumentReference.js | 34 ++++++ .../r4/retrieveQuestionnaireResponse.js | 34 ++++++ .../src/routes/r4/retrieveServiceRequest.js | 34 ++++++ .../r4/services/mockResponseProvider.js | 114 +++++++++++++++++- .../r4/schemas/eRS-ServiceRequest.yaml | 20 +++ .../a0X1-create-update-service-request.yaml | 1 + .../a0X5-retrieve-service-request.yaml | 37 ++++++ .../a0X6-retrieve-communication.yaml | 34 ++++++ .../a0X7-retrieve-document-reference.yaml | 34 ++++++ .../a0X8-retrieve-questionnaire-response.yaml | 34 ++++++ .../pathParameters/CommunicationUuid.yaml | 9 ++ .../pathParameters/DocumentReferenceUuid.yaml | 9 ++ .../QuestionnaireResponseUuid.yaml | 9 ++ .../pathParameters/ServiceRequestUuid.yaml | 8 ++ .../getCommunication/200Response.yaml | 21 ++++ .../getDocumentReference/200Response.yaml | 21 ++++ .../getQuestionnaireResponse/200Response.yaml | 21 ++++ .../getServiceRequest/200Response.yaml | 33 +++++ specification/e-referrals-service-api.yaml | 12 ++ 33 files changed, 964 insertions(+), 11 deletions(-) create mode 100644 sandbox/src/mocks/r4/getCommunication/responses/initialCommunication.json create mode 100644 sandbox/src/mocks/r4/getDocumentReference/responses/AdviceRequestAttachment.json create mode 100644 sandbox/src/mocks/r4/getQuestionnaireResponse/responses/basicQuestionnaireResponse.json create mode 100644 sandbox/src/routes/r4/postCommunication.js create mode 100644 sandbox/src/routes/r4/postDocumentReference.js create mode 100644 sandbox/src/routes/r4/postQuestionnaireResponse.js create mode 100644 sandbox/src/routes/r4/postServiceRequest.js create mode 100644 sandbox/src/routes/r4/retrieveCommunication.js create mode 100644 sandbox/src/routes/r4/retrieveDocumentReference.js create mode 100644 sandbox/src/routes/r4/retrieveQuestionnaireResponse.js create mode 100644 sandbox/src/routes/r4/retrieveServiceRequest.js create mode 100644 specification/components/r4/schemas/endpoints/a0X5-retrieve-service-request.yaml create mode 100644 specification/components/r4/schemas/endpoints/a0X6-retrieve-communication.yaml create mode 100644 specification/components/r4/schemas/endpoints/a0X7-retrieve-document-reference.yaml create mode 100644 specification/components/r4/schemas/endpoints/a0X8-retrieve-questionnaire-response.yaml create mode 100644 specification/components/r4/schemas/pathParameters/CommunicationUuid.yaml create mode 100644 specification/components/r4/schemas/pathParameters/DocumentReferenceUuid.yaml create mode 100644 specification/components/r4/schemas/pathParameters/QuestionnaireResponseUuid.yaml create mode 100644 specification/components/r4/schemas/pathParameters/ServiceRequestUuid.yaml create mode 100644 specification/components/r4/schemas/responses/getCommunication/200Response.yaml create mode 100644 specification/components/r4/schemas/responses/getDocumentReference/200Response.yaml create mode 100644 specification/components/r4/schemas/responses/getQuestionnaireResponse/200Response.yaml create mode 100644 specification/components/r4/schemas/responses/getServiceRequest/200Response.yaml diff --git a/sandbox/src/mocks/r4/getCommunication/responses/initialCommunication.json b/sandbox/src/mocks/r4/getCommunication/responses/initialCommunication.json new file mode 100644 index 000000000..f502f2d29 --- /dev/null +++ b/sandbox/src/mocks/r4/getCommunication/responses/initialCommunication.json @@ -0,0 +1,78 @@ +{ + "id": "cf8d99c4-b4b1-4ad3-b5b0-2381bee8c6e8", + "meta": { + "versionId": 1 + }, + "resourceType": "Communication", + "status": "completed", + "received": "2022-12-11T13:01:33+00:00", + "basedOn": [ + { + "reference": "ServiceRequest/a.832db7fa-ebdd-44b6-ab3b-8329c2d43149" + } + ], + "subject": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/nhs-number", + "value": "9912003888" + } + }, + "category": [ + { + "coding": [ + { + "system": "https://fhir.nhs.uk/CodeSystem/eRS-CommunicationSentBy", + "code": "REQUESTER" + } + ] + } + ], + "recipient": [ + { + "reference": "HealthcareService/54b0506d-49af-4245-9d40-d7d64902055e" + } + ], + "payload": [ + { + "contentReference": { + "reference": "DocumentReference/6f693b93-fc6f-4aa1-955e-d9548b5a6a9a" + } + }, + { + "contentString": "Please advise me on this patient who ...(information about patient)" + } + ], + "contained": [ + { + "resourceType": "PractitionerRole", + "id": "sender", + "practitioner": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/sds-user-id", + "value": "103264992985" + }, + "display": "DR AA BHATIA" + }, + "organization": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/ods-organization-code", + "value": "C81007" + }, + "display": "VERNON STREET MEDICAL CTR" + }, + "code": [ + { + "coding": [ + { + "system": "https://fhir.nhs.uk/CodeSystem/eRS-BusinessFunction-1", + "code": "REFERRING_CLINICIAN" + } + ] + } + ] + } + ], + "sender": { + "reference": "#sender" + } +} diff --git a/sandbox/src/mocks/r4/getDocumentReference/responses/AdviceRequestAttachment.json b/sandbox/src/mocks/r4/getDocumentReference/responses/AdviceRequestAttachment.json new file mode 100644 index 000000000..63f4c2147 --- /dev/null +++ b/sandbox/src/mocks/r4/getDocumentReference/responses/AdviceRequestAttachment.json @@ -0,0 +1,86 @@ +{ + "id": "03f55377-33e0-4ad2-9ecc-0788342f24a1", + "meta": { + "versionId": 1 + }, + "resourceType": "DocumentReference", + "type": { + "coding": [ + { + "system": "https://fhir.nhs.uk/CodeSystem/eRS-AttachmentType", + "code": "ADVICE_REQUEST", + "display": "Advice Request" + } + ] + }, + "status": "current", + "subject": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/nhs-number", + "value": "9912003888" + } + }, + "content": [ + { + "attachment": { + "contentType": "application/pdf", + "url": "Binary/959724e3-8719-4ff3-ae37-5198c450e0f6", + "size": 18592, + "title": "upload.png", + "creation": "2022-01-31", + "extension": [ + { + "url": "https://fhir.nhs.uk/StructureDefinition/Extension-eRS-AttachedBy", + "valueReference": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/sds-user-id", + "value": "987654321" + } + } + } + ] + } + } + ], + "context": { + "related" : [ + { + "type": "ServiceRequest", + "reference": "ServiceRequest/a.832db7fa-ebdd-44b6-ab3b-8329c2d43149" + } + ] + }, + "contained": [ + { + "resourceType": "PractitionerRole", + "id": "author", + "practitioner": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/sds-user-id", + "value": "103264992985" + }, + "display": "DR AA BHATIA" + }, + "organization": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/ods-organization-code", + "value": "C81007" + }, + "display": "VERNON STREET MEDICAL CTR" + }, + "code": [ + { + "coding": [ + { + "system": "https://fhir.nhs.uk/CodeSystem/eRS-BusinessFunction-1", + "code": "REFERRING_CLINICIAN" + } + ] + } + ] + } + ], + "author": { + "reference": "#author" + } +} diff --git a/sandbox/src/mocks/r4/getQuestionnaireResponse/responses/basicQuestionnaireResponse.json b/sandbox/src/mocks/r4/getQuestionnaireResponse/responses/basicQuestionnaireResponse.json new file mode 100644 index 000000000..fbcb16869 --- /dev/null +++ b/sandbox/src/mocks/r4/getQuestionnaireResponse/responses/basicQuestionnaireResponse.json @@ -0,0 +1,79 @@ +{ + "resourceType": "QuestionnaireResponse", + "id": "d9d4cf80-3f9d-4435-9f3b-e6efb09ad654", + "meta": { + "versionId": 2 + }, + "questionnaire": "https://fhir.nhs.uk/Questionnaire/ERS-ShortList", + "basedOn": [ + { + "reference": "ServiceRequest/a.832db7fa-ebdd-44b6-ab3b-8329c2d43149" + } + ], + "subject": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/nhs-number", + "value": "9912003888" + } + }, + "status": "completed", + "authored" : "2022-01-11T16:40:00+00:00", + "contained": [ + { + "resourceType": "PractitionerRole", + "id": "source", + "practitioner": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/sds-user-id", + "value": "103264992985" + }, + "display": "DR AA BHATIA" + }, + "organization": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/ods-organization-code", + "value": "C81007" + }, + "display": "VERNON STREET MEDICAL CTR" + }, + "code": [ + { + "coding": [ + { + "system": "https://fhir.nhs.uk/CodeSystem/eRS-BusinessFunction-1", + "code": "REFERRING_CLINICIAN" + } + ] + } + ] + } + ], + "source": { + "reference": "#source" + }, + "item": [ + { + "linkId": "searchCriteria", + "answer": [ + { + "valueString": "HealthcareService?supportedSpecialty=general-medicine&supportedPriority=routine" + } + ] + }, + { + "linkId": "services", + "answer": [ + { + "valueReference": { + "reference": "HealthcareService/76de72bc-f001-49fa-84c6-af15a4fdb72c" + } + }, + { + "valueReference": { + "reference": "HealthcareService/54b0506d-49af-4245-9d40-d7d64902055e" + } + } + ] + } + ] +} diff --git a/sandbox/src/mocks/r4/getServiceRequest/responses/adviceRequestedAandG.json b/sandbox/src/mocks/r4/getServiceRequest/responses/adviceRequestedAandG.json index e0f395ac1..583db3cfd 100644 --- a/sandbox/src/mocks/r4/getServiceRequest/responses/adviceRequestedAandG.json +++ b/sandbox/src/mocks/r4/getServiceRequest/responses/adviceRequestedAandG.json @@ -2,7 +2,7 @@ "resourceType": "ServiceRequest", "id": "a.832db7fa-ebdd-44b6-ab3b-8329c2d43149", "meta": { - "versionId": "5" + "versionId": 5 }, "subject": { "identifier": { @@ -81,7 +81,17 @@ "value": "C81007" }, "display": "VERNON STREET MEDICAL CTR" - } + }, + "code": [ + { + "coding": [ + { + "system": "https://fhir.nhs.uk/CodeSystem/eRS-BusinessFunction-1", + "code": "REFERRING_CLINICIAN" + } + ] + } + ] } ], "requester": { diff --git a/sandbox/src/mocks/r4/getServiceRequest/responses/incompleteAandG.json b/sandbox/src/mocks/r4/getServiceRequest/responses/incompleteAandG.json index 136df89a7..aeb6b3503 100644 --- a/sandbox/src/mocks/r4/getServiceRequest/responses/incompleteAandG.json +++ b/sandbox/src/mocks/r4/getServiceRequest/responses/incompleteAandG.json @@ -2,7 +2,7 @@ "resourceType": "ServiceRequest", "id": "a.832db7fa-ebdd-44b6-ab3b-8329c2d43149", "meta": { - "versionId": "5" + "versionId": 5 }, "subject": { "identifier": { @@ -86,7 +86,7 @@ { "coding": [ { - "system": "https://fhir.nhs.uk/STU3/CodeSystem/eRS-BusinessFunction-1", + "system": "https://fhir.nhs.uk/CodeSystem/eRS-BusinessFunction-1", "code": "REFERRING_CLINICIAN" } ] diff --git a/sandbox/src/mocks/r4/getServiceRequest/responses/shortlistedAandG.json b/sandbox/src/mocks/r4/getServiceRequest/responses/shortlistedAandG.json index a737f2628..b424be670 100644 --- a/sandbox/src/mocks/r4/getServiceRequest/responses/shortlistedAandG.json +++ b/sandbox/src/mocks/r4/getServiceRequest/responses/shortlistedAandG.json @@ -2,7 +2,7 @@ "resourceType": "ServiceRequest", "id": "a.832db7fa-ebdd-44b6-ab3b-8329c2d43149", "meta": { - "versionId": "5" + "versionId": 5 }, "subject": { "identifier": { @@ -81,7 +81,17 @@ "value": "C81007" }, "display": "VERNON STREET MEDICAL CTR" - } + }, + "code": [ + { + "coding": [ + { + "system": "https://fhir.nhs.uk/CodeSystem/eRS-BusinessFunction-1", + "code": "REFERRING_CLINICIAN" + } + ] + } + ] } ], "requester": { diff --git a/sandbox/src/mocks/r4/getServiceRequest/responses/shortlistedAandGAttachment.json b/sandbox/src/mocks/r4/getServiceRequest/responses/shortlistedAandGAttachment.json index 8eed3e4fe..ca90034ae 100644 --- a/sandbox/src/mocks/r4/getServiceRequest/responses/shortlistedAandGAttachment.json +++ b/sandbox/src/mocks/r4/getServiceRequest/responses/shortlistedAandGAttachment.json @@ -2,7 +2,7 @@ "resourceType": "ServiceRequest", "id": "a.832db7fa-ebdd-44b6-ab3b-8329c2d43149", "meta": { - "versionId": "5" + "versionId": 5 }, "subject": { "identifier": { @@ -81,7 +81,18 @@ "value": "C81007" }, "display": "VERNON STREET MEDICAL CTR" - } + }, + + "code": [ + { + "coding": [ + { + "system": "https://fhir.nhs.uk/CodeSystem/eRS-BusinessFunction-1", + "code": "REFERRING_CLINICIAN" + } + ] + } + ] } ], "requester": { diff --git a/sandbox/src/mocks/r4/sendQuestionnaireResponse/requests/basicQuestionnaireResponse.json b/sandbox/src/mocks/r4/sendQuestionnaireResponse/requests/basicQuestionnaireResponse.json index 3f56e0d1f..c1e69162c 100644 --- a/sandbox/src/mocks/r4/sendQuestionnaireResponse/requests/basicQuestionnaireResponse.json +++ b/sandbox/src/mocks/r4/sendQuestionnaireResponse/requests/basicQuestionnaireResponse.json @@ -10,7 +10,7 @@ "identifier": { "system": "https://fhir.nhs.uk/Id/nhs-number", "value": "9912003888" - }, + } }, "status" : "completed", "authored" : "2022-01-11T16:40:00+00:00", diff --git a/sandbox/src/routes/index.js b/sandbox/src/routes/index.js index a3d2d4e2a..17f4ccf45 100644 --- a/sandbox/src/routes/index.js +++ b/sandbox/src/routes/index.js @@ -40,6 +40,14 @@ const retrieveBusinessFunctions = require('./r4/retrieveBusinessFunctions') const retrieveOboUsers = require('./r4/retrieveOboUsers') const retrieveHealthcareService = require('./r4/retrieveHealthcareService') const searchForHealthcareServices = require('./r4/searchForHealthcareServices') +const createUpdateServiceRequest = require('./r4/postServiceRequest') +const createUpdateDocumentReference = require('./r4/postDocumentReference') +const sendCommunication = require('./r4/postCommunication') +const sendQuestionnaireResponse = require('./r4/postQuestionnaireResponse') +const retrieveServiceRequest = require('./r4/retrieveServiceRequest') +const retrieveDocumentReference = require('./r4/retrieveDocumentReference') +const retrieveCommunication = require('./r4/retrieveCommunication') +const retrieveQuestionnaireResponse = require('./r4/retrieveQuestionnaireResponse') const routes = [].concat( getStatus, @@ -76,7 +84,15 @@ const routes = [].concat( cancelAppointmentActionLater, cancelReferral, retrieveAppointment, - retrieveAdviceAndGuidanceOverviewPdf + retrieveAdviceAndGuidanceOverviewPdf, + createUpdateServiceRequest, + createUpdateDocumentReference, + sendCommunication, + sendQuestionnaireResponse, + retrieveServiceRequest, + retrieveDocumentReference, + retrieveCommunication, + retrieveQuestionnaireResponse ) module.exports = routes diff --git a/sandbox/src/routes/r4/postCommunication.js b/sandbox/src/routes/r4/postCommunication.js new file mode 100644 index 000000000..a1b3739ba --- /dev/null +++ b/sandbox/src/routes/r4/postCommunication.js @@ -0,0 +1,28 @@ +const mockResponseProvider = require('./services/mockResponseProvider') +const businessFunctionValidator = require('../../services/businessFunctionValidator') + +module.exports = [ + /** + * Sandbox implementation for post ServiceRequest endpoint + */ + { + method: 'POST', + path: '/FHIR/R4/Communication', + handler: (request, h) => { + + const allowedBusinessFunctions = ["REFERRING_CLINICIAN", "REFERRING_CLINICIAN_ADMIN"] + + const validationResult = businessFunctionValidator.validateBusinessFunction(request, h, allowedBusinessFunctions) + if (validationResult) { + return validationResult + } + + const { responsePath, responseCode } = mockResponseProvider.getExampleResponseForPostCommunication(request); + if (responsePath != null) { + return h.file(responsePath, { etagMethod: false }).code(responseCode).type("application/fhir+json").etag("1", { weak: true }) + } + + return h.file('SandboxErrorOutcome.json').code(422); + } + } +] diff --git a/sandbox/src/routes/r4/postDocumentReference.js b/sandbox/src/routes/r4/postDocumentReference.js new file mode 100644 index 000000000..1f3652e29 --- /dev/null +++ b/sandbox/src/routes/r4/postDocumentReference.js @@ -0,0 +1,28 @@ +const mockResponseProvider = require('./services/mockResponseProvider') +const businessFunctionValidator = require('../../services/businessFunctionValidator') + +module.exports = [ + /** + * Sandbox implementation for post ServiceRequest endpoint + */ + { + method: 'POST', + path: '/FHIR/R4/DocumentReference', + handler: (request, h) => { + + const allowedBusinessFunctions = ["REFERRING_CLINICIAN", "REFERRING_CLINICIAN_ADMIN"] + + const validationResult = businessFunctionValidator.validateBusinessFunction(request, h, allowedBusinessFunctions) + if (validationResult) { + return validationResult + } + + const { responsePath, responseCode } = mockResponseProvider.getExampleResponseForPostDocumentReference(request); + if (responsePath != null) { + return h.file(responsePath, { etagMethod: false }).code(responseCode).type("application/fhir+json").etag("1", { weak: true }) + } + + return h.file('SandboxErrorOutcome.json').code(422); + } + } +] diff --git a/sandbox/src/routes/r4/postQuestionnaireResponse.js b/sandbox/src/routes/r4/postQuestionnaireResponse.js new file mode 100644 index 000000000..604d9e2cd --- /dev/null +++ b/sandbox/src/routes/r4/postQuestionnaireResponse.js @@ -0,0 +1,28 @@ +const mockResponseProvider = require('./services/mockResponseProvider') +const businessFunctionValidator = require('../../services/businessFunctionValidator') + +module.exports = [ + /** + * Sandbox implementation for post ServiceRequest endpoint + */ + { + method: 'POST', + path: '/FHIR/R4/QuestionnaireResponse', + handler: (request, h) => { + + const allowedBusinessFunctions = ["REFERRING_CLINICIAN", "REFERRING_CLINICIAN_ADMIN"] + + const validationResult = businessFunctionValidator.validateBusinessFunction(request, h, allowedBusinessFunctions) + if (validationResult) { + return validationResult + } + + const { responsePath, responseCode } = mockResponseProvider.getExampleResponseForPostQuestionnaireResponse(request); + if (responsePath != null) { + return h.file(responsePath, { etagMethod: false }).code(responseCode).type("application/fhir+json").etag("1", { weak: true }) + } + + return h.file('SandboxErrorOutcome.json').code(422); + } + } +] diff --git a/sandbox/src/routes/r4/postServiceRequest.js b/sandbox/src/routes/r4/postServiceRequest.js new file mode 100644 index 000000000..10d9afc1d --- /dev/null +++ b/sandbox/src/routes/r4/postServiceRequest.js @@ -0,0 +1,28 @@ +const mockResponseProvider = require('./services/mockResponseProvider') +const businessFunctionValidator = require('../../services/businessFunctionValidator') + +module.exports = [ + /** + * Sandbox implementation for post ServiceRequest endpoint + */ + { + method: 'POST', + path: '/FHIR/R4/ServiceRequest', + handler: (request, h) => { + + const allowedBusinessFunctions = ["REFERRING_CLINICIAN", "REFERRING_CLINICIAN_ADMIN"] + + const validationResult = businessFunctionValidator.validateBusinessFunction(request, h, allowedBusinessFunctions) + if (validationResult) { + return validationResult + } + + const { responsePath, responseCode } = mockResponseProvider.getExampleResponseForPostServiceRequest(request); + if (responsePath != null) { + return h.file(responsePath, { etagMethod: false }).code(responseCode).type("application/fhir+json").etag("1", { weak: true }) + } + + return h.file('SandboxErrorOutcome.json').code(422); + } + } +] diff --git a/sandbox/src/routes/r4/retrieveCommunication.js b/sandbox/src/routes/r4/retrieveCommunication.js new file mode 100644 index 000000000..00a1f8d1d --- /dev/null +++ b/sandbox/src/routes/r4/retrieveCommunication.js @@ -0,0 +1,34 @@ +const mockResponseProvider = require('./services/mockResponseProvider') +const businessFunctionValidator = require('../../services/businessFunctionValidator') + +function retrieveCommunication(request, h) { + const allowedBusinessFunctions = ["REFERRING_CLINICIAN", "REFERRING_CLINICIAN_ADMIN"] + + const validationResult = businessFunctionValidator.validateBusinessFunction(request, h, allowedBusinessFunctions) + if (validationResult) { + return validationResult + } + + if(request.method == 'HEAD') { + if(request.params.uuid == 1) { + return h.response(' ').code(200).type('application/fhir+json').etag('1', { weak: true }).removeHeader('content-length') + } + } + else { + var responsePath = mockResponseProvider.getExampleResponseForGetCommunication(request) + if (responsePath) { + return h.file(responsePath, { etagMethod: false }).code(200).type('application/fhir+json').etag('1', { weak: true }) + } + } + + return h.file('../NotFoundOutcome.txt').code(404) +} + + +module.exports = [ + { + method: 'GET', + path: '/FHIR/R4/Communication/{uuid}', + handler: retrieveCommunication + } +] diff --git a/sandbox/src/routes/r4/retrieveDocumentReference.js b/sandbox/src/routes/r4/retrieveDocumentReference.js new file mode 100644 index 000000000..ffb39f019 --- /dev/null +++ b/sandbox/src/routes/r4/retrieveDocumentReference.js @@ -0,0 +1,34 @@ +const mockResponseProvider = require('./services/mockResponseProvider') +const businessFunctionValidator = require('../../services/businessFunctionValidator') + +function retrieveDocumentReference(request, h) { + const allowedBusinessFunctions = ["REFERRING_CLINICIAN", "REFERRING_CLINICIAN_ADMIN"] + + const validationResult = businessFunctionValidator.validateBusinessFunction(request, h, allowedBusinessFunctions) + if (validationResult) { + return validationResult + } + + if(request.method == 'HEAD') { + if(request.params.uuid == 1) { + return h.response(' ').code(200).type('application/fhir+json').etag('1', { weak: true }).removeHeader('content-length') + } + } + else { + var responsePath = mockResponseProvider.getExampleResponseForGetDocumentReference(request) + if (responsePath) { + return h.file(responsePath, { etagMethod: false }).code(200).type('application/fhir+json').etag('1', { weak: true }) + } + } + + return h.file('../NotFoundOutcome.txt').code(404) +} + + +module.exports = [ + { + method: 'GET', + path: '/FHIR/R4/DocumentReference/{uuid}', + handler: retrieveDocumentReference + } +] diff --git a/sandbox/src/routes/r4/retrieveQuestionnaireResponse.js b/sandbox/src/routes/r4/retrieveQuestionnaireResponse.js new file mode 100644 index 000000000..b60fbc9ab --- /dev/null +++ b/sandbox/src/routes/r4/retrieveQuestionnaireResponse.js @@ -0,0 +1,34 @@ +const mockResponseProvider = require('./services/mockResponseProvider') +const businessFunctionValidator = require('../../services/businessFunctionValidator') + +function retrieveQuestionnaireResponse(request, h) { + const allowedBusinessFunctions = ["REFERRING_CLINICIAN", "REFERRING_CLINICIAN_ADMIN"] + + const validationResult = businessFunctionValidator.validateBusinessFunction(request, h, allowedBusinessFunctions) + if (validationResult) { + return validationResult + } + + if(request.method == 'HEAD') { + if(request.params.uuid == 1) { + return h.response(' ').code(200).type('application/fhir+json').etag('1', { weak: true }).removeHeader('content-length') + } + } + else { + var responsePath = mockResponseProvider.getExampleResponseForGetQuestionnaireResponse(request) + if (responsePath) { + return h.file(responsePath, { etagMethod: false }).code(200).type('application/fhir+json').etag('1', { weak: true }) + } + } + + return h.file('../NotFoundOutcome.txt').code(404) +} + + +module.exports = [ + { + method: 'GET', + path: '/FHIR/R4/QuestionnaireResponse/{uuid}', + handler: retrieveQuestionnaireResponse + } +] diff --git a/sandbox/src/routes/r4/retrieveServiceRequest.js b/sandbox/src/routes/r4/retrieveServiceRequest.js new file mode 100644 index 000000000..240627b3e --- /dev/null +++ b/sandbox/src/routes/r4/retrieveServiceRequest.js @@ -0,0 +1,34 @@ +const mockResponseProvider = require('./services/mockResponseProvider') +const businessFunctionValidator = require('../../services/businessFunctionValidator') + +function retrieveServiceRequest(request, h) { + const allowedBusinessFunctions = ["REFERRING_CLINICIAN", "REFERRING_CLINICIAN_ADMIN"] + + const validationResult = businessFunctionValidator.validateBusinessFunction(request, h, allowedBusinessFunctions) + if (validationResult) { + return validationResult + } + + if(request.method == 'HEAD') { + if(request.params.uuid == 1) { + return h.response(' ').code(200).type('application/fhir+json').etag('1', { weak: true }).removeHeader('content-length') + } + } + else { + var responsePath = mockResponseProvider.getExampleResponseForGetServiceRequest(request) + if (responsePath) { + return h.file(responsePath, { etagMethod: false }).code(200).type('application/fhir+json').etag('1', { weak: true }) + } + } + + return h.file('../NotFoundOutcome.txt').code(404) +} + + +module.exports = [ + { + method: 'GET', + path: '/FHIR/R4/ServiceRequest/{uuid}', + handler: retrieveServiceRequest + } +] diff --git a/sandbox/src/routes/r4/services/mockResponseProvider.js b/sandbox/src/routes/r4/services/mockResponseProvider.js index ae5721db6..1ea20dd69 100644 --- a/sandbox/src/routes/r4/services/mockResponseProvider.js +++ b/sandbox/src/routes/r4/services/mockResponseProvider.js @@ -1,3 +1,32 @@ +const fs = require('fs') +const lodash = require('lodash') + +function mapExampleResponse(request, exampleResponseMap) { + + if (request && request.payload) { + for (const [requestBodyPath, response] of Object.entries(exampleResponseMap)) { + try { + console.error(fs.readFileSync(requestBodyPath, 'utf8')); + const exampleRequestBody = JSON.parse(fs.readFileSync(requestBodyPath)) + var requestBody = request.payload; + + if ('object' != (typeof requestBody)) { + requestBody = JSON.parse(request.payload) + } + + if (lodash.isEqual(requestBody, exampleRequestBody)) { + return response; + } + } catch (err) { + console.error(err) + throw err + } + } + } + + return null; +} + module.exports = { getExampleResponseForRetrieveBusinessFunctions: function () { @@ -40,5 +69,88 @@ module.exports = { } return null - } + }, + + getExampleResponseForPostServiceRequest: function (request) { + var responseMap = { + 'src/mocks/r4/createServiceRequest/requests/createIncomplete.json': {responsePath: 'r4/createServiceRequest/responses/createdIncomplete.json', responseCode: 201} + } + return mapExampleResponse(request, responseMap) + }, + + getExampleResponseForPostDocumentReference: function (request) { + var responseMap = { + 'src/mocks/r4/createDocumentReference/requests/AdviceRequestAttachment.json': {responsePath: 'r4/createDocumentReference/responses/AdviceRequestAttachment.json', responseCode: 201} + } + return mapExampleResponse(request, responseMap) + }, + + getExampleResponseForPostCommunication: function (request) { + var responseMap = { + 'src/mocks/r4/sendCommunication/requests/initialCommunication.json': {responsePath: 'r4/sendCommunication/responses/initialCommunication.json', responseCode: 201} + } + return mapExampleResponse(request, responseMap) + }, + getExampleResponseForPostQuestionnaireResponse: function (request) { + var responseMap = { + 'src/mocks/r4/sendQuestionnaireResponse/requests/basicQuestionnaireResponse.json': {responsePath: 'r4/sendQuestionnaireResponse/responses/basicQuestionnaireResponse.json', responseCode: 201} + } + return mapExampleResponse(request, responseMap) + }, + + getExampleResponseForGetServiceRequest: function (request) { + const version = request.params.version + const uuid = request.params.uuid + + if (uuid == 1 && (!version || version == 1)) { + return 'r4/getServiceRequest/responses/adviceRequestedAandG.json' + } + + if (uuid == 2 && (!version || version == 1)) { + return 'r4/getServiceRequest/responses/incompleteAandG.json' + } + + if (uuid == 3 && (!version || version == 1)) { + return 'r4/getServiceRequest/responses/shortlistedAandG.json' + } + + if (uuid == 4 && (!version || version == 1)) { + return 'r4/getServiceRequest/responses/shortlistedAandGAttachment.json' + } + + return null + }, + + getExampleResponseForGetCommunication: function (request) { + const version = request.params.version + const uuid = request.params.uuid + + if (uuid == 1 && (!version || version == 1)) { + return 'r4/getCommunication/responses/initialCommunication.json' + } + + return null + }, + + getExampleResponseForGetDocumentReference: function (request) { + const version = request.params.version + const uuid = request.params.uuid + + if (uuid == 1 && (!version || version == 1)) { + return 'r4/getDocumentReference/responses/AdviceRequestAttachment.json' + } + + return null + }, + + getExampleResponseForGetQuestionnaireResponse: function (request) { + const version = request.params.version + const uuid = request.params.uuid + + if (uuid == 1 && (!version || version == 1)) { + return 'r4/getQuestionnaireResponse/responses/basicQuestionnaireResponse.json' + } + + return null + }, } diff --git a/specification/components/r4/schemas/eRS-ServiceRequest.yaml b/specification/components/r4/schemas/eRS-ServiceRequest.yaml index 5ca41ff72..7c5afbaea 100644 --- a/specification/components/r4/schemas/eRS-ServiceRequest.yaml +++ b/specification/components/r4/schemas/eRS-ServiceRequest.yaml @@ -95,6 +95,7 @@ properties: type: string enum: - draft + - active example: draft extension: type: array @@ -144,6 +145,25 @@ properties: enum: - '#requester' example: '#requester' + supportingInfo: + type: array + items: + type: object + required: + - type + - reference + properties: + type: + type: string + enum: + - 'QuestionnaireResponse' + - 'DocumentReference' + - 'Communication' + example: 'QuestionnaireResponse' + reference: + type: string + example: 'QuestionnaireResponse/d9d4cf80-3f9d-4435-9f3b-e6efb09ad654' + diff --git a/specification/components/r4/schemas/endpoints/a0X1-create-update-service-request.yaml b/specification/components/r4/schemas/endpoints/a0X1-create-update-service-request.yaml index a07ef2236..cf59aa930 100644 --- a/specification/components/r4/schemas/endpoints/a0X1-create-update-service-request.yaml +++ b/specification/components/r4/schemas/endpoints/a0X1-create-update-service-request.yaml @@ -10,6 +10,7 @@ operationId: a0X1-create-update-service-request parameters: - $ref: '../headers/request/BearerAuthorization.yaml' - $ref: '../headers/request/CorrelationID.yaml' + - $ref: '../headers/request/BusinessFunction.yaml' requestBody: required: true content: diff --git a/specification/components/r4/schemas/endpoints/a0X5-retrieve-service-request.yaml b/specification/components/r4/schemas/endpoints/a0X5-retrieve-service-request.yaml new file mode 100644 index 000000000..c21ca6b67 --- /dev/null +++ b/specification/components/r4/schemas/endpoints/a0X5-retrieve-service-request.yaml @@ -0,0 +1,37 @@ +security: + - bearerAuth: [] +description: | + ## Overview + + TBC: Use this endpoint to retrieve a Service Request + + ## Sandbox test scenarios + You can test the following scenarios in our sandbox environment + + | Scenario | Service Request Id | + | ------------------------------------------------------------------------ | ------------------- | + | Advice Requested | `1` | + | Incomplete | `2` | + | Shortlisted Only | `3` | + | Shorlisted With Attachment | `4` | +summary: A0X5 - Retrieve service request +operationId: a0X%-retrieve-service-request +parameters: + - $ref: '../headers/request/BearerAuthorization.yaml' + - $ref: '../pathParameters/ServiceRequestUuid.yaml' + - $ref: '../headers/request/OdsCode.yaml' + - $ref: '../headers/request/BusinessFunction.yaml' + - $ref: '../headers/request/CorrelationID.yaml' +responses: + '200': + $ref: '../responses/getServiceRequest/200Response.yaml' + '401': + $ref: '../responses/Unauthorized.yaml' + '403': + $ref: '../responses/Forbidden.yaml' + '404': + $ref: '../responses/NotFound.yaml' + '429': + $ref: '../responses/TooManyRequests.yaml' + '500': + $ref: '../responses/InternalServerError.yaml' diff --git a/specification/components/r4/schemas/endpoints/a0X6-retrieve-communication.yaml b/specification/components/r4/schemas/endpoints/a0X6-retrieve-communication.yaml new file mode 100644 index 000000000..b352ff1cd --- /dev/null +++ b/specification/components/r4/schemas/endpoints/a0X6-retrieve-communication.yaml @@ -0,0 +1,34 @@ +security: + - bearerAuth: [] +description: | + ## Overview + + TBC: Use this endpoint to retrieve a Communication + + ## Sandbox test scenarios + You can test the following scenarios in our sandbox environment + + | Scenario | Communication Id | + | ------------------------------------------------------------------------ | ------------------- | + | Initial Communication | `1` | +summary: A0X6 - Retrieve communication +operationId: a0X%-retrieve-communication +parameters: + - $ref: '../headers/request/BearerAuthorization.yaml' + - $ref: '../pathParameters/CommunicationUuid.yaml' + - $ref: '../headers/request/OdsCode.yaml' + - $ref: '../headers/request/BusinessFunction.yaml' + - $ref: '../headers/request/CorrelationID.yaml' +responses: + '200': + $ref: '../responses/getCommunication/200Response.yaml' + '401': + $ref: '../responses/Unauthorized.yaml' + '403': + $ref: '../responses/Forbidden.yaml' + '404': + $ref: '../responses/NotFound.yaml' + '429': + $ref: '../responses/TooManyRequests.yaml' + '500': + $ref: '../responses/InternalServerError.yaml' diff --git a/specification/components/r4/schemas/endpoints/a0X7-retrieve-document-reference.yaml b/specification/components/r4/schemas/endpoints/a0X7-retrieve-document-reference.yaml new file mode 100644 index 000000000..fe55d3563 --- /dev/null +++ b/specification/components/r4/schemas/endpoints/a0X7-retrieve-document-reference.yaml @@ -0,0 +1,34 @@ +security: + - bearerAuth: [] +description: | + ## Overview + + TBC: Use this endpoint to retrieve a Document Reference + + ## Sandbox test scenarios + You can test the following scenarios in our sandbox environment + + | Scenario | Document Reference Id | + | ------------------------------------------------------------- | ------------------------ | + | Advice Request Attachment | `1` | +summary: A0X7 - Retrieve communication +operationId: a0X7-retrieve-document-reference +parameters: + - $ref: '../headers/request/BearerAuthorization.yaml' + - $ref: '../pathParameters/DocumentReferenceUuid.yaml' + - $ref: '../headers/request/OdsCode.yaml' + - $ref: '../headers/request/BusinessFunction.yaml' + - $ref: '../headers/request/CorrelationID.yaml' +responses: + '200': + $ref: '../responses/getDocumentReference/200Response.yaml' + '401': + $ref: '../responses/Unauthorized.yaml' + '403': + $ref: '../responses/Forbidden.yaml' + '404': + $ref: '../responses/NotFound.yaml' + '429': + $ref: '../responses/TooManyRequests.yaml' + '500': + $ref: '../responses/InternalServerError.yaml' diff --git a/specification/components/r4/schemas/endpoints/a0X8-retrieve-questionnaire-response.yaml b/specification/components/r4/schemas/endpoints/a0X8-retrieve-questionnaire-response.yaml new file mode 100644 index 000000000..7c6c3beb4 --- /dev/null +++ b/specification/components/r4/schemas/endpoints/a0X8-retrieve-questionnaire-response.yaml @@ -0,0 +1,34 @@ +security: + - bearerAuth: [] +description: | + ## Overview + + TBC: Use this endpoint to retrieve a Questionnaire Response + + ## Sandbox test scenarios + You can test the following scenarios in our sandbox environment + + | Scenario | Questionnaire Response Id | + | ------------------------------------------------------------- | ---------------------------- | + | Basic Questionnaire Response | `1` | +summary: A0X8 - Retrieve communication +operationId: a0X8-retrieve-document-reference +parameters: + - $ref: '../headers/request/BearerAuthorization.yaml' + - $ref: '../pathParameters/QuestionnaireResponseUuid.yaml' + - $ref: '../headers/request/OdsCode.yaml' + - $ref: '../headers/request/BusinessFunction.yaml' + - $ref: '../headers/request/CorrelationID.yaml' +responses: + '200': + $ref: '../responses/getQuestionnaireResponse/200Response.yaml' + '401': + $ref: '../responses/Unauthorized.yaml' + '403': + $ref: '../responses/Forbidden.yaml' + '404': + $ref: '../responses/NotFound.yaml' + '429': + $ref: '../responses/TooManyRequests.yaml' + '500': + $ref: '../responses/InternalServerError.yaml' diff --git a/specification/components/r4/schemas/pathParameters/CommunicationUuid.yaml b/specification/components/r4/schemas/pathParameters/CommunicationUuid.yaml new file mode 100644 index 000000000..cfa2c6402 --- /dev/null +++ b/specification/components/r4/schemas/pathParameters/CommunicationUuid.yaml @@ -0,0 +1,9 @@ +name: uuid +in: path +description: | + The UUID of the communication to be retrieved. It must be valid and relate to an existing Communication otherwise a HTTP 404 response will be returned. +required: true +schema: + type: string + format: uuid + example: 'cf8d99c4-b4b1-4ad3-b5b0-2381bee8c6e8' diff --git a/specification/components/r4/schemas/pathParameters/DocumentReferenceUuid.yaml b/specification/components/r4/schemas/pathParameters/DocumentReferenceUuid.yaml new file mode 100644 index 000000000..75357f2f1 --- /dev/null +++ b/specification/components/r4/schemas/pathParameters/DocumentReferenceUuid.yaml @@ -0,0 +1,9 @@ +name: uuid +in: path +description: | + The UUID of the document reference to be retrieved. It must be valid and relate to an existing Document Reference otherwise a HTTP 404 response will be returned. +required: true +schema: + type: string + format: uuid + example: '03f55377-33e0-4ad2-9ecc-0788342f24a1' diff --git a/specification/components/r4/schemas/pathParameters/QuestionnaireResponseUuid.yaml b/specification/components/r4/schemas/pathParameters/QuestionnaireResponseUuid.yaml new file mode 100644 index 000000000..7fd260f9c --- /dev/null +++ b/specification/components/r4/schemas/pathParameters/QuestionnaireResponseUuid.yaml @@ -0,0 +1,9 @@ +name: uuid +in: path +description: | + The UUID of the questionnaire response to be retrieved. It must be valid and relate to an existing Questionnaire Response otherwise a HTTP 404 response will be returned. +required: true +schema: + type: string + format: uuid + example: 'd9d4cf80-3f9d-4435-9f3b-e6efb09ad654' diff --git a/specification/components/r4/schemas/pathParameters/ServiceRequestUuid.yaml b/specification/components/r4/schemas/pathParameters/ServiceRequestUuid.yaml new file mode 100644 index 000000000..d539523e5 --- /dev/null +++ b/specification/components/r4/schemas/pathParameters/ServiceRequestUuid.yaml @@ -0,0 +1,8 @@ +name: uuid +in: path +description: | + The UUID of the service request to be retrieved. It must be valid and relate to an existing Service Request otherwise a HTTP 404 response will be returned. +required: true +schema: + type: string + example: 'a.832db7fa-ebdd-44b6-ab3b-8329c2d43149' diff --git a/specification/components/r4/schemas/responses/getCommunication/200Response.yaml b/specification/components/r4/schemas/responses/getCommunication/200Response.yaml new file mode 100644 index 000000000..6bac17488 --- /dev/null +++ b/specification/components/r4/schemas/responses/getCommunication/200Response.yaml @@ -0,0 +1,21 @@ +description: Response contains the Service Request requested. +headers: + X-Correlation-ID: + $ref: '../../headers/response/CorrelationID.yaml' + X-Request-ID: + $ref: '../../headers/response/RequestID.yaml' + ETag: + $ref: '../../headers/response/ETag.yaml' + Cache-Control: + $ref: '../../headers/response/CacheControl.yaml' + Content-Type: + $ref: '../../headers/response/ContentTypeFhirJson.yaml' +content: + application/fhir+json: + schema: + $ref: '../../eRS-Communication.yaml' + examples: + initial-communication: + summary: Initial Communication. + value: + $ref: '../../../examples/getCommunication/responses/initialCommunication.json' diff --git a/specification/components/r4/schemas/responses/getDocumentReference/200Response.yaml b/specification/components/r4/schemas/responses/getDocumentReference/200Response.yaml new file mode 100644 index 000000000..e6168337e --- /dev/null +++ b/specification/components/r4/schemas/responses/getDocumentReference/200Response.yaml @@ -0,0 +1,21 @@ +description: Response contains the Service Request requested. +headers: + X-Correlation-ID: + $ref: '../../headers/response/CorrelationID.yaml' + X-Request-ID: + $ref: '../../headers/response/RequestID.yaml' + ETag: + $ref: '../../headers/response/ETag.yaml' + Cache-Control: + $ref: '../../headers/response/CacheControl.yaml' + Content-Type: + $ref: '../../headers/response/ContentTypeFhirJson.yaml' +content: + application/fhir+json: + schema: + $ref: '../../eRS-DocumentReference.yaml' + examples: + initial-communication: + summary: Initial Communication. + value: + $ref: '../../../examples/getDocumentReference/responses/AdviceRequestAttachment.json' diff --git a/specification/components/r4/schemas/responses/getQuestionnaireResponse/200Response.yaml b/specification/components/r4/schemas/responses/getQuestionnaireResponse/200Response.yaml new file mode 100644 index 000000000..3fc56080a --- /dev/null +++ b/specification/components/r4/schemas/responses/getQuestionnaireResponse/200Response.yaml @@ -0,0 +1,21 @@ +description: Response contains the Service Request requested. +headers: + X-Correlation-ID: + $ref: '../../headers/response/CorrelationID.yaml' + X-Request-ID: + $ref: '../../headers/response/RequestID.yaml' + ETag: + $ref: '../../headers/response/ETag.yaml' + Cache-Control: + $ref: '../../headers/response/CacheControl.yaml' + Content-Type: + $ref: '../../headers/response/ContentTypeFhirJson.yaml' +content: + application/fhir+json: + schema: + $ref: '../../eRS-QuestionnaireResponse.yaml' + examples: + initial-communication: + summary: Initial Communication. + value: + $ref: '../../../examples/getQuestionnaireResponse/responses/basicQuestionnaireResponse.json' diff --git a/specification/components/r4/schemas/responses/getServiceRequest/200Response.yaml b/specification/components/r4/schemas/responses/getServiceRequest/200Response.yaml new file mode 100644 index 000000000..c87b5a3c6 --- /dev/null +++ b/specification/components/r4/schemas/responses/getServiceRequest/200Response.yaml @@ -0,0 +1,33 @@ +description: Response contains the Service Request requested. +headers: + X-Correlation-ID: + $ref: '../../headers/response/CorrelationID.yaml' + X-Request-ID: + $ref: '../../headers/response/RequestID.yaml' + ETag: + $ref: '../../headers/response/ETag.yaml' + Cache-Control: + $ref: '../../headers/response/CacheControl.yaml' + Content-Type: + $ref: '../../headers/response/ContentTypeFhirJson.yaml' +content: + application/fhir+json: + schema: + $ref: '../../eRS-ServiceRequest.yaml' + examples: + advice-requested: + summary: Advice Requested. + value: + $ref: '../../../examples/getServiceRequest/responses/adviceRequestedAandG.json' + incomplete: + summary: Incomplete. + value: + $ref: '../../../examples/getServiceRequest/responses/incompleteAandG.json' + shortlisted: + summary: Incomplete. + value: + $ref: '../../../examples/getServiceRequest/responses/shortlistedAandG.json' + shortlisted-with-attachment: + summary: Incomplete. + value: + $ref: '../../../examples/getServiceRequest/responses/shortlistedAandGAttachment.json' diff --git a/specification/e-referrals-service-api.yaml b/specification/e-referrals-service-api.yaml index da7daafb1..104659eb5 100644 --- a/specification/e-referrals-service-api.yaml +++ b/specification/e-referrals-service-api.yaml @@ -383,6 +383,18 @@ paths: /R4/Communication: post: $ref: 'components/r4/schemas/endpoints/a0X4-create-update-communication.yaml' + /R4/ServiceRequest/{uuid}: + get: + $ref: 'components/r4/schemas/endpoints/a0X5-retrieve-service-request.yaml' + /R4/Communication/{uuid}: + get: + $ref: 'components/r4/schemas/endpoints/a0X6-retrieve-communication.yaml' + /R4/DocumentReference/{uuid}: + get: + $ref: 'components/r4/schemas/endpoints/a0X7-retrieve-document-reference.yaml' + /R4/QuestionnaireResponse/{uuid}: + get: + $ref: 'components/r4/schemas/endpoints/a0X8-retrieve-questionnaire-response.yaml' components: securitySchemes: bearerAuth: