diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index d913736d..9be9b426 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -51,9 +51,6 @@ https://nhsd-jira.digital.nhs.uk/browse/NPA-XXXX - [ ] Commit messages follow the template: `NPA-XXXX: ` - [ ] All acceptance criteria from the Jira ticket are addressed - [ ] Automated tests (unit/integration/API/infrastructure etc. tests) are added or updated -- [ ] The [traceability matrix](https://nhsd-confluence.digital.nhs.uk/display/NPA/Traceability+matrix) is updated - with - new tests or requirements - [ ] Assignees and appropriate labels (e.g. `terraform`, `documentation`) are added --- diff --git a/.gitignore b/.gitignore index 7b7cda0d..50666f81 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,8 @@ env .dir-locals.el *.pyc +openapitools.json + sandbox/output.json sandbox/pytest_html_report.html sandbox/archive/ diff --git a/postman/Validate Relationship Service Sandbox.postman_collection.json b/postman/Validated Relationship Service Sandbox.postman_collection.json similarity index 95% rename from postman/Validate Relationship Service Sandbox.postman_collection.json rename to postman/Validated Relationship Service Sandbox.postman_collection.json index 67b91c2b..cf310cf2 100644 --- a/postman/Validate Relationship Service Sandbox.postman_collection.json +++ b/postman/Validated Relationship Service Sandbox.postman_collection.json @@ -1,10 +1,11 @@ { "info": { - "_postman_id": "679cd3dc-8b52-4699-84e3-499fce3d7e15", - "name": "Validated Relationship Service Sandbox 28/08/25", + "_postman_id": "66c6bd03-3fda-4ff7-9be9-bace275b60cf", + "name": "Validated Relationship Service Sandbox 08/09/25", "description": "This Postman collection includes example scenarios for each of the Validated Relationship Service (VRS) API endpoints, covering both valid and invalid request scenarios.\n\nThe collection is pointed towards the VRS sandbox environment, which will return a specific example response based on the request sent. All data shown in the requests or responses is test data.\n\nOur sandbox environment only covers the scenarios listed in the Postman collection and is open access. It does not allow you to test authorisation or any scenarios beyond the ones documented.\n\nFull specification is available at [https://digital.nhs.uk/developer/api-catalogue/validated-relationship-service](https://digital.nhs.uk/developer/api-catalogue/validated-relationship-service)", "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", - "_exporter_id": "18067099" + "_exporter_id": "45653607", + "_collection_link": "https://www.postman.com/lukeelliott-8674106/workspace/validated-relationship-service-sandbox-08-11-2025/collection/45653607-66c6bd03-3fda-4ff7-9be9-bace275b60cf?action=share&source=collection_link&creator=45653607" }, "item": [ { @@ -21,6 +22,10 @@ " \"resourceType\": \"QuestionnaireResponse\",", " \"status\": \"completed\",", " \"authored\": \"2024-07-15T09:43:03.280Z\",", + " \"id\": \"156e1560-e532-4e2a-85ad-5aeff03dc43e\",", + " \"identifier\": {", + " \"value\": \"19318ZGLAB\"", + " },", " \"source\": {", " \"type\": \"RelatedPerson\",", " \"identifier\": {", @@ -230,7 +235,7 @@ } ], "url": { - "raw": "{{api_base_url}}/QuestionnaireResponse?referenceCode=19318ZGLAB", + "raw": "{{api_base_url}}/QuestionnaireResponse?ID=156e1560-e532-4e2a-85ad-5aeff03dc43e", "host": [ "{{api_base_url}}" ], @@ -239,8 +244,8 @@ ], "query": [ { - "key": "referenceCode", - "value": "19318ZGLAB" + "key": "ID", + "value": "156e1560-e532-4e2a-85ad-5aeff03dc43e" } ] }, @@ -249,30 +254,30 @@ "response": [] }, { - "name": "Missing Reference Code", + "name": "Missing Access Request UUID", "event": [ { "listen": "test", "script": { "exec": [ "const expectedResponseBody = {", - " \"resourceType\": \"OperationOutcome\",", - " \"issue\": [", - " {", - " \"severity\": \"error\",", - " \"code\": \"required\",", - " \"details\": {", - " \"coding\": [", - " {", - " \"system\": \"https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode\",", - " \"code\": \"MISSING_REFERENCE_CODE\",", - " \"display\": \"Missing reference code\"", - " }", - " ]", - " },", - " \"diagnostics\": \"The reference code parameter is required but was not provided.\"", - " }", - " ]", + " \"resourceType\": \"OperationOutcome\",", + " \"issue\": [", + " {", + " \"severity\": \"error\",", + " \"code\": \"required\",", + " \"details\": {", + " \"coding\": [", + " {", + " \"system\": \"https://fhir.nhs.uk/STU3/CodeSystem/Spine-ErrorOrWarningCode-1\",", + " \"code\": \"BAD_REQUEST\",", + " \"display\": \"Bad request\"", + " }", + " ]", + " },", + " \"diagnostics\": \"The access request ID parameter is required but was not provided.\"", + " }", + " ]", "};", "", "pm.test(\"Status code is 400\", function () {", @@ -317,31 +322,31 @@ "response": [] }, { - "name": "Invalid Reference Code", + "name": "Invalid Access Request UUID", "event": [ { "listen": "test", "script": { "exec": [ "const expectedResponseBody = {", - " \"resourceType\": \"OperationOutcome\",", - " \"issue\": [", - " {", - " \"severity\": \"error\",", - " \"code\": \"invalid\",", - " \"details\": {", - " \"coding\": [", - " {", - " \"system\": \"https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode\",", - " \"code\": \"INVALID_REFERENCE_CODE\",", - " \"display\": \"Invalid reference code\"", - " }", - " ]", - " },", - " \"diagnostics\": \"The specified reference code format is invalid. Reference codes must be alphanumeric.\"", - " }", - " ]", - "};", + " \"resourceType\": \"OperationOutcome\",", + " \"issue\": [", + " {", + " \"severity\": \"error\",", + " \"code\": \"invalid\",", + " \"details\": {", + " \"coding\": [", + " {", + " \"system\": \"https://fhir.nhs.uk/STU3/CodeSystem/Spine-ErrorOrWarningCode-1\",", + " \"code\": \"INVALID_IDENTIFIER_VALUE\",", + " \"display\": \"Invalid identifier value\",", + " }", + " ]", + " },", + " \"diagnostics\": \"The specified access request ID is invalid. Access request IDs must be a valid UUID.\",", + " }", + " ],", + " };", "", "pm.test(\"Status code is 400\", function () {", " pm.response.to.have.status(400);", @@ -372,7 +377,7 @@ } ], "url": { - "raw": "{{api_base_url}}/QuestionnaireResponse?referenceCode=INVALID", + "raw": "{{api_base_url}}/QuestionnaireResponse?ID=INVALID", "host": [ "{{api_base_url}}" ], @@ -381,7 +386,7 @@ ], "query": [ { - "key": "referenceCode", + "key": "ID", "value": "INVALID" } ] @@ -391,30 +396,30 @@ "response": [] }, { - "name": "Reference Code Not Found", + "name": "Access Request UUID Not Found", "event": [ { "listen": "test", "script": { "exec": [ "const expectedResponseBody = {", - " \"resourceType\": \"OperationOutcome\",", - " \"issue\": [", - " {", - " \"severity\": \"error\",", - " \"code\": \"not-found\",", - " \"details\": {", - " \"coding\": [", - " {", - " \"system\": \"https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode\",", - " \"code\": \"QUESTIONNAIRE_RESPONSE_NOT_FOUND\",", - " \"display\": \"Questionnaire response not found\"", - " }", - " ]", - " },", - " \"diagnostics\": \"The Questionnaire response could not be found using the provided reference code.\"", - " }", - " ]", + " \"resourceType\": \"OperationOutcome\",", + " \"issue\": [", + " {", + " \"severity\": \"error\",", + " \"code\": \"not-found\",", + " \"details\": {", + " \"coding\": [", + " {", + " \"system\": \"https://fhir.nhs.uk/STU3/CodeSystem/Spine-ErrorOrWarningCode-1\",", + " \"code\": \"QUESTIONNAIRE_RESPONSE_NOT_FOUND\",", + " \"display\": \"Questionnaire response not found\"", + " }", + " ]", + " },", + " \"diagnostics\": \"The Questionnaire response could not be found using the provided access request ID.\"", + " }", + " ]", "};", "", "pm.test(\"Status code is 404\", function () {", @@ -446,7 +451,7 @@ } ], "url": { - "raw": "{{api_base_url}}/QuestionnaireResponse?referenceCode=ABC123XY", + "raw": "{{api_base_url}}/QuestionnaireResponse?ID=60d09b82-f4bb-41f9-b41e-767999b4ac9b", "host": [ "{{api_base_url}}" ], @@ -455,8 +460,8 @@ ], "query": [ { - "key": "referenceCode", - "value": "ABC123XY" + "key": "ID", + "value": "60d09b82-f4bb-41f9-b41e-767999b4ac9b" } ] }, @@ -502,7 +507,11 @@ "pm.test(\"Response has the correct body\", () => {", " const responseJson = pm.response.json();", " pm.expect(responseJson).to.eql(expectedResponseBody);", - "});" + "});", + "", + "pm.test(\"Location header is returned\", () => {", + " pm.response.to.have.header(\"Location\", \"https://sandbox.api.service.nhs.uk/validated-relationships/FHIR/R4/QuestionnaireResponse?ID=156e1560-e532-4e2a-85ad-5aeff03dc43e\")", + "})" ], "type": "text/javascript", "packages": {} @@ -582,7 +591,11 @@ "pm.test(\"Response has the correct body\", () => {", " const responseJson = pm.response.json();", " pm.expect(responseJson).to.eql(expectedResponseBody);", - "});" + "});", + "", + "pm.test(\"Location header is returned\", () => {", + " pm.response.to.have.header(\"Location\", \"https://sandbox.api.service.nhs.uk/validated-relationships/FHIR/R4/QuestionnaireResponse?ID=156e1560-e532-4e2a-85ad-5aeff03dc43e\")", + "})" ], "type": "text/javascript", "packages": {} @@ -728,7 +741,11 @@ "pm.test(\"Response has the correct body\", () => {", " const responseJson = pm.response.json();", " pm.expect(responseJson).to.eql(expectedResponseBody);", - "});" + "});", + "", + "pm.test(\"Location header is returned\", () => {", + " pm.response.to.have.header(\"Location\", \"https://sandbox.api.service.nhs.uk/validated-relationships/FHIR/R4/QuestionnaireResponse?ID=156e1560-e532-4e2a-85ad-5aeff03dc43e\")", + "})" ], "type": "text/javascript", "packages": {} @@ -807,7 +824,11 @@ "pm.test(\"Response has the correct body\", () => {", " const responseJson = pm.response.json();", " pm.expect(responseJson).to.eql(expectedResponseBody);", - "});" + "});", + "", + "pm.test(\"Location header is returned\", () => {", + " pm.response.to.have.header(\"Location\", \"https://sandbox.api.service.nhs.uk/validated-relationships/FHIR/R4/QuestionnaireResponse?ID=156e1560-e532-4e2a-85ad-5aeff03dc43e\")", + "})" ], "type": "text/javascript", "packages": {} @@ -2106,6 +2127,15 @@ " \"resource\": {", " \"resourceType\": \"Patient\",", " \"id\": \"A3CC67E2\",", + " \"meta\": {", + " \"security\": [", + " {", + " \"system\": \"https://fhir.nhs.uk/CodeSystem/NHSIdentityProofingLevel\",", + " \"code\": \"P9\",", + " \"display\": \"High level verification (P9)\"", + " }", + " ]", + " },", " \"identifier\": [", " {", " \"system\": \"https://fhir.nhs.uk/Id/nhs-number\",", @@ -2226,7 +2256,7 @@ " \"end\": \"2026-02-11\",", " \"start\": \"2025-02-11\"", " }", - " },", + " }", " },", " \"search\": {", " \"mode\": \"match\"", @@ -2275,6 +2305,15 @@ " \"resource\": {", " \"resourceType\": \"Patient\",", " \"id\": \"DFCC67F5\",", + " \"meta\": {", + " \"security\": [", + " {", + " \"system\": \"https://fhir.nhs.uk/CodeSystem/NHSIdentityProofingLevel\",", + " \"code\": \"P9\",", + " \"display\": \"High level verification (P9)\"", + " }", + " ]", + " },", " \"identifier\": [", " {", " \"system\": \"https://fhir.nhs.uk/Id/nhs-number\",", @@ -2391,7 +2430,7 @@ " \"end\": \"2026-02-11\",", " \"start\": \"2025-02-11\"", " }", - " },", + " }", " },", " \"search\": {", " \"mode\": \"match\"", @@ -3410,6 +3449,15 @@ " \"resource\": {", " \"resourceType\": \"Patient\",", " \"id\": \"A3CC67E2\",", + " \"meta\": {", + " \"security\": [", + " {", + " \"system\": \"https://fhir.nhs.uk/CodeSystem/NHSIdentityProofingLevel\",", + " \"code\": \"P9\",", + " \"display\": \"High level verification (P9)\"", + " }", + " ]", + " },", " \"identifier\": [", " {", " \"system\": \"https://fhir.nhs.uk/Id/nhs-number\",", @@ -3530,7 +3578,7 @@ " \"end\": \"2026-02-11\",", " \"start\": \"2025-02-11\"", " }", - " },", + " }", " },", " \"search\": {", " \"mode\": \"match\"", @@ -3541,6 +3589,15 @@ " \"resource\": {", " \"resourceType\": \"Patient\",", " \"id\": \"DFCC67F5\",", + " \"meta\": {", + " \"security\": [", + " {", + " \"system\": \"https://fhir.nhs.uk/CodeSystem/NHSIdentityProofingLevel\",", + " \"code\": \"P9\",", + " \"display\": \"High level verification (P9)\"", + " }", + " ]", + " },", " \"identifier\": [", " {", " \"system\": \"https://fhir.nhs.uk/Id/nhs-number\",", @@ -3657,7 +3714,7 @@ " \"end\": \"2026-02-11\",", " \"start\": \"2025-02-11\"", " }", - " },", + " }", " },", " \"search\": {", " \"mode\": \"match\"", @@ -3668,6 +3725,15 @@ " \"resource\": {", " \"resourceType\": \"Patient\",", " \"id\": \"ZPTT32T3\",", + " \"meta\": {", + " \"security\": [", + " {", + " \"system\": \"https://fhir.nhs.uk/CodeSystem/NHSIdentityProofingLevel\",", + " \"code\": \"P9\",", + " \"display\": \"High level verification (P9)\"", + " }", + " ]", + " },", " \"identifier\": [", " {", " \"system\": \"https://fhir.nhs.uk/Id/nhs-number\",", @@ -3784,7 +3850,7 @@ " \"end\": \"2026-02-11\",", " \"start\": \"2025-02-11\"", " }", - " },", + " }", " },", " \"search\": {", " \"mode\": \"match\"", @@ -4319,6 +4385,15 @@ " \"resource\": {", " \"resourceType\": \"Patient\",", " \"id\": \"A3CC67E2\",", + " \"meta\": {", + " \"security\": [", + " {", + " \"system\": \"https://fhir.nhs.uk/CodeSystem/NHSIdentityProofingLevel\",", + " \"code\": \"P9\",", + " \"display\": \"High level verification (P9)\"", + " }", + " ]", + " },", " \"identifier\": [", " {", " \"system\": \"https://fhir.nhs.uk/Id/nhs-number\",", @@ -4439,7 +4514,7 @@ " \"end\": \"2026-02-11\",", " \"start\": \"2025-02-11\"", " }", - " },", + " }", " },", " \"search\": {", " \"mode\": \"match\"", @@ -4488,6 +4563,15 @@ " \"resource\": {", " \"resourceType\": \"Patient\",", " \"id\": \"DFCC67F5\",", + " \"meta\": {", + " \"security\": [", + " {", + " \"system\": \"https://fhir.nhs.uk/CodeSystem/NHSIdentityProofingLevel\",", + " \"code\": \"P9\",", + " \"display\": \"High level verification (P9)\"", + " }", + " ]", + " },", " \"identifier\": [", " {", " \"system\": \"https://fhir.nhs.uk/Id/nhs-number\",", @@ -4604,7 +4688,7 @@ " \"end\": \"2026-02-11\",", " \"start\": \"2025-02-11\"", " }", - " },", + " }", " },", " \"search\": {", " \"mode\": \"match\"", @@ -4653,6 +4737,15 @@ " \"resource\": {", " \"resourceType\": \"Patient\",", " \"id\": \"ZPTT32T3\",", + " \"meta\": {", + " \"security\": [", + " {", + " \"system\": \"https://fhir.nhs.uk/CodeSystem/NHSIdentityProofingLevel\",", + " \"code\": \"P9\",", + " \"display\": \"High level verification (P9)\"", + " }", + " ]", + " },", " \"identifier\": [", " {", " \"system\": \"https://fhir.nhs.uk/Id/nhs-number\",", @@ -4769,7 +4862,7 @@ " \"end\": \"2026-02-11\",", " \"start\": \"2025-02-11\"", " }", - " },", + " }", " },", " \"search\": {", " \"mode\": \"match\"", @@ -5142,6 +5235,15 @@ " \"resource\": {", " \"resourceType\": \"Patient\",", " \"id\": \"A3CC67E2\",", + " \"meta\": {", + " \"security\": [", + " {", + " \"system\": \"https://fhir.nhs.uk/CodeSystem/NHSIdentityProofingLevel\",", + " \"code\": \"P9\",", + " \"display\": \"High level verification (P9)\"", + " }", + " ]", + " },", " \"identifier\": [", " {", " \"system\": \"https://fhir.nhs.uk/Id/nhs-number\",", @@ -5301,7 +5403,7 @@ " \"end\": \"2026-02-11\",", " \"start\": \"2025-02-11\"", " }", - " },", + " }", " },", " \"search\": {", " \"mode\": \"match\"", @@ -5419,7 +5521,7 @@ " \"end\": \"2026-02-11\",", " \"start\": \"2025-02-11\"", " }", - " },", + " }", " },", " \"search\": {", " \"mode\": \"match\"", @@ -5537,7 +5639,7 @@ " \"end\": \"2026-02-11\",", " \"start\": \"2025-02-11\"", " }", - " },", + " }", " },", " \"search\": {", " \"mode\": \"match\"", @@ -6033,6 +6135,15 @@ " \"resource\": {", " \"resourceType\": \"Patient\",", " \"id\": \"A3CC67E2\",", + " \"meta\": {", + " \"security\": [", + " {", + " \"system\": \"https://fhir.nhs.uk/CodeSystem/NHSIdentityProofingLevel\",", + " \"code\": \"P9\",", + " \"display\": \"High level verification (P9)\"", + " }", + " ]", + " },", " \"identifier\": [", " {", " \"system\": \"https://fhir.nhs.uk/Id/nhs-number\",", @@ -6149,7 +6260,7 @@ " \"end\": \"2026-02-11\",", " \"start\": \"2025-02-11\"", " }", - " },", + " }", " },", " \"search\": {", " \"mode\": \"match\"", @@ -6229,7 +6340,7 @@ " \"end\": \"2026-02-11\",", " \"start\": \"2025-02-11\"", " }", - " },", + " }", " },", " \"search\": {", " \"mode\": \"match\"", @@ -6309,7 +6420,7 @@ " \"end\": \"2026-02-11\",", " \"start\": \"2025-02-11\"", " }", - " },", + " }", " },", " \"search\": {", " \"mode\": \"match\"", @@ -6612,6 +6723,15 @@ " \"resource\": {", " \"resourceType\": \"Patient\",", " \"id\": \"DFCC67F5\",", + " \"meta\": {", + " \"security\": [", + " {", + " \"system\": \"https://fhir.nhs.uk/CodeSystem/NHSIdentityProofingLevel\",", + " \"code\": \"P9\",", + " \"display\": \"High level verification (P9)\"", + " }", + " ]", + " },", " \"identifier\": [", " {", " \"system\": \"https://fhir.nhs.uk/Id/nhs-number\",", @@ -6728,7 +6848,7 @@ " \"end\": \"2026-02-11\",", " \"start\": \"2025-02-11\"", " }", - " },", + " }", " },", " \"search\": {", " \"mode\": \"match\"", @@ -6984,6 +7104,15 @@ " \"resource\": {", " \"resourceType\": \"Patient\",", " \"id\": \"A3CC67E2\",", + " \"meta\": {", + " \"security\": [", + " {", + " \"system\": \"https://fhir.nhs.uk/CodeSystem/NHSIdentityProofingLevel\",", + " \"code\": \"P9\",", + " \"display\": \"High level verification (P9)\"", + " }", + " ]", + " },", " \"identifier\": [", " {", " \"system\": \"https://fhir.nhs.uk/Id/nhs-number\",", @@ -7104,7 +7233,7 @@ " \"end\": \"2026-02-11\",", " \"start\": \"2025-02-11\"", " }", - " },", + " }", " },", " \"search\": {", " \"mode\": \"match\"", @@ -8031,119 +8160,128 @@ "script": { "exec": [ "const expectedResponseBody = {", - " \"resourceType\": \"Bundle\",", - " \"timestamp\": \"2020-08-26T14:00:00+00:00\",", - " \"total\": 1,", - " \"type\": \"searchset\",", - " \"link\": [", + " \"resourceType\": \"Bundle\",", + " \"timestamp\": \"2020-08-26T14:00:00+00:00\",", + " \"total\": 1,", + " \"type\": \"searchset\",", + " \"link\": [", " {", " \"relation\": \"self\",", " \"url\": \"https://sandbox.api.service.nhs.uk/validated-relationships/FHIR/R4/Consent?performer:identifier=9000000010&_include=Consent:patient\"", " }", " ],", - " \"entry\": [", - " {", - " \"fullUrl\": \"https://api.service.nhs.uk/validated-relationships/FHIR/R4/Patient/DFCC67F5\",", - " \"resource\": {", - " \"resourceType\": \"Patient\",", - " \"id\": \"DFCC67F5\",", - " \"identifier\": [", - " {", - " \"system\": \"https://fhir.nhs.uk/Id/nhs-number\",", - " \"value\": \"9000000005\"", - " },", - " {", - " \"system\": \"https://placeholder.fhir.nhs.uk/Id/local-gp-patient-identifier\",", - " \"value\": \"ABC1234567\"", - " }", - " ],", - " \"name\": [", - " {", - " \"id\": \"123456\",", - " \"use\": \"usual\",", - " \"period\": {", - " \"start\": \"2020-01-01\",", - " \"end\": \"2021-12-31\"", + " \"entry\": [", + " {", + " \"fullUrl\": \"https://api.service.nhs.uk/validated-relationships/FHIR/R4/Patient/DFCC67F5\",", + " \"resource\": {", + " \"resourceType\": \"Patient\",", + " \"id\": \"DFCC67F5\",", + " \"meta\": {", + " \"security\": [", + " {", + " \"system\": \"https://fhir.nhs.uk/CodeSystem/NHSIdentityProofingLevel\",", + " \"code\": \"P9\",", + " \"display\": \"High level verification (P9)\"", + " }", + " ]", + " },", + " \"identifier\": [", + " {", + " \"system\": \"https://fhir.nhs.uk/Id/nhs-number\",", + " \"value\": \"9000000005\"", + " },", + " {", + " \"system\": \"https://placeholder.fhir.nhs.uk/Id/local-gp-patient-identifier\",", + " \"value\": \"ABC1234567\"", + " }", + " ],", + " \"name\": [", + " {", + " \"id\": \"123456\",", + " \"use\": \"usual\",", + " \"period\": {", + " \"start\": \"2020-01-01\",", + " \"end\": \"2021-12-31\"", + " },", + " \"given\": [", + " \"Sally\"", + " ],", + " \"family\": \"Evans\",", + " \"prefix\": [", + " \"Mrs\"", + " ]", + " }", + " ],", + " \"birthDate\": \"1995-10-22\",", + " \"generalPractitioner\": [", + " {", + " \"type\": \"Organization\",", + " \"identifier\": {", + " \"value\": \"ODS12345\",", + " \"system\": \"https://fhir.nhs.uk/Id/ods-organization-code\"", + " }", + " }", + " ]", " },", - " \"given\": [", - " \"Sally\"", - " ],", - " \"family\": \"Evans\",", - " \"prefix\": [", - " \"Mrs\"", - " ]", - " }", - " ],", - " \"birthDate\": \"1995-10-22\",", - " \"generalPractitioner\": [", - " {", - " \"type\": \"Organization\",", - " \"identifier\": {", - " \"value\": \"ODS12345\",", - " \"system\": \"https://fhir.nhs.uk/Id/ods-organization-code\"", - " }", - " }", - " ]", - " },", - " \"search\": {", - " \"mode\": \"include\"", - " }", - " },", - " {", - " \"fullUrl\": \"https://api.service.nhs.uk/validated-relationships/FHIR/R4/Consent/WWCC67T1\",", - " \"resource\": {", - " \"resourceType\": \"Consent\",", - " \"id\": \"WWCC67T1\",", - " \"status\": \"active\",", - " \"scope\": {", - " \"coding\": [", - " {", - " \"system\": \"http://terminology.hl7.org/CodeSystem/consentscope\",", - " \"code\": \"patient-privacy\",", - " \"display\": \"Privacy Consent\"", + " \"search\": {", + " \"mode\": \"include\"", " }", - " ],", - " \"text\": \"Patient Privacy Consent\"", - " },", - " \"category\": [", - " {", - " \"coding\": [", - " {", - " \"system\": \"http://terminology.hl7.org/CodeSystem/v3-ActCode\",", - " \"code\": \"INFA\",", - " \"display\": \"Information Access\"", - " }", - " ],", - " \"text\": \"Information Access Consent\"", - " }", - " ],", - " \"patient\": {", - " \"identifier\": {", - " \"system\": \"https://fhir.nhs.uk/Id/nhs-number\",", - " \"value\": \"9000000005\"", - " }", " },", - " \"dateTime\": \"2024-07-21T17:32:28Z\",", - " \"performer\": [", - " {", - " \"identifier\": {", - " \"system\": \"https://fhir.nhs.uk/Id/nhs-number\",", - " \"value\": \"9000000010\"", - " }", - " }", - " ],", - " \"policy\": [", - " {", - " \"authority\": \"https://www.england.nhs.uk\",", - " \"uri\": \"REPLACE_WITH_LINK_TO_PUBLISHED_NATIONAL_PROXY_STANDARD\"", + " {", + " \"fullUrl\": \"https://api.service.nhs.uk/validated-relationships/FHIR/R4/Consent/WWCC67T1\",", + " \"resource\": {", + " \"resourceType\": \"Consent\",", + " \"id\": \"WWCC67T1\",", + " \"status\": \"active\",", + " \"scope\": {", + " \"coding\": [", + " {", + " \"system\": \"http://terminology.hl7.org/CodeSystem/consentscope\",", + " \"code\": \"patient-privacy\",", + " \"display\": \"Privacy Consent\"", + " }", + " ],", + " \"text\": \"Patient Privacy Consent\"", + " },", + " \"category\": [", + " {", + " \"coding\": [", + " {", + " \"system\": \"http://terminology.hl7.org/CodeSystem/v3-ActCode\",", + " \"code\": \"INFA\",", + " \"display\": \"Information Access\"", + " }", + " ],", + " \"text\": \"Information Access Consent\"", + " }", + " ],", + " \"patient\": {", + " \"identifier\": {", + " \"system\": \"https://fhir.nhs.uk/Id/nhs-number\",", + " \"value\": \"9000000005\"", + " }", + " },", + " \"dateTime\": \"2024-07-21T17:32:28Z\",", + " \"performer\": [", + " {", + " \"identifier\": {", + " \"system\": \"https://fhir.nhs.uk/Id/nhs-number\",", + " \"value\": \"9000000010\"", + " }", + " }", + " ],", + " \"policy\": [", + " {", + " \"authority\": \"https://www.england.nhs.uk\",", + " \"uri\": \"REPLACE_WITH_LINK_TO_PUBLISHED_NATIONAL_PROXY_STANDARD\"", + " }", + " ]", + " },", + " \"search\": {", + " \"mode\": \"match\"", " }", - " ],", - " },", - " \"search\": {", - " \"mode\": \"match\"", - " }", - " }", - " ]", + " }", + " ]", "}", "", "pm.test(\"Status code is 200\", function () {", @@ -8394,6 +8532,15 @@ " \"resource\": {", " \"resourceType\": \"Patient\",", " \"id\": \"DFCC67F5\",", + " \"meta\": {", + " \"security\": [", + " {", + " \"system\": \"https://fhir.nhs.uk/CodeSystem/NHSIdentityProofingLevel\",", + " \"code\": \"P9\",", + " \"display\": \"High level verification (P9)\"", + " }", + " ]", + " },", " \"identifier\": [", " {", " \"system\": \"https://fhir.nhs.uk/Id/nhs-number\",", @@ -8510,7 +8657,7 @@ " \"end\": \"2026-02-11\",", " \"start\": \"2025-02-11\"", " }", - " },", + " }", " },", " \"search\": {", " \"mode\": \"match\"", @@ -8518,7 +8665,6 @@ " }", " ]", "}", - "", "pm.test(\"Status code is 200\", function () {", " pm.response.to.have.status(200);", "});", @@ -8699,123 +8845,132 @@ "script": { "exec": [ "const expectedResponseBody = {", - " \"resourceType\": \"Bundle\",", - " \"timestamp\": \"2020-08-26T14:00:00+00:00\",", - " \"total\": 1,", - " \"type\": \"searchset\",", - " \"link\": [", + " \"resourceType\": \"Bundle\",", + " \"timestamp\": \"2020-08-26T14:00:00+00:00\",", + " \"total\": 1,", + " \"type\": \"searchset\",", + " \"link\": [", " {", " \"relation\": \"self\",", " \"url\": \"https://sandbox.api.service.nhs.uk/validated-relationships/FHIR/R4/Consent?performer:identifier=9000000019&_include=Consent:patient\"", " }", " ],", - " \"entry\": [", - " {", - " \"fullUrl\": \"https://api.service.nhs.uk/validated-relationships/FHIR/R4/Patient/A3CC67E2\",", - " \"resource\": {", - " \"resourceType\": \"Patient\",", - " \"id\": \"A3CC67E2\",", - " \"identifier\": [", - " {", - " \"system\": \"https://fhir.nhs.uk/Id/nhs-number\",", - " \"value\": \"9000000009\"", - " },", - " {", - " \"system\": \"https://placeholder.fhir.nhs.uk/Id/local-gp-patient-identifier\",", - " \"value\": \"ABC1234556\"", - " }", - " ],", - " \"name\": [", - " {", - " \"id\": \"123456\",", - " \"use\": \"usual\",", - " \"period\": {", - " \"start\": \"2020-01-01\",", - " \"end\": \"2021-12-31\"", + " \"entry\": [", + " {", + " \"fullUrl\": \"https://api.service.nhs.uk/validated-relationships/FHIR/R4/Patient/A3CC67E2\",", + " \"resource\": {", + " \"resourceType\": \"Patient\",", + " \"id\": \"A3CC67E2\",", + " \"meta\": {", + " \"security\": [", + " {", + " \"system\": \"https://fhir.nhs.uk/CodeSystem/NHSIdentityProofingLevel\",", + " \"code\": \"P9\",", + " \"display\": \"High level verification (P9)\"", + " }", + " ]", + " },", + " \"identifier\": [", + " {", + " \"system\": \"https://fhir.nhs.uk/Id/nhs-number\",", + " \"value\": \"9000000009\"", + " },", + " {", + " \"system\": \"https://placeholder.fhir.nhs.uk/Id/local-gp-patient-identifier\",", + " \"value\": \"ABC1234556\"", + " }", + " ],", + " \"name\": [", + " {", + " \"id\": \"123456\",", + " \"use\": \"usual\",", + " \"period\": {", + " \"start\": \"2020-01-01\",", + " \"end\": \"2021-12-31\"", + " },", + " \"given\": [", + " \"Jane Marie Anne\"", + " ],", + " \"family\": \"Smith\",", + " \"prefix\": [", + " \"Mrs\"", + " ],", + " \"suffix\": [", + " \"MBE\",", + " \"PhD\"", + " ]", + " }", + " ],", + " \"birthDate\": \"2022-10-22\",", + " \"generalPractitioner\": [", + " {", + " \"type\": \"Organization\",", + " \"identifier\": {", + " \"value\": \"ODS12345\",", + " \"system\": \"https://fhir.nhs.uk/Id/ods-organization-code\"", + " }", + " }", + " ]", " },", - " \"given\": [", - " \"Jane Marie Anne\"", - " ],", - " \"family\": \"Smith\",", - " \"prefix\": [", - " \"Mrs\"", - " ],", - " \"suffix\": [", - " \"MBE\",", - " \"PhD\"", - " ]", - " }", - " ],", - " \"birthDate\": \"2022-10-22\",", - " \"generalPractitioner\": [", - " {", - " \"type\": \"Organization\",", - " \"identifier\": {", - " \"value\": \"ODS12345\",", - " \"system\": \"https://fhir.nhs.uk/Id/ods-organization-code\"", - " }", - " }", - " ]", - " },", - " \"search\": {", - " \"mode\": \"include\"", - " }", - " },", - " {", - " \"fullUrl\": \"https://api.service.nhs.uk/validated-relationships/FHIR/R4/Consent/BBCC67E9\",", - " \"resource\": {", - " \"resourceType\": \"Consent\",", - " \"id\": \"BBCC67E9\",", - " \"status\": \"active\",", - " \"scope\": {", - " \"coding\": [", - " {", - " \"system\": \"http://terminology.hl7.org/CodeSystem/consentscope\",", - " \"code\": \"patient-privacy\",", - " \"display\": \"Privacy Consent\"", + " \"search\": {", + " \"mode\": \"include\"", " }", - " ],", - " \"text\": \"Patient Privacy Consent\"", " },", - " \"category\": [", - " {", - " \"coding\": [", - " {", - " \"system\": \"http://terminology.hl7.org/CodeSystem/v3-ActCode\",", - " \"code\": \"INFA\",", - " \"display\": \"Information Access\"", - " }", - " ],", - " \"text\": \"Information Access Consent\"", - " }", - " ],", - " \"patient\": {", - " \"identifier\": {", - " \"system\": \"https://fhir.nhs.uk/Id/nhs-number\",", - " \"value\": \"9000000009\"", - " }", - " },", - " \"dateTime\": \"2024-07-21T17:32:28Z\",", - " \"performer\": [", - " {", - " \"identifier\": {", - " \"system\": \"https://fhir.nhs.uk/Id/nhs-number\",", - " \"value\": \"9000000019\"", - " }", - " }", - " ],", - " \"policy\": [", - " {", - " \"authority\": \"https://www.england.nhs.uk\",", - " \"uri\": \"REPLACE_WITH_LINK_TO_PUBLISHED_NATIONAL_PROXY_STANDARD\"", + " {", + " \"fullUrl\": \"https://api.service.nhs.uk/validated-relationships/FHIR/R4/Consent/BBCC67E9\",", + " \"resource\": {", + " \"resourceType\": \"Consent\",", + " \"id\": \"BBCC67E9\",", + " \"status\": \"active\",", + " \"scope\": {", + " \"coding\": [", + " {", + " \"system\": \"http://terminology.hl7.org/CodeSystem/consentscope\",", + " \"code\": \"patient-privacy\",", + " \"display\": \"Privacy Consent\"", + " }", + " ],", + " \"text\": \"Patient Privacy Consent\"", + " },", + " \"category\": [", + " {", + " \"coding\": [", + " {", + " \"system\": \"http://terminology.hl7.org/CodeSystem/v3-ActCode\",", + " \"code\": \"INFA\",", + " \"display\": \"Information Access\"", + " }", + " ],", + " \"text\": \"Information Access Consent\"", + " }", + " ],", + " \"patient\": {", + " \"identifier\": {", + " \"system\": \"https://fhir.nhs.uk/Id/nhs-number\",", + " \"value\": \"9000000009\"", + " }", + " },", + " \"dateTime\": \"2024-07-21T17:32:28Z\",", + " \"performer\": [", + " {", + " \"identifier\": {", + " \"system\": \"https://fhir.nhs.uk/Id/nhs-number\",", + " \"value\": \"9000000019\"", + " }", + " }", + " ],", + " \"policy\": [", + " {", + " \"authority\": \"https://www.england.nhs.uk\",", + " \"uri\": \"REPLACE_WITH_LINK_TO_PUBLISHED_NATIONAL_PROXY_STANDARD\"", + " }", + " ]", + " },", + " \"search\": {", + " \"mode\": \"match\"", " }", - " ]", - " },", - " \"search\": {", - " \"mode\": \"match\"", - " }", - " }", - " ]", + " }", + " ]", "}", "", "pm.test(\"Status code is 200\", function () {", @@ -9070,6 +9225,15 @@ " \"resource\": {", " \"resourceType\": \"Patient\",", " \"id\": \"A3CC67E2\",", + " \"meta\": {", + " \"security\": [", + " {", + " \"system\": \"https://fhir.nhs.uk/CodeSystem/NHSIdentityProofingLevel\",", + " \"code\": \"P9\",", + " \"display\": \"High level verification (P9)\"", + " }", + " ]", + " },", " \"identifier\": [", " {", " \"system\": \"https://fhir.nhs.uk/Id/nhs-number\",", @@ -9190,7 +9354,7 @@ " \"end\": \"2026-02-11\",", " \"start\": \"2025-02-11\"", " }", - " },", + " }", " },", " \"search\": {", " \"mode\": \"match\"", diff --git a/sandbox/README.md b/sandbox/README.md index 7f1cbfee..5fc49f9d 100644 --- a/sandbox/README.md +++ b/sandbox/README.md @@ -63,6 +63,10 @@ Please note all commands are meant to be run from this directory `/sandbox` To run the API with hot reloading use `make start-dev` +### Updating examples + +The examples held in `./api/examples/` are copied at sandbox startup from `../specification/examples/`. See [Makefile](./Makefile) `start` & `start-dev`. + ### Testing #### Unit Tests diff --git a/sandbox/api/constants.py b/sandbox/api/constants.py index 7467d933..0f6bdcda 100644 --- a/sandbox/api/constants.py +++ b/sandbox/api/constants.py @@ -100,8 +100,8 @@ # GET QuestionnaireResponse GET_QUESTIONNAIRE_RESPONSE_DIRECTORY = "./api/examples/GET_QuestionnaireResponse/" GET_QUESTIONNAIRE_RESPONSE__SUCCESS = f"{GET_QUESTIONNAIRE_RESPONSE_DIRECTORY}success.yaml" -GET_QUESTIONNAIRE_RESPONSE__INVALID = f"{GET_QUESTIONNAIRE_RESPONSE_DIRECTORY}errors/invalid_reference_code.yaml" -GET_QUESTIONNAIRE_RESPONSE__MISSING = f"{GET_QUESTIONNAIRE_RESPONSE_DIRECTORY}errors/missing_reference_code.yaml" +GET_QUESTIONNAIRE_RESPONSE__INVALID = f"{GET_QUESTIONNAIRE_RESPONSE_DIRECTORY}errors/invalid_access_request_id.yaml" +GET_QUESTIONNAIRE_RESPONSE__MISSING = f"{GET_QUESTIONNAIRE_RESPONSE_DIRECTORY}errors/missing_access_request_id.yaml" GET_QUESTIONNAIRE_RESPONSE__NOT_FOUND = ( f"{GET_QUESTIONNAIRE_RESPONSE_DIRECTORY}errors/questionnaire_response_not_found.yaml" ) diff --git a/sandbox/api/get_questionnaire_response.py b/sandbox/api/get_questionnaire_response.py index eb8c7366..795340d4 100644 --- a/sandbox/api/get_questionnaire_response.py +++ b/sandbox/api/get_questionnaire_response.py @@ -23,17 +23,17 @@ def get_questionnaire_response_response() -> Union[dict, tuple]: Union[dict, tuple]: Response for GET /QuestionnaireResponse """ try: - reference_code = request.args.get("referenceCode") - if reference_code == "19318ZGLAB": + access_request_id = request.args.get("ID") + if access_request_id == "156e1560-e532-4e2a-85ad-5aeff03dc43e": return generate_response_from_example(GET_QUESTIONNAIRE_RESPONSE__SUCCESS, 200) - elif reference_code == "INVALID": + elif access_request_id == "INVALID": return generate_response_from_example(GET_QUESTIONNAIRE_RESPONSE__INVALID, 400) - elif reference_code == "" or reference_code is None: + elif access_request_id == "" or access_request_id is None: return generate_response_from_example(GET_QUESTIONNAIRE_RESPONSE__MISSING, 400) - elif reference_code == "ABC123XY": + elif access_request_id == "60d09b82-f4bb-41f9-b41e-767999b4ac9b": return generate_response_from_example(GET_QUESTIONNAIRE_RESPONSE__NOT_FOUND, 404) else: - raise ValueError("Invalid reference code") + raise ValueError("Invalid access request ID") except Exception: logger.exception("GET questionnaire response failed") return generate_response_from_example(INTERNAL_SERVER_ERROR_EXAMPLE, 500) diff --git a/sandbox/api/post_questionnaire_response.py b/sandbox/api/post_questionnaire_response.py index fb08d136..da5cfde1 100644 --- a/sandbox/api/post_questionnaire_response.py +++ b/sandbox/api/post_questionnaire_response.py @@ -10,6 +10,9 @@ ) from .utils import generate_response_from_example +QUESTIONNAIRE_RESPONSE_APP_BASE_PATH = ( + "https://sandbox.api.service.nhs.uk/validated-relationships/FHIR/R4/QuestionnaireResponse" +) basicConfig(level=INFO, format="%(asctime)s - %(message)s") logger = getLogger(__name__) @@ -29,7 +32,8 @@ def post_questionnaire_response_response() -> Union[dict, tuple]: # Successful questionnaire response if source_identifier in ["9000000009", "9000000017"]: - response = generate_response_from_example(POST_QUESTIONNAIRE_RESPONSE__SUCCESS, 200) + header = {"location": f"{QUESTIONNAIRE_RESPONSE_APP_BASE_PATH}?ID=156e1560-e532-4e2a-85ad-5aeff03dc43e"} + response = generate_response_from_example(POST_QUESTIONNAIRE_RESPONSE__SUCCESS, 200, headers=header) # Duplicate relationship elif source_identifier == "9000000049": response = generate_response_from_example(POST_QUESTIONNAIRE_RESPONSE__DUPLICATE_RELATIONSHIP_ERROR, 409) diff --git a/sandbox/api/tests/test_get_questionnaire_response.py b/sandbox/api/tests/test_get_questionnaire_response.py index 02fee64b..72f9ab05 100644 --- a/sandbox/api/tests/test_get_questionnaire_response.py +++ b/sandbox/api/tests/test_get_questionnaire_response.py @@ -10,34 +10,34 @@ ("request_args", "response_file_name", "status_code"), [ ( - "referenceCode=19318ZGLAB", + "ID=156e1560-e532-4e2a-85ad-5aeff03dc43e", "./api/examples/GET_QuestionnaireResponse/success.yaml", 200, ), ( - "referenceCode=INVALID", - "./api/examples/GET_QuestionnaireResponse/errors/invalid_reference_code.yaml", + "ID=INVALID", + "./api/examples/GET_QuestionnaireResponse/errors/invalid_access_request_id.yaml", 400, ), ( - "referenceCode=", - "./api/examples/GET_QuestionnaireResponse/errors/missing_reference_code.yaml", + "ID=", + "./api/examples/GET_QuestionnaireResponse/errors/missing_access_request_id.yaml", 400, ), ( - "referenceCode=ABC123XY", + "ID=60d09b82-f4bb-41f9-b41e-767999b4ac9b", "./api/examples/GET_QuestionnaireResponse/errors/questionnaire_response_not_found.yaml", 404, ), ( - "referenceCode=INVALID_CODE", + "ID=INVALID_CODE", "./api/examples/errors/internal-server-error.yaml", 500, ), ], ) @patch("sandbox.api.get_questionnaire_response.generate_response_from_example") -def test_get_consent_returns_expected_responses__mocked_utils( +def test_get_questionnaire_response_returns_expected_responses__mocked_utils( mock_generate_response_from_example: MagicMock, request_args: str, response_file_name: str, diff --git a/sandbox/api/tests/test_post_questionnaire_response.py b/sandbox/api/tests/test_post_questionnaire_response.py index 6cef14be..7851f8b4 100644 --- a/sandbox/api/tests/test_post_questionnaire_response.py +++ b/sandbox/api/tests/test_post_questionnaire_response.py @@ -10,31 +10,36 @@ INTERNAL_SERVER_ERROR_EXAMPLE, ) +SANDBOX_API_URL = "https://sandbox.api.service.nhs.uk/validated-relationships" QUESTIONNAIRE_RESPONSE_API_ENDPOINT = "/FHIR/R4/QuestionnaireResponse" @pytest.mark.parametrize( - ("nhs_num", "response_file_name", "status_code"), + ("nhs_num", "response_file_name", "status_code", "id"), [ ( "9000000009", POST_QUESTIONNAIRE_RESPONSE__SUCCESS, 200, + "156e1560-e532-4e2a-85ad-5aeff03dc43e", ), ( "9000000017", POST_QUESTIONNAIRE_RESPONSE__SUCCESS, 200, + "156e1560-e532-4e2a-85ad-5aeff03dc43e", ), ( "9000000049", POST_QUESTIONNAIRE_RESPONSE__DUPLICATE_RELATIONSHIP_ERROR, 409, + None, ), ( "INVALID_NHS_NUMBER", INTERNAL_SERVER_ERROR_EXAMPLE, 500, + None, ), ], ) @@ -42,6 +47,7 @@ def test_post_questionnaire_response( mock_generate_response_from_example: MagicMock, nhs_num: str, + id: str, response_file_name: str, status_code: int, client: object, @@ -57,6 +63,13 @@ def test_post_questionnaire_response( # Act response = client.post(QUESTIONNAIRE_RESPONSE_API_ENDPOINT, json=json) # Assert - mock_generate_response_from_example.assert_called_once_with(response_file_name, status_code) + if id is not None: + mock_generate_response_from_example.assert_called_once_with( + response_file_name, + status_code, + headers={"location": f"{SANDBOX_API_URL}{QUESTIONNAIRE_RESPONSE_API_ENDPOINT}?ID={id}"}, + ) + else: + mock_generate_response_from_example.assert_called_once_with(response_file_name, status_code) assert response.status_code == status_code assert response.json == loads(mocked_response.get_data(as_text=True)) diff --git a/specification/examples/responses/GET_QuestionnaireResponse/errors/invalid_access_request_id.yaml b/specification/examples/responses/GET_QuestionnaireResponse/errors/invalid_access_request_id.yaml new file mode 100644 index 00000000..81d65d5d --- /dev/null +++ b/specification/examples/responses/GET_QuestionnaireResponse/errors/invalid_access_request_id.yaml @@ -0,0 +1,14 @@ +InvalidAccessRequestID: + summary: Invalid access request ID + description: The provided access request ID is invalid in format. + value: + resourceType: "OperationOutcome" + issue: + - severity: "error" + code: "invalid" + details: + coding: + - system: "https://fhir.nhs.uk/STU3/CodeSystem/Spine-ErrorOrWarningCode-1" + code: "INVALID_IDENTIFIER_VALUE" + display: "Invalid identifier value" + diagnostics: "The specified access request ID is invalid. Access request IDs must be a valid UUID." diff --git a/specification/examples/responses/GET_QuestionnaireResponse/errors/invalid_reference_code.yaml b/specification/examples/responses/GET_QuestionnaireResponse/errors/invalid_reference_code.yaml deleted file mode 100644 index 79868514..00000000 --- a/specification/examples/responses/GET_QuestionnaireResponse/errors/invalid_reference_code.yaml +++ /dev/null @@ -1,14 +0,0 @@ -InvalidReferenceCode: - summary: Invalid reference code - description: The provided reference code is invalid in format. - value: - resourceType: "OperationOutcome" - issue: - - severity: "error" - code: "invalid" - details: - coding: - - system: "https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode" - code: "INVALID_REFERENCE_CODE" - display: "Invalid reference code" - diagnostics: "The specified reference code format is invalid. Reference codes must be alphanumeric." \ No newline at end of file diff --git a/specification/examples/responses/GET_QuestionnaireResponse/errors/missing_access_request_id.yaml b/specification/examples/responses/GET_QuestionnaireResponse/errors/missing_access_request_id.yaml new file mode 100644 index 00000000..92e53386 --- /dev/null +++ b/specification/examples/responses/GET_QuestionnaireResponse/errors/missing_access_request_id.yaml @@ -0,0 +1,14 @@ +MissingAccessRequestID: + summary: Missing access request ID + description: No access request ID was provided in the request. + value: + resourceType: "OperationOutcome" + issue: + - severity: "error" + code: "required" + details: + coding: + - system: "https://fhir.nhs.uk/STU3/CodeSystem/Spine-ErrorOrWarningCode-1" + code: "BAD_REQUEST" + display: "Bad request" + diagnostics: "The access request ID parameter is required but was not provided." diff --git a/specification/examples/responses/GET_QuestionnaireResponse/errors/missing_reference_code.yaml b/specification/examples/responses/GET_QuestionnaireResponse/errors/missing_reference_code.yaml deleted file mode 100644 index 3d4c4cbb..00000000 --- a/specification/examples/responses/GET_QuestionnaireResponse/errors/missing_reference_code.yaml +++ /dev/null @@ -1,14 +0,0 @@ -MissingReferenceCode: - summary: Missing reference code - description: No reference code was provided in the request. - value: - resourceType: "OperationOutcome" - issue: - - severity: "error" - code: "required" - details: - coding: - - system: "https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode" - code: "MISSING_REFERENCE_CODE" - display: "Missing reference code" - diagnostics: "The reference code parameter is required but was not provided." \ No newline at end of file diff --git a/specification/examples/responses/GET_QuestionnaireResponse/errors/questionnaire_response_not_found.yaml b/specification/examples/responses/GET_QuestionnaireResponse/errors/questionnaire_response_not_found.yaml index 0f9a924e..04627dfe 100644 --- a/specification/examples/responses/GET_QuestionnaireResponse/errors/questionnaire_response_not_found.yaml +++ b/specification/examples/responses/GET_QuestionnaireResponse/errors/questionnaire_response_not_found.yaml @@ -1,6 +1,6 @@ QuestionnaireResponseNotFound: summary: Questionnaire response not found - description: The Questionnaire response could not be found using the provided reference code. + description: The Questionnaire response could not be found using the provided access request ID. value: resourceType: "OperationOutcome" issue: @@ -8,7 +8,7 @@ QuestionnaireResponseNotFound: code: "not-found" details: coding: - - system: "https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode" + - system: "https://fhir.nhs.uk/STU3/CodeSystem/Spine-ErrorOrWarningCode-1" code: "QUESTIONNAIRE_RESPONSE_NOT_FOUND" display: "Questionnaire response not found" - diagnostics: "The Questionnaire response could not be found using the provided reference code." + diagnostics: "The Questionnaire response could not be found using the provided access request ID." diff --git a/specification/examples/responses/GET_QuestionnaireResponse/success.yaml b/specification/examples/responses/GET_QuestionnaireResponse/success.yaml index 19ca9595..c3538a83 100644 --- a/specification/examples/responses/GET_QuestionnaireResponse/success.yaml +++ b/specification/examples/responses/GET_QuestionnaireResponse/success.yaml @@ -5,6 +5,9 @@ GetQuestionnaireResponseSuccess: resourceType: QuestionnaireResponse status: "completed" authored: "2024-07-15T09:43:03.280Z" + id: "156e1560-e532-4e2a-85ad-5aeff03dc43e" + identifier: + value: "19318ZGLAB" source: type: "RelatedPerson" identifier: diff --git a/specification/examples/responses/POST_QuestionnaireResponse/success.yaml b/specification/examples/responses/POST_QuestionnaireResponse/success.yaml index 6177456d..2cf2d6db 100644 --- a/specification/examples/responses/POST_QuestionnaireResponse/success.yaml +++ b/specification/examples/responses/POST_QuestionnaireResponse/success.yaml @@ -9,4 +9,4 @@ PostQuestionnaireResponseSuccess: details: coding: - code: "19318ZGLAB" - display: "19318ZGLAB" + display: "19318ZGLAB" \ No newline at end of file diff --git a/specification/validated-relationships-service-api.yaml b/specification/validated-relationships-service-api.yaml index 523e6186..43601572 100644 --- a/specification/validated-relationships-service-api.yaml +++ b/specification/validated-relationships-service-api.yaml @@ -141,7 +141,7 @@ info: * only covers a limited set of scenarios * is open access, so does not allow you to test authorisation - [Run In Postman](https://app.getpostman.com/run-collection/18067099-679cd3dc-8b52-4699-84e3-499fce3d7e15?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D18067099-679cd3dc-8b52-4699-84e3-499fce3d7e15%26entityType%3Dcollection%26workspaceId%3D8a8e66e5-71af-4830-9f29-9d98cbec443a) + [Run In Postman](https://god.gw.postman.com/run-collection/45653607-66c6bd03-3fda-4ff7-9be9-bace275b60cf?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D45653607-66c6bd03-3fda-4ff7-9be9-bace275b60cf%26entityType%3Dcollection%26workspaceId%3Dbd95b9f9-f9b0-4f1f-958a-2f6822c182c1) ### Integration testing @@ -238,7 +238,13 @@ paths: $ref: "./examples/requests/POST_QuestionnaireResponse/duplicate_relationship.yaml#/QuestionnaireResponseDuplicateRelationship" responses: "200": - description: Request was received successfully for processing + description: Request was received successfully for processing + headers: + location: + schema: + type: string + example: https://sandbox.api.service.nhs.uk/validated-relationships/FHIR/R4/QuestionnaireResponse?ID=156e1560-e532-4e2a-85ad-5aeff03dc43e + description: URL for the newly created access request content: application/fhir+json: schema: @@ -292,11 +298,11 @@ paths: summary: Get a proxy access request description: | ## Overview - Retrieve a QuestionnaireResponse using its unique reference code. This endpoint returns the full + Retrieve a QuestionnaireResponse using its unique access request ID. This endpoint returns the full QuestionnaireResponse document that was previously submitted. ## Request Requirements - A valid reference code must be provided as a query parameter. This reference code is returned + A valid access request ID must be provided as a query parameter. This access request ID is returned when a QuestionnaireResponse is initially submitted via the POST endpoint. ## Access modes @@ -307,25 +313,25 @@ paths: ## Sandbox test scenarios - | Scenario | Request | Response | - | --------------------------- | -------------------------- | ------------------------------------------------------------- | - | Valid reference code | referenceCode=19318ZGLAB | HTTP Status 200 with QuestionnaireResponse | - | Invalid reference code | referenceCode=INVALID | HTTP Status 400 with INVALID_REFERENCE_CODE message | - | Missing reference code | No referenceCode parameter | HTTP Status 400 with MISSING_REFERENCE_CODE message | - | Non-existent reference code | referenceCode=ABC123XY | HTTP Status 404 with QUESTIONNAIRE_RESPONSE_NOT_FOUND message | + | Scenario | Request | Response | + | -------------------------------- | ----------------------------------------| ------------------------------------------------------------- | + | Valid access request ID | ID=156e1560-e532-4e2a-85ad-5aeff03dc43e | HTTP Status 200 with QuestionnaireResponse | + | Invalid access request ID | ID=INVALID | HTTP Status 400 with INVALID_IDENTIFIER_VALUE message | + | Missing access request ID | No ID parameter | HTTP Status 400 with BAD_REQUEST message | + | Non-existent access request ID | ID=60d09b82-f4bb-41f9-b41e-767999b4ac9b | HTTP Status 404 with QUESTIONNAIRE_RESPONSE_NOT_FOUND message | operationId: get-questionnaire-response parameters: - $ref: "#/components/parameters/BearerAuthorization" - $ref: "#/components/parameters/RequestID" - $ref: "#/components/parameters/CorrelationID" - - name: referenceCode + - name: ID in: query - description: The unique reference code of the QuestionnaireResponse to retrieve + description: The unique access request ID of the QuestionnaireResponse to retrieve required: true schema: type: string - example: "19318ZGLAB" + example: "156e1560-e532-4e2a-85ad-5aeff03dc43e" responses: "200": description: QuestionnaireResponse successfully retrieved. @@ -342,13 +348,13 @@ paths: | HTTP status | Error code | Description | | ----------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | - | 400 | `INVALID_REFERENCE_CODE` | The reference code must be alphanumeric and exactly 10 characters long. | + | 400 | `INVALID_IDENTIFIER_VALUE` | The access request ID must be a valid uuid. | | 400 | `INVALID_VALUE` | Invalid Parameter or Invalid operation. | - | 400 | `MISSING_REFERENCE_CODE` | The reference code is required but was not provided in the request. | + | 400 | `BAD_REQUEST` | The access request ID is required but was not provided in the request. | | 400 | `MISSING_VALUE` | Missing header or parameter. For details, see the `diagnostics` field. | | 401 | `ACCESS_DENIED` | Missing or invalid OAuth 2.0 bearer token in request. | | 403 | `FORBIDDEN` | Access denied to resource. | - | 404 | `QUESTIONNAIRE_RESPONSE_NOT_FOUND` | No questionnaire response was found for the provided reference code. | + | 404 | `QUESTIONNAIRE_RESPONSE_NOT_FOUND` | No questionnaire response was found for the provided access request ID. | | 404 | `INVALIDATED_RESOURCE` | Resource that has been marked as invalid was requested - invalid resources cannot be retrieved | | 405 | `METHOD_NOT_ALLOWED` | The method is not allowed. | | 408 | `TIMEOUT` | Request timed out. | @@ -359,11 +365,11 @@ paths: schema: $ref: "#/components/schemas/OperationOutcome" examples: - invalidReferenceCode: - $ref: "./examples/responses/GET_QuestionnaireResponse/errors/invalid_reference_code.yaml#/InvalidReferenceCode" - missingReferenceCode: - $ref: "./examples/responses/GET_QuestionnaireResponse/errors/missing_reference_code.yaml#/MissingReferenceCode" - referenceCodeNotFound: + invalidAccessRequestID: + $ref: "./examples/responses/GET_QuestionnaireResponse/errors/invalid_access_request_id.yaml#/InvalidAccessRequestID" + missingAccessRequestID: + $ref: "./examples/responses/GET_QuestionnaireResponse/errors/missing_access_request_id.yaml#/MissingAccessRequestID" + questionnaireResponseNotFound: $ref: "./examples/responses/GET_QuestionnaireResponse/errors/questionnaire_response_not_found.yaml#/QuestionnaireResponseNotFound" "5XX": description: | @@ -539,12 +545,12 @@ paths: | Multiple proxy relationships without filtering and details | `performer:identifier`=`9000000022` | HTTP Status 200 Bundle containing a multiple proxy relationships without details | | Multiple proxy relationships including performer details | `performer:identifier`=`9000000022` and `_include` = `Consent:performer` | HTTP Status 200 Bundle containing a multiple proxy relationships including performer details | | Multiple proxy relationships including patient details | `performer:identifier`=`9000000022` and `_include` = `Consent:patient` | HTTP Status 200 Bundle containing a multiple proxy relationships including patient details | - | Multiple proxy relationships including performer and patient details | `performer:identifier`=`9000000022` and `_include` = `Consent:patient` and `_include` = `Consent:performer` | HTTP Status 200 Bundle containing a multiple proxy relationships including performer and patient details | + | Multiple proxy relationships including performer and patient details | `performer:identifier`=`9000000022` and `_include` = `Consent:patient` and `_include` = `Consent:performer` | HTTP Status 200 Bundle containing a multiple proxy relationships including performer and patient details | | Multiple proxy relationships, single patient | `patient:identifier`=`9000000100` | HTTP Status 200 Bundle containing a multiple proxy relationships including performer and patient details | - | Multiple proxy relationships, single patient, including proxy details | `patient:identifier`=`9000000100` and `_include` = `Consent:performer` | HTTP Status 200 Bundle containing a multiple proxy relationships including proxy details | + | Multiple proxy relationships, single patient, including proxy details | `patient:identifier`=`9000000100` and `_include` = `Consent:performer` | HTTP Status 200 Bundle containing a multiple proxy relationships including proxy details | | Multiple proxy relationships, single patient, including patient details | `patient:identifier`=`9000000100` and `_include` = `Consent:patient` | HTTP Status 200 Bundle containing a multiple proxy relationships including patient details | - | Multiple proxy relationships, single patient, including proxy and patient details | `patient:identifier`=`9000000100` and `_include` = `Consent:patient` and `_include` = `Consent:performer` | HTTP Status 200 Bundle containing a multiple proxy relationships including proxy and patient details | - | No proxy relationships | `performer:identifier`=`9000000025` and `_include` = `Consent:patient` and `_include` = `Consent:performer` and `status` = `active` | HTTP Status 200 empty bundle | + | Multiple proxy relationships, single patient, including proxy and patient details | `patient:identifier`=`9000000100` and `_include` = `Consent:patient` and `_include` = `Consent:performer` | HTTP Status 200 Bundle containing a multiple proxy relationships including proxy and patient details | + | No proxy relationships | `performer:identifier`=`9000000025` and `_include` = `Consent:patient` and `_include` = `Consent:performer` and `status` = `active` | HTTP Status 200 empty bundle | | A single proxy relationship between consenting adults | `performer:identifier`=`9000000010` and/or `patient:identifier`=`9000000005` | HTTP Status 200 Bundle containing a single proxy relationship | | A single proxy relationship between consenting adults including details | `performer:identifier`=`9000000010` and/or `patient:identifier`=`9000000005` and `_include` = `Consent:patient` and `_include` = `Consent:proxy` | HTTP Status 200 Bundle containing a single proxy relationship including performer and patient details | | A single proxy relationship between a mother and child | `performer:identifier`=`9000000019` and/or `patient:identifier`=`9000000009` | HTTP Status 200 Bundle containing a single proxy relationship |