-
Notifications
You must be signed in to change notification settings - Fork 28
Adds the pathways for v3 handling around fhir_ids (BB-4166) #1419
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
Conversation
…t appears to work. Will be open to refactoring
…estclient patient/EOB/coverage are now broken, some tests are broken as well. Will fix in morning
…in create_token_response
…function throwing 404
…nctionality is working)
…tend more off version
… failing and we have some TODOs, but v3 and v2 endpoints all work
…ly do not pass a value for a log statement
apps/mymedicare_cb/models.py
Outdated
| hicn_updated = True | ||
|
|
||
| update_fhir_id = False | ||
| if user.crosswalk.fhir_id(Versions.V2) == '' or user.crosswalk.fhir_id(Versions.V3) == '': |
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.
@clewellyn-nava this changed as a result of 4224, as we now return a blank string from the fhir_id function. Wanted to call out to make sure this looks good to you. The behavior of a null fhir_id_v3 or v2 getting updated on a re-auth was broken as a result of this, but we've now confirmed it works 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.
Apologies, it was silently returning None on implicit codepaths and I wanted to make it explicit, didn't think about downstream None checks in this PR.
This can be revisited when we remove the fhir_id fully, in my opinion.
…ids are always updated if DB values differ from what BFD returns
|
@bwang-icf can you add some details on validating specific scenarios like a fhir_id_v2 being none, a re-auth happens, fhir_id_v2 is populated, updating the columns with whatever comes from BFD, etc.? |
That's a good idea. I'll add some more validation steps here and the expected outcomes. Some of these will need some input from the team/BFD to determine actual expected outcomes.
|
|
@bwang-icf @jimmyfagan @jadudm @clewellyn-nava and anyone else who reviews this work:
I did not realize that not all v2 synthetic users have v3 data, that may already be common knowledge, but want to call it out again here. |
| case Versions.V1: | ||
| user = Crosswalk.objects.get(fhir_id_v2=patient_id).user |
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.
Do we have fhir_id_v1 or both v1 and v2 share fhir_id_v2 , if so could you add comment in here to avoid confusion?
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.
Sure thing. I can add a comment here, but for most areas we are definitely treating v1/v2 as the same thing since their pathways are fairly similar.
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.
@stiwarisemanticbits , for reference (and so we have it here):
There used to be only fhir_id. We have now introduced _v2 and _v3, and the references to fhir_id became a function on the model that now takes a version parameter. So, everywhere we used to say:
crosswalk.fhir_id
(which was, at that time, implicitly already v1 and v2)
we now say:
crosswalk.fhir_id(Version.Vx)
So, commenting that V1 now shares V2 is something we would have to comment throughout the entire codebase. @bwang-icf , before we start commenting this in the code, we may want to decide if/where we need to document this kind of design work. I personally think it would be the TRD.
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.
I think commenting on the model is sufficient, otherwise we run into issues you described.
I believe we can also use | in case statements in Python 3.11
case Version.V1 | Version.V2
This has the code read that they are treated the same, and if someone is curious as to why, they can reference the model comment. Just my two cents.
| def supported_versions(): | ||
| return [Versions.V1, Versions.V2, Versions.V3] | ||
|
|
||
| def latest_versions(): | ||
| return [Versions.V2, Versions.V3] | ||
|
|
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.
We renamed this file but https://github.com/CMSgov/bluebutton-web-server/blob/15c1c3a62c7489df3b3596ed05c3c8abcce14980/apps/integration_tests/selenium_tests.py
still seems to be calling constants.py
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. Correcting this
apps/fhir/bluebutton/utils.py
Outdated
| if crosswalk.fhir_id(2) is not None: | ||
| result["BlueButton-BeneficiaryId"] = "patientId:" + str(crosswalk.fhir_id(2)) | ||
| # TODO: As we move to v2/v3, v3 does not use the hicnHash. We will want to refactor. | ||
| if crosswalk.fhir_id(version) is not None: |
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.
I checked crosswalk.fhir_id(version) is also returning empty string, which will not be none and will go to else block
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.
I think that would be expected behavior if we couldn't find a fhir id. If it's v2, then we would try to use hicn and if it's v3, it should just error out to a patient not found. Are you thinking something unintended would happen?
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.
@bwang-icf , you may want to look at this more closely. We did, for a bit, have behavior where crosswalk.fhir_id(version) could return None or a str. Now, we are always returning a str. (Unless that changed again?) So, this check will always fail.
I haven't expanded the code, but it would be good to reason through: if that code pathway always returns a string, and we're checking if it is not None (implying, under previous logic, that something was found)... is it the same now that we're always returning str, and we return '' when there is no value found?
(Edit: Actually, looking at this just a moment more, @stiwarisemanticbits has asked a really good question. I'd suggest walking through this code once more with that mindset: we no longer return None when something is not found, we return '', which means we may need to rethink the logic in this section in more way than one.)
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.
Trying to get this with the debugger by running a v3 request with user 00001 and I'm getting the patient 404 Your patient data cannot be found at this time error before it can get hit. I wondered if it was something funky with the debugger and tried 09003 and that did go through and trigger this code, so it seems like if we don't have the fhir_id, we display that page before we get here. Will look some more into it tomorrow.
| fhir_id, hash_lookup_type = match_fhir_id( | ||
| mbi=slsx_client.mbi, | ||
| hicn_hash=hicn_hash, | ||
| request=request, | ||
| version=supported_version, |
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.
When looping over v3 for a user without v3 data, match_fhir_id raises exceptions.NotFound, which we are not handling here. Is that expected? Before we reach to v3 v2 lookup is already succeeded, but overall method will fail.
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 I'm understanding correctly, you're seeing that if a request's version (v3 in this case) does NOT have a corresponding v3 fhir_id, we're erroring out even though we have a v2 fhir_id. That is expected behavior because we would not want to return the wrong version's fhir_id on a request as that could lead to complications down the line. Let me know if I'm missing something.
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.
I don't understand... @JamesDemeryNava , didn't we add something to the else clause here, so that the dictionaries would be more consistent/have values for every version? Granted, I don't think that would address @stiwarisemanticbits 's point.
I've ticketed cleaning up match_fhir_id. It is in the critical path, and as @stiwarisemanticbits (implicitly) points out, it is too easy for us to miss things in this function that could impact behavior.
https://jira.cms.gov/projects/BB2/issues/BB2-4265
Perhaps we will pick up the ticket, or perhaps we'll come up with something else.
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.
@jadudm We discussed it but I didn't push it. With doing a .get, I don't think it's necessary. Could be convinced otherwise, I think it depends where we land on the discussion above for v3 handling when it's not available.
clewellyn-nava
left a comment
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 work to everyone involved on this one, definitely a doozy.
JamesDemeryNava
left a comment
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.
ensuring this isn't merged until the TODO in generic.py is addressed (working on it now)
JIRA Ticket:
BB2-4166
What Does This PR Do?
Adds the pathways for v3 handling around fhir_ids. There are a lot of new spots where we are extending in the version that did not previously have it and should now have fhir_ids for either v1/v2 or v3 updated whenever there is an authorization or refresh.
What Should Reviewers Watch For?
If you're reviewing this PR, please check for these things in particular:
Validation
Validated with a local run and flow of the test client
During initial auth with v2 using a user that has v3 information (such as BBUser09003), view the local db columns for fhir_id, fhir_id_v2, and fhir_id_v3. For BBUser09003, they should all be populated with -10000010284539 for fhir_id/fhir_id_v2 and -206068516 for fhir_id_v3.
Manipulate the fhir_id values (erase them, add extra digits, remove digits, etc.) and perform a re-auth with the same user in v2. The values should return to their original values.
Perform the same steps as above using a v3 auth token using a user like BBUser09003 that has v3 information. We want to see the same fhir_id columns with the same values.
Perform steps 1 and 2 using a v2 auth token with a user that does NOT have v3 information (such as BBUser00001) and view the local db columns. The values should be updated to have a fhir_id_v2 but no fhir_id_v3.
Manipulate the fhir_id_v2 and re-auth to ensure that will also return to the original value.
Authenticate/re-authenticate with a user that does not have a fhir_id for the specific version you are requesting. If there is no fhir_id corresponding to the request's version, we should error out. We may need to reach out to BFD to ask for another user to use for this test case.
What Security Implications Does This PR Have?
Please indicate if this PR does any of the following:
security engineer's approval.
Any Migrations?
etc)