Skip to content

Commit 75b84f4

Browse files
committed
NRL-1188 merge develop
1 parent 8b88655 commit 75b84f4

File tree

56 files changed

+2749
-727
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+2749
-727
lines changed

.github/workflows/daily-build.yml

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
name: Build NRL Project on Environment
2+
run-name: Build NRL Project on ${{ inputs.environment || 'dev' }}
3+
permissions:
4+
id-token: write
5+
contents: read
6+
actions: write
7+
8+
on:
9+
schedule:
10+
- cron: "0 1 * * *"
11+
workflow_dispatch:
12+
inputs:
13+
environment:
14+
type: environment
15+
description: "The environment to deploy changes to"
16+
default: "dev"
17+
required: true
18+
19+
jobs:
20+
build:
21+
name: Build - develop
22+
runs-on: [self-hosted, ci]
23+
24+
steps:
25+
- name: Git clone - develop
26+
uses: actions/checkout@v4
27+
with:
28+
ref: develop
29+
30+
- name: Setup asdf cache
31+
uses: actions/cache@v4
32+
with:
33+
path: ~/.asdf
34+
key: ${{ runner.os }}-asdf-${{ hashFiles('**/.tool-versions') }}
35+
restore-keys: |
36+
${{ runner.os }}-asdf-
37+
38+
- name: Install asdf
39+
uses: asdf-vm/actions/[email protected]
40+
with:
41+
asdf_branch: v0.13.1
42+
43+
- name: Install zip
44+
run: sudo apt-get install zip
45+
46+
- name: Setup Python environment
47+
run: |
48+
poetry install --no-root
49+
source $(poetry env info --path)/bin/activate
50+
51+
- name: Run Linting
52+
run: make lint
53+
54+
- name: Run Unit Tests
55+
run: make test
56+
57+
- name: Build Project
58+
run: make build
59+
60+
- name: Configure Management Credentials
61+
uses: aws-actions/configure-aws-credentials@v4
62+
with:
63+
aws-region: eu-west-2
64+
role-to-assume: ${{ secrets.MGMT_ROLE_ARN }}
65+
role-session-name: github-actions-ci-${{ inputs.environment || 'dev' }}-${{ github.run_id }}
66+
67+
- name: Add S3 Permissions to Lambda
68+
run: |
69+
account=$(echo '${{ inputs.environment || 'dev' }}' | cut -d '-' -f1)
70+
inactive_stack=$(poetry run python ./scripts/get_env_config.py inactive-stack ${{ inputs.environment || 'dev' }})
71+
make get-s3-perms ENV=${account} TF_WORKSPACE_NAME=${inactive_stack}
72+
73+
- name: Save Build Artifacts
74+
uses: actions/upload-artifact@v4
75+
with:
76+
name: build-artifacts
77+
path: |
78+
dist/*.zip
79+
!dist/nrlf_permissions.zip
80+
81+
- name: Save NRLF Permissions cache
82+
uses: actions/cache/save@v4
83+
with:
84+
key: ${{ github.run_id }}-nrlf-permissions
85+
path: dist/nrlf_permissions.zip

api/consumer/searchDocumentReference/search_document_reference.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from nrlf.core.logger import LogReference, logger
1010
from nrlf.core.model import ConnectionMetadata, ConsumerRequestParams
1111
from nrlf.core.response import Response, SpineErrorResponse
12-
from nrlf.core.validators import validate_category, validate_type_system
12+
from nrlf.core.validators import validate_category, validate_type
1313

1414

1515
@request_handler(params=ConsumerRequestParams)
@@ -46,15 +46,14 @@ def handler(
4646
base_url = f"https://{config.ENVIRONMENT}.api.service.nhs.uk/"
4747
self_link = f"{base_url}record-locator/consumer/FHIR/R4/DocumentReference?subject:identifier=https://fhir.nhs.uk/Id/nhs-number|{params.nhs_number}"
4848

49-
# TODO - Add checks for the type code as well as system
50-
if not validate_type_system(params.type, metadata.pointer_types):
49+
if not validate_type(params.type, metadata.pointer_types):
5150
logger.log(
5251
LogReference.CONSEARCH002,
5352
type=params.type,
5453
pointer_types=metadata.pointer_types,
5554
)
5655
return SpineErrorResponse.INVALID_CODE_SYSTEM(
57-
diagnostics="Invalid query parameter (The provided type system does not match the allowed types for this organisation)",
56+
diagnostics="Invalid query parameter (The provided type does not match the allowed types for this organisation)",
5857
expression="type",
5958
)
6059

api/consumer/searchDocumentReference/tests/test_search_document_reference_consumer.py

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,56 @@ def test_search_document_reference_happy_path(repository: DocumentPointerReposit
5959
}
6060

6161

62+
@mock_aws
63+
@mock_repository
64+
def test_search_document_reference_accession_number_in_pointer(
65+
repository: DocumentPointerRepository,
66+
):
67+
doc_ref = load_document_reference("Y05868-736253002-Valid")
68+
doc_ref.identifier = [
69+
{"type": {"text": "Accession-Number"}, "value": "Y05868.123456789"}
70+
]
71+
doc_pointer = DocumentPointer.from_document_reference(doc_ref)
72+
repository.create(doc_pointer)
73+
74+
event = create_test_api_gateway_event(
75+
headers=create_headers(),
76+
query_string_parameters={
77+
"subject:identifier": "https://fhir.nhs.uk/Id/nhs-number|6700028191",
78+
},
79+
)
80+
81+
result = handler(event, create_mock_context())
82+
body = result.pop("body")
83+
84+
assert result == {
85+
"statusCode": "200",
86+
"headers": default_response_headers(),
87+
"isBase64Encoded": False,
88+
}
89+
90+
parsed_body = json.loads(body)
91+
assert parsed_body == {
92+
"resourceType": "Bundle",
93+
"type": "searchset",
94+
"total": 1,
95+
"link": [
96+
{
97+
"relation": "self",
98+
"url": "https://pytest.api.service.nhs.uk/record-locator/consumer/FHIR/R4/DocumentReference?subject:identifier=https://fhir.nhs.uk/Id/nhs-number|6700028191",
99+
}
100+
],
101+
"entry": [{"resource": doc_ref.model_dump(exclude_none=True)}],
102+
}
103+
104+
created_doc_pointer = repository.get_by_id("Y05868-99999-99999-999999")
105+
106+
assert created_doc_pointer is not None
107+
assert json.loads(created_doc_pointer.document)["identifier"] == [
108+
{"type": {"text": "Accession-Number"}, "value": "Y05868.123456789"}
109+
]
110+
111+
62112
@mock_aws
63113
@mock_repository
64114
def test_search_document_reference_happy_path_with_custodian(
@@ -451,7 +501,7 @@ def test_search_document_reference_invalid_type(repository: DocumentPointerRepos
451501
}
452502
]
453503
},
454-
"diagnostics": "Invalid query parameter (The provided type system does not match the allowed types for this organisation)",
504+
"diagnostics": "Invalid query parameter (The provided type does not match the allowed types for this organisation)",
455505
"expression": ["type"],
456506
}
457507
],

api/consumer/searchPostDocumentReference/search_post_document_reference.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from nrlf.core.logger import LogReference, logger
1010
from nrlf.core.model import ConnectionMetadata, ConsumerRequestParams
1111
from nrlf.core.response import Response, SpineErrorResponse
12-
from nrlf.core.validators import validate_category, validate_type_system
12+
from nrlf.core.validators import validate_category, validate_type
1313

1414

1515
@request_handler(body=ConsumerRequestParams)
@@ -50,14 +50,14 @@ def handler(
5050
base_url = f"https://{config.ENVIRONMENT}.api.service.nhs.uk/"
5151
self_link = f"{base_url}record-locator/consumer/FHIR/R4/DocumentReference?subject:identifier=https://fhir.nhs.uk/Id/nhs-number|{body.nhs_number}"
5252

53-
if not validate_type_system(body.type, metadata.pointer_types):
53+
if not validate_type(body.type, metadata.pointer_types):
5454
logger.log(
5555
LogReference.CONPOSTSEARCH002,
5656
type=body.type,
5757
pointer_types=metadata.pointer_types,
5858
)
5959
return SpineErrorResponse.INVALID_CODE_SYSTEM(
60-
diagnostics="Invalid type (The provided type system does not match the allowed types for this organisation)",
60+
diagnostics="The provided type does not match the allowed types for this organisation",
6161
expression="type",
6262
)
6363

api/consumer/searchPostDocumentReference/tests/test_search_post_document_reference_consumer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ def test_search_post_document_reference_invalid_type(
424424
}
425425
]
426426
},
427-
"diagnostics": "Invalid type (The provided type system does not match the allowed types for this organisation)",
427+
"diagnostics": "The provided type does not match the allowed types for this organisation",
428428
"expression": ["type"],
429429
}
430430
],

api/consumer/swagger.yaml

Lines changed: 86 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ info:
3636
* [End of Life Care Coordination Summary](http://snomed.info/sct/861421000000109)
3737
* [Emergency health care plan](http://snomed.info/sct/887701000000100)
3838
* [Lloyd George record folder](http://snomed.info/sct/16521000000101)
39-
* [Advanced care plan](http://snomed.info/sct/736366004)
39+
* [Advance care plan](http://snomed.info/sct/736366004)
4040
* [Treatment escalation plan](http://snomed.info/sct/735324008)
4141
* [Summary record]("http://snomed.info/sct|824321000000109")
4242
* [Personalised Care and Support Plan]("http://snomed.info/sct|2181441000000107")
@@ -788,7 +788,7 @@ components:
788788
description: The status of this document reference.
789789
docStatus:
790790
type: string
791-
pattern: "[^\\s]+(\\s[^\\s]+)*"
791+
enum: ["entered-in-error", "amended", "preliminary", "final"]
792792
description: The status of the underlying document.
793793
type:
794794
$ref: "#/components/schemas/CodeableConcept"
@@ -1065,15 +1065,19 @@ components:
10651065
$ref: "#/components/schemas/Attachment"
10661066
description: The document or URL of the document along with critical metadata to prove content has integrity.
10671067
format:
1068-
$ref: "#/components/schemas/Coding"
1068+
$ref: "#/components/schemas/NRLFormatCode"
10691069
description: An identifier of the document encoding, structure, and template that the document conforms to beyond the base format indicated in the mimeType.
10701070
extension:
10711071
type: array
10721072
items:
1073-
$ref: "#/components/schemas/Extension"
1074-
description: Additional content defined by implementations.
1073+
$ref: "#/components/schemas/ContentStabilityExtension"
1074+
description: Additional extension for content stability.
1075+
minItems: 1
1076+
maxItems: 1
10751077
required:
10761078
- attachment
1079+
- format
1080+
- extension
10771081
DocumentReferenceRelatesTo:
10781082
type: object
10791083
properties:
@@ -1130,6 +1134,9 @@ components:
11301134
type: string
11311135
pattern: ([0-9]([0-9]([0-9][1-9]|[1-9]0)|[1-9]00)|[1-9]000)(-(0[1-9]|1[0-2])(-(0[1-9]|[1-2][0-9]|3[0-1])(T([01][0-9]|2[0-3]):[0-5][0-9]:([0-5][0-9]|60)(\.[0-9]+)?(Z|(\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00)))?)?)?
11321136
description: The date that the attachment was first created.
1137+
required:
1138+
- contentType
1139+
- url
11331140
CodeableConcept:
11341141
type: object
11351142
properties:
@@ -1146,11 +1153,6 @@ components:
11461153
type: string
11471154
pattern: "[ \\r\\n\\t\\S]+"
11481155
description: A human language representation of the concept as seen/selected/uttered by the user who entered the data and/or which represents the intended meaning of the user.
1149-
extension:
1150-
type: array
1151-
items:
1152-
$ref: "#/components/schemas/Extension"
1153-
description: Additional content defined by implementations.
11541156
Coding:
11551157
type: object
11561158
properties:
@@ -1187,6 +1189,78 @@ components:
11871189
type: string
11881190
pattern: \S*
11891191
description: The reference details for the link.
1192+
ContentStabilityExtension:
1193+
allOf:
1194+
- $ref: "#/components/schemas/Extension"
1195+
- type: object
1196+
properties:
1197+
url:
1198+
type: string
1199+
enum:
1200+
- "https://fhir.nhs.uk/England/StructureDefinition/Extension-England-ContentStability"
1201+
valueCodeableConcept:
1202+
$ref: "#/components/schemas/ContentStabilityExtensionValueCodeableConcept"
1203+
required:
1204+
- url
1205+
- valueCodeableConcept
1206+
ContentStabilityExtensionValueCodeableConcept:
1207+
allOf:
1208+
- $ref: "#/components/schemas/CodeableConcept"
1209+
- type: object
1210+
properties:
1211+
coding:
1212+
type: array
1213+
items:
1214+
$ref: "#/components/schemas/ContentStabilityExtensionCoding"
1215+
minItems: 1
1216+
maxItems: 1
1217+
required:
1218+
- coding
1219+
ContentStabilityExtensionCoding:
1220+
allOf:
1221+
- $ref: "#/components/schemas/Coding"
1222+
- type: object
1223+
properties:
1224+
system:
1225+
type: string
1226+
enum:
1227+
- "https://fhir.nhs.uk/England/CodeSystem/England-NRLContentStability"
1228+
code:
1229+
type: string
1230+
enum: ["static", "dynamic"]
1231+
display:
1232+
type: string
1233+
enum: ["Static", "Dynamic"]
1234+
required:
1235+
- system
1236+
- code
1237+
- display
1238+
NRLFormatCode:
1239+
allOf:
1240+
- $ref: "#/components/schemas/Coding"
1241+
- type: object
1242+
properties:
1243+
system:
1244+
type: string
1245+
enum:
1246+
- "https://fhir.nhs.uk/England/CodeSystem/England-NRLFormatCode"
1247+
description: The system URL for the NRLF Format Code.
1248+
code:
1249+
type: string
1250+
enum:
1251+
- "urn:nhs-ic:record-contact"
1252+
- "urn:nhs-ic:unstructured"
1253+
description: The code representing the format of the document.
1254+
display:
1255+
type: string
1256+
enum:
1257+
- "Contact details (HTTP Unsecured)"
1258+
- "Unstructured Document"
1259+
description: The display text for the code.
1260+
required:
1261+
- system
1262+
- code
1263+
- display
11901264
Identifier:
11911265
type: object
11921266
properties:
@@ -1519,8 +1593,8 @@ components:
15191593
SNOMED_CODES_LLOYD_GEORGE_RECORD_FOLDER:
15201594
summary: Lloyd George record folder
15211595
value: http://snomed.info/sct|16521000000101
1522-
SNOMED_CODES_ADVANCED_CARE_PLAN:
1523-
summary: Advanced care plan
1596+
SNOMED_CODES_ADVANCE_CARE_PLAN:
1597+
summary: Advance care plan
15241598
value: http://snomed.info/sct|736366004
15251599
SNOMED_CODES_TREATMENT_ESCALATION_PLAN:
15261600
summary: Treatment escalation plan

0 commit comments

Comments
 (0)