All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog,
-
Updated skeleton processing to recognise
RCMR_IN030000UK07as a valid full-message skeleton type in addition toRCMR_IN030000UK06, ensuring the service correctly replaces the inbound payload when a UK07 skeleton is received. -
Add Spring retry to MHS queue consumer to facilitate a more reasonable retry delay.
- Fixed spelling error in measurement unit "milliliter".
- Add thread-safe synchronisation when merging and uncompressing a large EHR Extract bundle to avoid a race condition occurring where multiple threads may attempt to merge and uncompress the same EHR Extract bundle at the same time. This could result in a corrupted EHR Extract bundle.
- Added fallback to use the
EhrCompositionauthor whenCondition.asserterwhen theEhrCompoositiondoes not have aparticipant2set.
- Fixed handling of multiple
<given>name fields in practitioner XML to JSON mapping to now correctly map multiple<given>names.
- Updated error handling when when processing skeleton payloads to throw a meaningful IllegalArgumentException when a payload node cannot be matched to a skeleton document ID, replacing an uninformative NullPointerException.
- Updated Skeleton processing service now removes any leading
_before matching the skeleton document ID to the payload node.
- Add new accepted values for Medication Statement Prescribing Agency extension to handle differing types of prescribing agency (e.g. NHS prescription, OTC sale).
- Add feature to handle differing EMIS Prescription Types.
- Add startup validation for required environment variables.
- Updated the length of varchar columns in
patient_attachment_logtable to 1024 characters.
- Fixed the
EHRExtractinteraction identifier used by timeout handling fromRCMR_IN030000UK06toRCMR_IN030000UK07.
- Blood pressure observations are retrieved only once to prevent duplicate entries.
- Changed the default output to
'Defaulted to Minor'when the adaptor receives GP2GP xml and finds a problem that is either coded as ‘unspecified significance’ or no severity qualifier is present.
- If a
ehrComposition(which includes aNarrativeStatementwith a reference to a document ) record includes aconfidentialityCodethen themeta.securityfield of the corresponding translated FHIRDocumentReferenceresource will now be appropriately populated.
- Fixed a bug where redactions were being removed from some Observations after being added.
- Added migration timeout override option as environment variable
MIGRATION_TIMEOUT_OVERRIDE. Setting this value totruewill ensure that the migration will time out after a period of 48 hours has passed.
- [Breaking Change - GP Connect 1.6.2] When an
agentPersonis provided with either an empty or missing namenameelement, this would previously result in aresource[Practitioner]withname[0].familyset toUnknown. This will no longer be set, but insteadresource[Practitioner].name[0].textwill now be populated withUnknown. - [Breaking Change - GP Connect 1.6.2] When an
agentPersonis provided with either an empty or missingagentPerson / name / familythen this will result in aresource[practitioner].name[0]withoutfamily,prefixorgivenpopulated. The fieldresource[practitioner].name[0].textwill instead now be populated with these values.
- Adjusted MedicationRequestPlan date to use ehrSupplyPrescribe for acute re-issues, maintaining ehrSupplyAuthorise for originals.
- Resolved an issue where the receiving adapter did not add a NOPAT entry into Condition when an observationStatement was referenced from linkSet.
- the relatedProblemHeader extension is populated in the GP Connect Topic List when mapping an ehrComposition with a flat structure
- In the event of patient migration request which has failed, the adaptor would previously reject an XML Electronic Health Record which had been resent to it. Now the adaptor will instead accept the resent EHR and perform the translation to FHIR.
- When sending a negative acknowledgement to the sending system in the event of a failure, include the textual description of the reason, e.g. "EHR Extract message not well-formed or not able to be processed". This behaviour while not required by the spec, has been implemented by other GP2GP systems, and is expected to be provided by one implementation.
- When a
LinkSetwhich is a linkage between aReferralRequestand one or moreDocumentReferencesis mapped then aConditionwill no longer be mapped for thisLinkset. Instead, thestatementRefs will be added to thesupportingInfowhen mapping theReferralRequestasDocumentReferences
- When provided an
agentPersonwithout anameelement, the adaptor will no longer throw an exception, but will instead map thePractitionerwith afamilyNameof"unknown".
- Remove 20 MB data processing limit to enable the Adaptor to handle larger pieces of data.
- Documented how the Adaptor behaves when dependent services are unavailable.
- Expanded the functionality added in version 2.1.0 to deduplicate SystmOne Problems.
Handle the case where a duplicate, empty
ObservationStatementis provided by SystmOne and ignore it from the generated FHIR output.
- In the event that an inbound MHS message cannot be processed and needs to be sent to the dead letter queue, the adaptor will now emit a log message at INFO level as opposed to DEBUG level.
- Fixed a bug when mapping a post-dated acute prescription with multiple issues, whereby the adaptor was generating
a
MedicationRequest [Plan]which was being referenced by multipleMedicationRequest [Order]. Now each acute prescription issue gets its ownMedicationRequest [Plan], with thepriorPrescriptionfield linking the plans together.
Note
Upgrade information This release includes an update to the SNOMED database Users will need to perform an update of their SNOMED database. This will need to be performed first, followed by deploying the updated version of the translator image.
- If a
medicationStatementormedicationRequestrecord includes aconfidentialityCode, themeta.securityfield of the corresponding FHIR resource will now be appropriately populated. - If a
referralRequestrecord includes aconfidentialityCode, themeta.securityfield of the corresponding FHIR resource will now be appropriately populated. - If a
procedureRequestrecord includes aconfidentialityCode, themeta.securityfield of the corresponding FHIR resource will now be appropriately populated. - If a
linksetrecord includes aconfidentialityCode, themeta.securityfield of the corresponding FHIR resource will now be appropriately populated. - If a
documentReferencerecord includes aconfidentialityCode, themeta.securityfield of the corresponding FHIR resource will now be appropriately populated. - If an
immunizationrecord includes aconfidentialityCode, themeta.securityfield of the corresponding FHIR resource will now be appropriately populated. - If a
bloodPressurerecord includes aconfidentialityCode, themeta.securityfield of the corresponding FHIR resource will now be appropriately populated. - If a
Observation,Specimen,DiagnosticReportrecord includes aconfidentialityCode, themeta.securityfield of the corresponding FHIR resource will now be appropriately populated.
- Resolved issue where the SNOMED import script would reject a password containing a '%' character.
- Fixed some Test Results being given a duplicated
Observation.categoryentries forLaboratory. - Fixed issue where the GPC Facade was not returning an error when an invalid
ConversationIdheader was provided. The Facade will now return a 400 instead of a 500 HTTP response. - Filing Comments were creating with incorrect
effectiveDateTime, this is now set from theehrComposition /author / timeinstead. - Filing Comments were creating with an incorrect
performer, this now references theehrComposition / author / agentRefinstead. - Addressed a bug where immunizations were incorrectly mapped to observations when the Snomed CT code being sent was a Description ID. The adaptor previously only checked against known vaccination Concept IDs.
- If a
ehrCompositionrecord includes aconfidentialityCode, themeta.securityfield of the correspondingEncounterFHIR resource will now be appropriately populated. - Add support for an Organization being referenced within the
ReferralRequest.recipientfield.
-
The AllergyIntoleranceMapper has been enhanced to support the redaction fix. If an Allergy Intolerance record includes a
confidentialityCode, themeta.securityfield of the corresponding FHIR resource will now be appropriately populated. -
When the SNOMED DB ingest script has not completed successfully, The GP2GP Translator Service will now exit and throw a RuntimeException with the following message:
FATAL: Expected Immunization codes not found in snomedct.immunization_codes view. SNOMED CT Database not set up correctly. Please update / reload the SNOMED DB.
DiagnosticReport.results now preserve original ordering provided in the HL7.
- The adaptor no longer checks incoming attachment content types aginst the
SUPPORTED_FILE_TYPESlist. This functionality can be implemented outside the adaptor if still desired.
- The
/$gpc.ackendpoint is now case insensitive and supports uppercase and lowercase values for theconversationIdheader values.
- Retry mechanism has been added for when the MHS outbound returns a 500 server response when acknowledging COPC messages.
- Mapping of
issuedfor Test Group Headers, Test Results, Filing Comment and has been updated to use time value from the GP2GPObservationStatement / availabilityTimefield and useEhrComposition / author / timeif not available.
- Cron time schedule has been changed from 6h to 2h so that the timeouts can be identified earlier
- When mapping a
MedicationRequest (PLAN), if the text in the original text is duplicated by a pertinent information text, then the original text is disregarded to avoid the unnecessary duplication.
-
SystmOne send a problem over GP2GP as two
ObservationStatements, where one is truncated and one isn't. This truncation can be identified where anObservationStatementis part of a problem, and the note ends in '...'. The adaptor will now identify this duplication, and merge the two into oneObservationStatement.Example
Original XML:<ehrComposition xmlns="urn:hl7-org:v3" classCode="COMPOSITION" moodCode="EVN"> <id root="e9105749-5aef-400d-8ad4-649ff03ac879"/> <code code="25671000000102" codeSystem="2.16.840.1.113883.2.1.3.2.4.15" displayName="Surgery Consultation Note"/> <statusCode code="COMPLETE"/> ... <component typeCode="COMP"> <ObservationStatement classCode="OBS" moodCode="EVN"> <id root="ba4edfcd-142e-4090-8a81-9ca2790849a8"/> <code code="14J.." codeSystem="2.16.840.1.113883.2.1.3.2.4.14" displayName="H/O: injury"> <translation code="161586000" codeSystem="2.16.840.1.113883.2.1.3.2.4.15" displayName="H/O: injury"/> <translation code="14J..00" codeSystem="2.16.840.1.113883.2.1.6.2" displayName="H/O: injury"/> </code> <statusCode code="COMPLETE"/> <effectiveTime> <low value="20001004"/> <high value="19000101000000"/> </effectiveTime> <availabilityTime value="20001004"/> <pertinentInformation typeCode="PERT"> <sequenceNumber value="+1"/> <pertinentAnnotation classCode="OBS" moodCode="EVN"> <text>Problem severity: Minor H/O: injury to little finger left hand poss gla...</text> </pertinentAnnotation> </pertinentInformation> </ObservationStatement> </component> <component typeCode="COMP"> <LinkSet classCode="OBS" moodCode="EVN"> <id root="7f384915-a2f9-44df-b407-e9c339707297"/> <code code="394775005" codeSystem="2.16.840.1.113883.2.1.3.2.4.15" displayName="Inactive Problem"/> <statusCode code="COMPLETE"/> <effectiveTime> <low value="20001004"/> <high value="19000101000000"/> </effectiveTime> <availabilityTime value="20001004"/> <conditionNamed inversionInd="true" typeCode="NAME"> <namedStatementRef classCode="OBS" moodCode="EVN"> <id root="ba4edfcd-142e-4090-8a81-9ca2790849a8"/> </namedStatementRef> </conditionNamed> </LinkSet> </component> <component typeCode="COMP"> <ObservationStatement classCode="OBS" moodCode="EVN"> <id root="f04d2995-c6f8-4cf0-8e07-5362a950e2a5"/> <code code="14J.." codeSystem="2.16.840.1.113883.2.1.3.2.4.14" displayName="H/O: injury"> <translation code="161586000" codeSystem="2.16.840.1.113883.2.1.3.2.4.15" displayName="H/O: injury"/> <translation code="14J..00" codeSystem="2.16.840.1.113883.2.1.6.2" displayName="H/O: injury"/> </code> <statusCode code="COMPLETE"/> <effectiveTime> <center nullFlavor="NI"/> </effectiveTime> <availabilityTime value="20001004"/> <pertinentInformation typeCode="PERT"> <sequenceNumber value="+1"/> <pertinentAnnotation classCode="OBS" moodCode="EVN"> <text>(New Episode). H/O: injury to little finger left hand poss glass in wound therefore refered to A+E</text> </pertinentAnnotation> </pertinentInformation> </ObservationStatement> </component> </ehrComposition>Gets merged into:<ehrComposition xmlns="urn:hl7-org:v3" classCode="COMPOSITION" moodCode="EVN"> <id root="e9105749-5aef-400d-8ad4-649ff03ac879"/> <code code="25671000000102" codeSystem="2.16.840.1.113883.2.1.3.2.4.15" displayName="Surgery Consultation Note"/> <statusCode code="COMPLETE"/> ... <component typeCode="COMP"> <ObservationStatement classCode="OBS" moodCode="EVN"> <id root="ba4edfcd-142e-4090-8a81-9ca2790849a8"/> <code code="14J.." codeSystem="2.16.840.1.113883.2.1.3.2.4.14" displayName="H/O: injury"> <translation code="161586000" codeSystem="2.16.840.1.113883.2.1.3.2.4.15" displayName="H/O: injury"/> <translation code="14J..00" codeSystem="2.16.840.1.113883.2.1.6.2" displayName="H/O: injury"/> </code> <statusCode code="COMPLETE"/> <effectiveTime> <low value="20001004"/> <high value="19000101000000"/> </effectiveTime> <availabilityTime value="20001004"/> <pertinentInformation typeCode="PERT"> <sequenceNumber value="+1"/> <pertinentAnnotation classCode="OBS" moodCode="EVN"> <text>Problem severity: Minor (New Episode). H/O: injury to little finger left hand poss glass in wound therefore refered to A+E</text> </pertinentAnnotation> </pertinentInformation> </ObservationStatement> </component> <component typeCode="COMP"> <LinkSet classCode="OBS" moodCode="EVN"> <id root="7f384915-a2f9-44df-b407-e9c339707297"/> <code code="394775005" codeSystem="2.16.840.1.113883.2.1.3.2.4.15" displayName="Inactive Problem"/> <statusCode code="COMPLETE"/> <effectiveTime> <low value="20001004"/> <high value="19000101000000"/> </effectiveTime> <availabilityTime value="20001004"/> <conditionNamed inversionInd="true" typeCode="NAME"> <namedStatementRef classCode="OBS" moodCode="EVN"> <id root="ba4edfcd-142e-4090-8a81-9ca2790849a8"/> </namedStatementRef> </conditionNamed> </LinkSet> </component> </ehrComposition> -
When a
CommentType: USER COMMENTNarrativeStatementis located within theBATTERYof aFiled Report, the adaptor now generates a new filing commentObservationand references this in the result property of the parentDiagnosticReport. This change makes the adaptor more closely resemble the GP Connect specification for DiagnosticReport and filing comments. The generatedObservationfiling comment will have thestatusofunknown.
- Breaking Change Identifier values and code systems where an OID is provided
(such as
2.16.840.1.113883.2.1.6.9) will now be provided as a URN (i.e.urn:oid:2.16.840.1.113883.2.1.6.9), as per GP Connect specification.
- The source of date for List (Consultation) is now ehrComposition author time otherwise from
the following fields in order of precedence:
- ehrComposition availibiltyTime
- ehrComposition effectiveTime - center
- EhrComposition effectiveTime - high
- EhrComposition effectiveTime - low
Condition.onsetDateTimeis now set to NULL when low or center entries of effectiveTime arenullFlavor="UNK".
-
Removed the
EhrExtract / AvailabilityTimefield as a fallback value from:Condition.assertedDateList.dateDiagnosticReport.issuedObservation.issuedDate
-
Replaced the
EhrExtract / AvailabilityTimefield as a fallback value withEhrComposition / author / time[@value]for:AllergyIntolerance.assertedDateMedicationRequest.authoredOn
- Plan Statements (Recalls) were previously mapped with a fixed value of
activefor the Status field. The adaptor will now interrogate the text field to see if a status has been provided, otherwise defaulting tounknown.
- Added Materialised View in the SnomedCT database to be used when querying for preferred terms.
Note
Upgrade information This release includes an update to the SNOMED database Users will need to perform an update of their SNOMED database. This will need to be performed first, followed by deploying the updated version of the translator image.
- Added Episodicity information to
commentproperty of Observations.
- Fixed malformed role coding defect introduced in version 1.4.1
- Assigning a role to a practitioner who records vaccinations
- Fixed an issue where
Observation Test GrouporObservation Test Resultswere incorrectly creating a relationship toFiling Commentsusing thehas-memberrelationship ProcedureRequestMapper.authoredOnis no longer populated withEhrExtract / availabilityTimeas a fallback, but does useEhrComposition / author / timeas a fallback instead now.
- REST buffer size has been set to 150Mb
- Fixed issue where mapping failed due to a Referral Request Priority not being found.
- Codings are now provided (code, display and system) in
PractionionerRole.codeandOrganization.typefields, where only thetextattribute was provided previously. - Fixed a bug which could lead to medication resource not being mapped if a failure had occurred when processing the previous EhrExtract during the medication mapping stage
- In the event of a GP2GP failure, the raw error code is now available in the
/Patient/$gpc.migratestructuredrecordresponse section with code system2.16.840.1.113883.2.1.3.2.4.17.101.
- Removed surplus references to Medication Statements from the Topic and Category entry arrays. The GP Connect documentation states Medications should be referenced using the Medication Request resource, which is already done.
- Updated postman collection to include attachment tests.
- Swapped the mixed-up population of 'author' and 'practitioner' fields in AllergyIntolerance.
- A SystmOne attachment split into multiple chunks can arrive with the same filename "Untitled". Previously each fragment would be stored using the filename provided, which in the case of SystmOne caused chunks to overwrite each other. The adaptor now generates a UUID which is prepended to the filename of a provided chunk to ensure uniqueness.
- Populate
identifierfield forPractitionerresources using the General Practitioner (GMP) number if available.
- Prevent
NarrativeStatement / textsat within a blood pressureCompoundStatementfrom being mapped into separate "Comment note" Observation resources. This information is already populated within the blood pressureObservation.commentfield, so creating a separate resource was duplicating this info.
- Changed
ReferralRequestmapping to useASAPinstead of theStatvalue.
- Updated the way immunization codes are loaded to build these from the relationships reference set in the SNOMED CT release rather than a static set of values. The previous static list of values was incomplete and included invalid codes. More information about how this improved functionality works can be found in the SNOMED database documentation.
Note
Upgrade information This release includes a database migration. This database migration will need to be performed first, followed by deploying the updated version of the facade and translator images. Finally users will need to perform an update of their SNOMED database.
This release backported the following fix to the v1.0 release.
- A SystmOne attachment split into multiple chunks can arrive with the same filename "Untitled". Previously each fragment would be stored using the filename provided, which in the case of SystmOne caused chunks to overwrite each other. The adaptor now generates a UUID which is prepended to the filename of a provided chunk to ensure uniqueness.
- Added functionality to include episodicity qualifiers when mapping allergy intolerances.
- Preserve the ordering of code / translation elements when mapping Codeable Concepts.
- Fix invalid state transition bug which caused the adaptor to move from a failed state to an in-progress state when a positive acknowledgement was received.
- Add additional error handling for exceptions raised when processing PSS queue, and MHS queue messages.
- Fix bug in some SQL statements which caused excessively large amounts of data to be returned, sometimes resulting in a PostgresSQL Out of Memory error.
- Fixed issue with some
ObservationStatementcoded as blood pressure readings not being output into Bundle. - Fixed issue with
AllergyIntolerancerecorder and asserter fields mapping.
- Documented database requirements in OPERATING.md
- New docker image published as nhsdev/nia-ps-db-migration
- Querying SDS service using an addtional endpoint to fetch ODS code
- Fix issue where continue message was not accepted by EMIS
- Fixed issue where EMIS
cidreferences caused large message merging to fail - Fix issue where attachments were given the incorrect object storage URL
- Fix issue where attachments were not de-compressed
- Enable logging of migration status updates when PS_LOGGING_LEVEL is set to DEBUG
- Fix acknowledgement message as it was not accepted by system one
- Fix SDS failing as part of GP2GP transfer process
- Add details about object storage to operating documentation.
- Enable AWS Instance Roles to be used for connecting to S3
- Fix issue where attachments with filenames containing special characters causes the transfer to fail.
- Fix issue where some resource types do not contain a degraded code when a SNOMED code has not been provided.
- Fix issue where unnecessary length checks on inline attachments could cause a transfer to fail.
- Change the codeable concept mapping to map Egton Codes found in
codeelements. - Change the codeable concept mapping to map Read Codes (READV2, CTV3) found in
codeelements. - Change the codeable concept mapping to map unknown code systems found in
codeelements.
- Fix issue where Inbound Adaptor rejects an EHR Extract from EMIS containing inline attachments where the description contains only the filename.
- Fix issue where Allergy Intolerances are referenced incorrectly when they are referenced from a list.
- Fix issue where a
Conditionis not correctly mapping thecodeelement in all instances.