Skip to content
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

15500 in1 mappings #16836

Merged
merged 8 commits into from
Jan 2, 2025
Merged

15500 in1 mappings #16836

merged 8 commits into from
Jan 2, 2025

Conversation

jack-h-wang
Copy link
Collaborator

@jack-h-wang jack-h-wang commented Dec 18, 2024

This PR implements IN1 mappings for OML_O21 and ORM_O21 messages.

Test Steps:

  1. Review mappings to verify they match the mapping inventory (unless noted otherwise).
  2. Confirm all integration tests pass.

Changes

  • implement IN1 and IN1Extension mappings
  • add hl7v2date extension
  • add DT to Period mapping
  • add XPN to RelatedPerson mapping
  • update AUIExtension mapping
  • update ORM_021 mapping
  • update tests

Checklist

Testing

  • Tested locally?
  • Ran ./prime test or ./gradlew testSmoke against local Docker ReportStream container?
  • (For Changes to /frontend-react/...) Ran npm run lint:write?
  • Added tests?

Linked Issues

@jack-h-wang jack-h-wang added the platform Platform Team label Dec 18, 2024
Copy link
Contributor

github-actions bot commented Dec 18, 2024

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

OpenSSF Scorecard

PackageVersionScoreDetails

Scanned Manifest Files

Copy link
Contributor

github-actions bot commented Dec 18, 2024

Test Results

1 268 tests  ±0   1 264 ✅ ±0   7m 54s ⏱️ -21s
  164 suites ±0       4 💤 ±0 
  164 files   ±0       0 ❌ ±0 

Results for commit 4fd96d9. ± Comparison against base commit 345f93c.

♻️ This comment has been updated with latest results.

Copy link
Contributor

github-actions bot commented Dec 18, 2024

Integration Test Results

 60 files  ±0   60 suites  ±0   42m 43s ⏱️ + 5m 57s
427 tests +1  417 ✅ +1  10 💤 ±0  0 ❌ ±0 
430 runs  +1  420 ✅ +1  10 💤 ±0  0 ❌ ±0 

Results for commit 4fd96d9. ± Comparison against base commit 345f93c.

♻️ This comment has been updated with latest results.

# These extensions exist because HL7 dates have very little restrictions (i.e. YYYY-MM, YYYY-MM-DD HH, YYYY-MM-DD HH:MM)
# are all valid, but the FHIR specs has much stricter rules. In order to reliably generate the same HL7 message, these
# extensions are used to capture what was in the original HL7 message and then exclusively used when mapping FHIR->HL7
- id: "hl7v2-date"
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This date only extension was added for two reasons: HL7 DT (date) and DTM (datetime) are distinct datatypes and should have separate handling, and storing it as a different extension makes it so transforms that should only be applied to datetimes (such as timezone conversion) would not apply. So far, only the IN1 mappings have been updated to use this extension.

@@ -2,7 +2,7 @@

url:
type: STRING
valueOf: IN1.14
valueOf: $auiExtensionName
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsure why this was hardcoded to IN1.14 previously, but this now better resembles other extension datatypes in that it receives the extension name from the caller.

@@ -0,0 +1,12 @@
# $schema: ./../../../../../json_schema/fhir/hl7-to-fhir-mapping-resource-template.json

resourceType: RelatedPerson
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A RelatedPerson needs to be created here but only the name is provided. That isn't enough information to reliably determine if an existing RelatedPerson resource is actually the same person, so no attempt is made to match one.

@jack-h-wang jack-h-wang marked this pull request as ready for review December 24, 2024 08:37
@jack-h-wang jack-h-wang requested a review from a team as a code owner December 24, 2024 08:37
@jack-h-wang jack-h-wang force-pushed the platform/jwang/15500-in1-mappings branch from a8bbc15 to 2432291 Compare December 26, 2024 16:58
@jack-h-wang jack-h-wang force-pushed the platform/jwang/15500-in1-mappings branch from 2432291 to 2a28b56 Compare December 26, 2024 20:06
@jack-h-wang jack-h-wang force-pushed the platform/jwang/15500-in1-mappings branch from 2a28b56 to 937df2f Compare December 27, 2024 17:00
@JFisk42 JFisk42 self-assigned this Dec 27, 2024
Copy link
Collaborator

@JFisk42 JFisk42 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything is looking good so far! I got to everything but a couple of the files today, I'll finish those up Monday.

One extra thing: We should either log a small ticket to add IN1 to ORM mappings or chuck it in on this review.

