-
Notifications
You must be signed in to change notification settings - Fork 40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[16143] Implement Convert Step Updates #16710
base: main
Are you sure you want to change the base?
Conversation
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.OpenSSF Scorecard
Scanned Manifest Files |
Integration Test Results 59 files 59 suites 38m 59s ⏱️ Results for commit 270faef. ♻️ This comment has been updated with latest results. |
* | ||
* @return true if has a MesssageHeader that contains an R01 or ORU_R01, otherwise false. | ||
*/ | ||
fun Bundle.isElr(): Boolean { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RS currently receives test orders and results. Instead of isElr
, perhaps a method like getMessageType
that returns an enum value like LAB_TEST_RESULT
or LAB_TEST_ORDER
or UNKOWN
would be more reusable? Then, I would say let's stamp the message if we get back either LAB_TEST_RESULT
or UNKOWN
just to be safe?
Implementing detection for LAB_TEST_ORDER
is optional at this point as there is no need to distinguish this as of yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added some code for this with only LAB_RESULT or UNKNOWN as options. Future features will need to add additional values to the enum.
fun Bundle.isElr(): Boolean { | ||
var isElr = false | ||
if (this.type == Bundle.BundleType.MESSAGE && this.entry.isNotEmpty()) { | ||
// By rule, the first entry must be a MessageHeader |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you link to documentation that says this? This makes me uneasy. See fun Bundle.getDiagnosticReportNoObservations(): List<Base> {
below to see how we can utilize FHIRPath here for a better solution imo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Look at the documentation around "entry" for the Bundle resource
This repeating element order: For bundles of type 'document' and 'message', the first resource is special (must be Composition or MessageHeader respectively). For all bundles, the meaning of the order of entries depends on the bundle type.
@@ -323,6 +326,10 @@ class FHIRConverter( | |||
// We know from the null check above that this cannot be null | |||
val bundle = processedItem.bundle!! | |||
transformer?.process(bundle) | |||
logger.info( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some suggestions to make this log message more detailed:
- Do this log after you make the child report (line 335) so that you can set
childReportId
to an actual value - (optional) You can access the
processedItem
var here, so add the tracking id of the item to this log message:processedItem.getTrackingId()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. Changes made.
@@ -508,24 +514,32 @@ class FHIRConverter( | |||
} | |||
// 'stamp' observations with their condition code | |||
if (item.bundle != null) { | |||
val isElr = if (item.bundle!!.getRSMessageType() == RSMessageType.LAB_RESULT) true else false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be simplified to: item.bundle!!.getRSMessageType() == RSMessageType.LAB_RESULT
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup.
UnmappableConditionMessage( | ||
it.failures.map { it.code }, | ||
it.source | ||
// Only do this if it is an ELR item. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comment not needed, the code is clear enough. Try to use comments to explain the "why" not the "what". In this case, no comment is needed imo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cleaned it up.
} | ||
} | ||
} | ||
logger.info( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need this exact log message again?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This came out of the conversation we had when we were reviewing the code previously. The gist of the conversation was that you thought we should capture every time the message was modified in some way.
* | ||
* @return true if has a MesssageHeader that contains an R01 or ORU_R01, otherwise false. | ||
*/ | ||
fun Bundle.isElr(): Boolean { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have we tried moving the logic here into getRSMessageType
? I think that would be cleaner, mostly because the code in this method that reads the message header value is going to be reused by test orders as well as other message types probably, right? I don't see the value of an isELR
method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My thought on this is that, if we intend to add several potential groupings (i.e., enums in RSMessageType), then getRSMessageType would become quite large. Keeping just meaningful function names related to the message grouping type makes the switch statement clearer in my opinion. Additionally, there is an old programming rule of thumb that goes something like "no subroutine should be longer than one screen in length". This, obviously, is rather vague but speaks to keeping code segments small to increase "understandability". You'll often see this argument backed by references like The Magic Number Seven, Plus or Minus Two.
*/ | ||
fun Bundle.getRSMessageType(): RSMessageType { | ||
when { | ||
isElr() -> return RSMessageType.LAB_RESULT |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you update this method per my suggestion above, you can just do this instead:
event is Coding && ((event.code == "R01") || (event.code == "ORU_R01")) -> return RSMessageType.LAB_RESULT
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my comment about your suggestion above.
@@ -43,14 +43,27 @@ const val validFHIRRecord1 = | |||
"""{"resourceType":"Bundle","id":"1667861767830636000.7db38d22-b713-49fc-abfa-2edba9c12347","meta":{"lastUpdated":"2022-11-07T22:56:07.832+00:00"},"identifier":{"value":"1234d1d1-95fe-462c-8ac6-46728dba581c"},"type":"message","timestamp":"2021-08-03T13:15:11.015+00:00","entry":[{"fullUrl":"Observation/d683b42a-bf50-45e8-9fce-6c0531994f09","resource":{"resourceType":"Observation","id":"d683b42a-bf50-45e8-9fce-6c0531994f09","status":"final","code":{"coding":[{"system":"http://loinc.org","code":"80382-5"}],"text":"Flu A"},"subject":{"reference":"Patient/9473889b-b2b9-45ac-a8d8-191f27132912"},"performer":[{"reference":"Organization/1a0139b9-fc23-450b-9b6c-cd081e5cea9d"}],"valueCodeableConcept":{"coding":[{"system":"http://snomed.info/sct","code":"260373001","display":"Detected"}]},"interpretation":[{"coding":[{"system":"http://terminology.hl7.org/CodeSystem/v2-0078","code":"A","display":"Abnormal"}]}],"method":{"extension":[{"url":"https://reportstream.cdc.gov/fhir/StructureDefinition/testkit-name-id","valueCoding":{"code":"BD Veritor System for Rapid Detection of SARS-CoV-2 & Flu A+B_Becton, Dickinson and Company (BD)"}},{"url":"https://reportstream.cdc.gov/fhir/StructureDefinition/equipment-uid","valueCoding":{"code":"BD Veritor System for Rapid Detection of SARS-CoV-2 & Flu A+B_Becton, Dickinson and Company (BD)"}}],"coding":[{"display":"BD Veritor System for Rapid Detection of SARS-CoV-2 & Flu A+B*"}]},"specimen":{"reference":"Specimen/52a582e4-d389-42d0-b738-bee51cf5244d"},"device":{"reference":"Device/78dc4d98-2958-43a3-a445-76ceef8c0698"}}}]}""" | |||
const val validFHIRRecord1Identifier = "1234d1d1-95fe-462c-8ac6-46728dba581c" | |||
|
|||
@Suppress("ktlint:standard:max-line-length") | |||
const val validFHIRRecord1a = | |||
"""{"resourceType":"Bundle","id":"1667861767830636000.7db38d22-b713-49fc-abfa-2edba9c12347","meta":{"lastUpdated":"2022-11-07T22:56:07.832+00:00"},"identifier":{"value":"1234d1d1-95fe-462c-8ac6-46728dba581c"},"type":"message","timestamp":"2021-08-03T13:15:11.015+00:00","entry":[{"fullUrl":"MessageHeader/0993dd0b-6ce5-3caf-a177-0b81cc780c18","resource":{"resourceType":"MessageHeader","id":"0993dd0b-6ce5-3caf-a177-0b81cc780c18","extension":[{"url":"https://reportstream.cdc.gov/fhir/StructureDefinition/encoding-characters","valueString":"^~\\&#"},{"url":"https://reportstream.cdc.gov/fhir/StructureDefinition/character-set","valueString":"UNICODE UTF-8"},{"url":"https://reportstream.cdc.gov/fhir/StructureDefinition/msh-message-header","extension":[{"url":"MSH.7","valueString":"20230501102531-0400"}]}],"eventCoding":{"system":"http://terminology.hl7.org/CodeSystem/v2-0003","code":"R01","display":"ORU^R01^ORU_R01"},"sender":{"reference":"Organization/1710886092467181000.213628f7-9569-4400-a95d-621c3bfbf121"}}},{"fullUrl":"Observation/d683b42a-bf50-45e8-9fce-6c0531994f09","resource":{"resourceType":"Observation","id":"d683b42a-bf50-45e8-9fce-6c0531994f09","status":"final","code":{"coding":[{"system":"http://loinc.org","code":"80382-5"}],"text":"Flu A"},"subject":{"reference":"Patient/9473889b-b2b9-45ac-a8d8-191f27132912"},"performer":[{"reference":"Organization/1a0139b9-fc23-450b-9b6c-cd081e5cea9d"}],"valueCodeableConcept":{"coding":[{"system":"http://snomed.info/sct","code":"260373001","display":"Detected"}]},"interpretation":[{"coding":[{"system":"http://terminology.hl7.org/CodeSystem/v2-0078","code":"A","display":"Abnormal"}]}],"method":{"extension":[{"url":"https://reportstream.cdc.gov/fhir/StructureDefinition/testkit-name-id","valueCoding":{"code":"BD Veritor System for Rapid Detection of SARS-CoV-2 & Flu A+B_Becton, Dickinson and Company (BD)"}},{"url":"https://reportstream.cdc.gov/fhir/StructureDefinition/equipment-uid","valueCoding":{"code":"BD Veritor System for Rapid Detection of SARS-CoV-2 & Flu A+B_Becton, Dickinson and Company (BD)"}}],"coding":[{"display":"BD Veritor System for Rapid Detection of SARS-CoV-2 & Flu A+B*"}]},"specimen":{"reference":"Specimen/52a582e4-d389-42d0-b738-bee51cf5244d"},"device":{"reference":"Device/78dc4d98-2958-43a3-a445-76ceef8c0698"}}}]}""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why did these 1a
versions need to be created?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was something that I meant to ask before I committed the code. We never reached a definitive conclusion about whether or not we could expect the event.Coding in the MessageHeader. If I just add it to the existing variables then it will break other tests. The 1a versions were added to support my tests without breaking the other existing tests.
@@ -544,6 +646,12 @@ class FhirConverterTests { | |||
} | |||
} | |||
|
|||
// @Test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please delete
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed.
Quality Gate passedIssues Measures |
This PR contains coding changes for user story 16144.
Test Steps:
Changes
Checklist
Testing
./prime test
or./gradlew testSmoke
against local Docker ReportStream container?Process
No changes.