diff --git a/lambdas/handlers/manage_nrl_pointer_handler.py b/lambdas/handlers/manage_nrl_pointer_handler.py index fb50e35be..a86c76819 100644 --- a/lambdas/handlers/manage_nrl_pointer_handler.py +++ b/lambdas/handlers/manage_nrl_pointer_handler.py @@ -1,7 +1,7 @@ import json from enums.nrl_sqs_upload import NrlActionTypes -from models.fhir.R4.nrl_fhir_document_reference import FhirDocumentReference +from models.fhir.R4.nrl_fhir_document_reference import DocumentReferenceInfo from models.nrl_sqs_message import NrlSqsMessage from services.base.nhs_oauth_service import NhsOauthService from services.base.ssm_service import SSMService @@ -49,11 +49,13 @@ def lambda_handler(event, context): ) match nrl_message.action: case NrlActionTypes.CREATE: - document = FhirDocumentReference( + document = DocumentReferenceInfo( **nrl_verified_message, custodian=nrl_api_service.end_user_ods_code, - ).document_ref_dict() - nrl_api_service.create_new_pointer(json.dumps(document)) + ).create_fhir_document_reference_object() + nrl_api_service.create_new_pointer( + document.model_dump_json(exclude_none=True) + ) case NrlActionTypes.DELETE: nrl_api_service.delete_pointer( nrl_message.nhs_number, nrl_message.snomed_code_doc_type diff --git a/lambdas/models/fhir/R4/nrl_fhir_document_reference.py b/lambdas/models/fhir/R4/nrl_fhir_document_reference.py index e1c473a89..4b58ada20 100644 --- a/lambdas/models/fhir/R4/nrl_fhir_document_reference.py +++ b/lambdas/models/fhir/R4/nrl_fhir_document_reference.py @@ -8,89 +8,10 @@ Period, Reference, ) -from models.nrl_sqs_message import NrlAttachment from pydantic import BaseModel, ConfigDict from pydantic.alias_generators import to_camel -class FhirDocumentReference(BaseModel): - model_config = ConfigDict(alias_generator=to_camel) - nhs_number: str - custodian: str - snomed_code_doc_type: SnomedCode = SnomedCodes.LLOYD_GEORGE.value - snomed_code_category: SnomedCode = SnomedCodes.CARE_PLAN.value - snomed_code_practice_setting: SnomedCode = ( - SnomedCodes.GENERAL_MEDICAL_PRACTICE.value - ) - attachment: Optional[NrlAttachment] = NrlAttachment() - - def document_ref_dict(self): - fhir_base_url = "https://fhir.nhs.uk/Id" - snomed_url = "http://snomed.info/sct" - - dooc = DocumentReference( - subject={ - "identifier": { - "system": fhir_base_url + "/nhs-number", - "value": self.nhs_number, - } - }, - custodian={ - "identifier": { - "system": fhir_base_url + "/ods-organization-code", - "value": self.custodian, - }, - }, - type={ - "coding": [ - { - "system": snomed_url, - "code": self.snomed_code_doc_type.code, - "display": self.snomed_code_doc_type.display_name, - } - ] - }, - content=[ - { - "attachment": self.attachment.model_dump( - by_alias=True, exclude_none=True - ), - } - ], - category=[ - { - "coding": [ - { - "system": snomed_url, - "code": self.snomed_code_category.code, - "display": self.snomed_code_category.display_name, - } - ] - } - ], - author=[ - { - "identifier": { - "system": fhir_base_url + "/ods-organization-code", - "value": self.custodian, - } - } - ], - context={ - "practiceSetting": { - "coding": [ - { - "system": snomed_url, - "code": self.snomed_code_practice_setting.code, - "display": self.snomed_code_practice_setting.display_name, - } - ] - } - }, - ) - return dooc.model_dump(exclude_none=True) - - class NRLFormatCode(Coding): system: Literal["https://fhir.nhs.uk/England/CodeSystem/England-NRLFormatCode"] = ( "https://fhir.nhs.uk/England/CodeSystem/England-NRLFormatCode" @@ -162,3 +83,75 @@ class DocumentReference(BaseModel): custodian: Optional[Reference] = None content: List[DocumentReferenceContent] context: Optional[DocumentReferenceContext] = None + + +class DocumentReferenceInfo(BaseModel): + model_config = ConfigDict(alias_generator=to_camel) + nhs_number: str + custodian: str + snomed_code_doc_type: SnomedCode = SnomedCodes.LLOYD_GEORGE.value + snomed_code_category: SnomedCode = SnomedCodes.CARE_PLAN.value + snomed_code_practice_setting: SnomedCode = ( + SnomedCodes.GENERAL_MEDICAL_PRACTICE.value + ) + attachment: Optional[Attachment] = Attachment() + + def create_fhir_document_reference_object(self): + fhir_base_url = "https://fhir.nhs.uk/Id" + snomed_url = "http://snomed.info/sct" + + fhir_document_ref = DocumentReference( + subject={ + "identifier": { + "system": fhir_base_url + "/nhs-number", + "value": self.nhs_number, + } + }, + custodian={ + "identifier": { + "system": fhir_base_url + "/ods-organization-code", + "value": self.custodian, + }, + }, + type={ + "coding": [ + { + "system": snomed_url, + "code": self.snomed_code_doc_type.code, + "display": self.snomed_code_doc_type.display_name, + } + ] + }, + content=[{"attachment": self.attachment}], + category=[ + { + "coding": [ + { + "system": snomed_url, + "code": self.snomed_code_category.code, + "display": self.snomed_code_category.display_name, + } + ] + } + ], + author=[ + { + "identifier": { + "system": fhir_base_url + "/ods-organization-code", + "value": self.custodian, + } + } + ], + context={ + "practiceSetting": { + "coding": [ + { + "system": snomed_url, + "code": self.snomed_code_practice_setting.code, + "display": self.snomed_code_practice_setting.display_name, + } + ] + } + }, + ) + return fhir_document_ref diff --git a/lambdas/models/nrl_sqs_message.py b/lambdas/models/nrl_sqs_message.py index 508543aa8..2c3d31f72 100644 --- a/lambdas/models/nrl_sqs_message.py +++ b/lambdas/models/nrl_sqs_message.py @@ -1,24 +1,11 @@ from typing import Optional from enums.snomed_codes import SnomedCode, SnomedCodes +from models.fhir.R4.nrl_fhir_document_reference import Attachment from pydantic import AliasGenerator, BaseModel, ConfigDict from pydantic.alias_generators import to_camel -class NrlAttachment(BaseModel): - model_config = ConfigDict( - alias_generator=AliasGenerator(serialization_alias=to_camel) - ) - - content_type: str = "application/pdf" - language: str = "en-UK" - url: str = "" - size: int = 0 - hash: str = "" - title: str = "" - creation: str = "" - - class NrlSqsMessage(BaseModel): model_config = ConfigDict( alias_generator=AliasGenerator(serialization_alias=to_camel), @@ -32,5 +19,5 @@ class NrlSqsMessage(BaseModel): SnomedCodes.GENERAL_MEDICAL_PRACTICE.value ) description: str = "" - attachment: Optional[NrlAttachment] = None + attachment: Optional[Attachment] = None action: str diff --git a/lambdas/services/bulk_upload_service.py b/lambdas/services/bulk_upload_service.py index 72cd35499..3f935e15e 100644 --- a/lambdas/services/bulk_upload_service.py +++ b/lambdas/services/bulk_upload_service.py @@ -8,8 +8,9 @@ from enums.patient_ods_inactive_status import PatientOdsInactiveStatus from enums.upload_status import UploadStatus from enums.virus_scan_result import VirusScanResult +from models.fhir.R4.nrl_fhir_document_reference import Attachment from models.nhs_document_reference import NHSDocumentReference -from models.nrl_sqs_message import NrlAttachment, NrlSqsMessage +from models.nrl_sqs_message import NrlSqsMessage from models.staging_metadata import MetadataFile, StagingMetadata from repositories.bulk_upload.bulk_upload_dynamo_repository import ( BulkUploadDynamoRepository, @@ -279,7 +280,7 @@ def handle_sqs_message(self, message: dict): + "/DocumentReference/" + last_document_processed.id ) - doc_details = NrlAttachment( + doc_details = Attachment( url=document_api_endpoint, ) nrl_sqs_message = NrlSqsMessage( diff --git a/lambdas/services/nrl_get_document_reference_service.py b/lambdas/services/nrl_get_document_reference_service.py index d0ffa9d5a..285a8aea2 100644 --- a/lambdas/services/nrl_get_document_reference_service.py +++ b/lambdas/services/nrl_get_document_reference_service.py @@ -4,8 +4,7 @@ from enums.lambda_error import LambdaError from enums.patient_ods_inactive_status import PatientOdsInactiveStatus from models.document_reference import DocumentReference -from models.fhir.R4.nrl_fhir_document_reference import FhirDocumentReference -from models.nrl_sqs_message import NrlAttachment +from models.fhir.R4.nrl_fhir_document_reference import Attachment, DocumentReferenceInfo from requests.exceptions import HTTPError from services.base.s3_service import S3Service from services.base.ssm_service import SSMService @@ -50,16 +49,20 @@ def handle_get_document_reference_request(self, document_id, bearer_token): def create_document_reference_fhir_response( self, document_reference: DocumentReference, presign_url: str ) -> dict: - document_details = NrlAttachment( + document_details = Attachment( url=presign_url, title=document_reference.file_name, creation=document_reference.created, ) - fhir_document_reference = FhirDocumentReference( - nhsNumber=document_reference.nhs_number, - custodian=document_reference.current_gp_ods, - attachment=document_details, - ).document_ref_dict() + fhir_document_reference = ( + DocumentReferenceInfo( + nhsNumber=document_reference.nhs_number, + custodian=document_reference.current_gp_ods, + attachment=document_details, + ) + .create_fhir_document_reference_object() + .model_dump(exclude_none=True) + ) return fhir_document_reference def is_user_allowed_to_see_file(self, user_details, document_reference): diff --git a/lambdas/tests/unit/handlers/test_manage_nrl_pointer_handler.py b/lambdas/tests/unit/handlers/test_manage_nrl_pointer_handler.py index b7a91c5c0..924e81d44 100644 --- a/lambdas/tests/unit/handlers/test_manage_nrl_pointer_handler.py +++ b/lambdas/tests/unit/handlers/test_manage_nrl_pointer_handler.py @@ -1,7 +1,8 @@ import pytest from enums.snomed_codes import SnomedCodes from handlers.manage_nrl_pointer_handler import lambda_handler -from models.nrl_sqs_message import NrlAttachment, NrlSqsMessage +from models.fhir.R4.nrl_fhir_document_reference import Attachment +from models.nrl_sqs_message import NrlSqsMessage from utils.exceptions import NrlApiException @@ -14,7 +15,7 @@ def mock_service(mocker): def build_test_sqs_message(action="create"): - doc_details = NrlAttachment( + doc_details = Attachment( url="https://example.org/my-doc.pdf", ) sqs_message = NrlSqsMessage( diff --git a/lambdas/tests/unit/services/test_bulk_upload_service.py b/lambdas/tests/unit/services/test_bulk_upload_service.py index b4be3f6ab..f93b6bfc9 100644 --- a/lambdas/tests/unit/services/test_bulk_upload_service.py +++ b/lambdas/tests/unit/services/test_bulk_upload_service.py @@ -8,7 +8,8 @@ from enums.upload_status import UploadStatus from enums.virus_scan_result import SCAN_RESULT_TAG_KEY, VirusScanResult from freezegun import freeze_time -from models.nrl_sqs_message import NrlAttachment, NrlSqsMessage +from models.fhir.R4.nrl_fhir_document_reference import Attachment +from models.nrl_sqs_message import NrlSqsMessage from models.pds_models import Patient from repositories.bulk_upload.bulk_upload_s3_repository import BulkUploadS3Repository from repositories.bulk_upload.bulk_upload_sqs_repository import BulkUploadSqsRepository @@ -238,7 +239,7 @@ def test_handle_sqs_message_happy_path_single_file( mock_ods_validation, ): TEST_STAGING_METADATA.retries = 0 - mock_nrl_attachment = NrlAttachment( + mock_nrl_attachment = Attachment( url=f"/DocumentReference/{TEST_DOCUMENT_REFERENCE.id}", ) mock_nrl_message = NrlSqsMessage( diff --git a/lambdas/tests/unit/services/test_nrl_get_document_reference_service.py b/lambdas/tests/unit/services/test_nrl_get_document_reference_service.py index b8d37a620..38c6a6175 100644 --- a/lambdas/tests/unit/services/test_nrl_get_document_reference_service.py +++ b/lambdas/tests/unit/services/test_nrl_get_document_reference_service.py @@ -68,15 +68,15 @@ def mock_fetch_user_info(patched_service, mocker): @pytest.mark.parametrize( - "input, expected", + "role_code, expected", [ ("S8001:G8005:R8000", "R8000"), ("S8001:G8005:R8015", "R8015"), ("S8001:G8005:R8008", "R8008"), ], ) -def test_process_role_code_returns_correct_role(patched_service, input, expected): - assert patched_service.process_role_code(input) == expected +def test_process_role_code_returns_correct_role(patched_service, role_code, expected): + assert patched_service.process_role_code(role_code) == expected def test_get_user_roles_and_ods_codes(patched_service):