@@ -40,6 +40,7 @@ elements:
# https://github.com/CDCgov/prime-reportstream/issues/15500
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This todo can be addressed now. OML mappings specify Coverage.subscriber=Patient[PID] so the fhirpath should be scoped to that.

But now that I'm looking into it I'm not sure how or if to resolve it. IN1.16 can be mapped to Coverage.subscriber either as the Patient or a RP.
Additional data point: I was looking at ORM mappings and they don't specify any required link.

The two options seem to be to either not have any scoping on this (and leave line 38 as is, but just remove the commented fhirpath. Or updating the fhirpath to scope the Coverage to either the patient or just any related person. Like 'Bundle.entry.resource.ofType(Coverage).where((subscriber.resolve().id = %resource.entry.resource.ofType(Patient).id) || subscriber.resolve().ofType(RelatedPerson))' (not sure if this logic works, just throwing it out there as pseudo code).

Copy link
Collaborator Author

@jack-h-wang jack-h-wang Dec 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm having trouble figuring out what adding RelatedPerson to the scope actually does for us; as it is, there's no explicit link between the RP and the patient. Writing the scope this way effectively boils down to the logic of include this coverage if IN1.16 was populated, and don't include it if it wasn't. That doesn't seem right to me either. (For the record, your pseudocode works but the or operator is or rather than ||.)

Looking closer at the Coverage resource, I wonder if it makes the most sense to unconditionally map Coverage.beneficiary to the patient and use that as the link... that logically makes sense to me, but that's not a mapping that anything is telling us to do. It gives me a little more piece of mind that we couldn't possibly mix up the order and end up writing the IN1 segment under the wrong patient, though... can these files contain more than one patient?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking we should keep as it and removing/updating todo because I don't think what is listed in the mapping inventory makes sense.

The references column for IN1[Coverage] states Coverage.subscriber=Patient[PID]. My understanding of the References column is that it is supposed to represent a required binding. IE How this should read is that we map Coverage back to IN1 if and only if Coverage.subscriber is a reference to the only patient in the bundle. (Please let me know if this is wrong).

So but this only works if IN1-17 is present and 'patient'. So putting anything more restrictive here would be a problem unless we did something radical like just adding a patient reference to Coverage.extension or Coverage.subscriber.extension or Coverage.beneficiary. There's lots of potential for confusion there and all of this is just to prevent if a fhir bundle is sent with irrelevant coverage resources which sounds very unlikely.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking a little more, PV1[Coverage] has Coverage.beneficiary.reference=Patient[1].id listed as reference. (This is a really sparse mapping file, only specifying that PV1-20 maps to Coverage.type.) If the implication is that both are supposed to update the same Coverage, then creating the Coverage.beneficiary link makes sense...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah actually I think you're right. Sorry, my brain has been flipping on the references column and I'm overthinking it. Looking at some examples in our code this column is generally treated as something that should be mapped, so adding a reference to the patient on Coverage.beneficiary and then having the mapping here require that sounds correct to me.

@@ -2,47 +2,94 @@

resourceType: Coverage

# IN1.2 CWE[Identifier] is a subset of the input CWE; maps identifier.name which does not exist; use IN1Extension
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CWE[Identifier] having name as a field on Identifier feels like it must be a typo in the mappings. This could be a good question to ask in the HL7/FHIR group.

To toss onto this: For Coverage there are some required fields that are entirely unmapped: status & beneficiary. Payor is also required but at least we map that when available. This second part is more of a note for if/when we address required fhir fields, but if we do post to the group these could be brought up at the same time.

Copy link
Collaborator

@JFisk42 JFisk42 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

Copy link

"url": "https://reportstream.cdc.gov/fhir/StructureDefinition/in1-coverage",
"extension": [
{
"url": "IN1.2",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I'm reading this correctly, the vast majority of the IN1 segment is stored in a giant extension on the Coverage resource?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct; we need a location to store any values that either didn't have a FHIR mapping or the FHIR mapping was insufficient for being able to rebuild the HL7. This is the same pattern as other mappings (OBX, PRT, etc).

Copy link
Collaborator

@jalbinson jalbinson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All looks good and tests pass locally on my machine

@jack-h-wang jack-h-wang merged commit a46da3b into main Jan 2, 2025
25 checks passed
@jack-h-wang jack-h-wang deleted the platform/jwang/15500-in1-mappings branch January 2, 2025 19:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
platform Platform Team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants