MyHealtheVet acts as a FHIR Server. It receives information from many sources and produces a given set of FHIR Resourrces
Utility Resources
Note that these resources are used purely to provide linkage, they are minimally populated based on the information MHV receives. Often that means all that is populated is an identifier.
Eventually this same API would support data from Cerner. Thus the same API providing comprehensive data from Vista and/or Cerner where ever it is.
Provenance – track where the data has come from, and if from multiple places track all.
Grahame - Intermediaries White Paper – https://confluence.hl7.org/display/FHIR/Intermediaries+White+Paper
HL7 FAST - Exchange Routing – http://hl7.org/fhir/R4/us/exchange-routing/
unknown (FHIR supports the following topics but unclear if this data exists in PHR)
care plan / care team resources
encounter resources
device resources
goal resources
procedure resources
questionnaire / questionnaireResponse resources
related person resources
service request resources
coverage resources
The use of FHIR AuditEvent should be used to track all uses of the FHIR API. This is a base configuration of the HAPI FHIR Server. See IHE Implementation Guide on the use of Basic Audit Log Patterns
Data input processing
General Pattern
Our FHIR database will have a Patient resource that is created as needed from the MHV Patient Profile. It contains minimal elements. The Patient is intended simply for API use.
Our FHIR database will assign Resource id value naturally using normal HAPI method (likely UUID)
Our FHIR database will put external identifiers (e.g. Those from the Vista id such as ImmunizationTO.id) into the .identifier element
The support Resources (Location, Organization, Practitioner, etc) will be contained in the primary clinical FHIR Resource. This because MHV is not told enough about these to properly identify and keep de-duplicated. For example when an Immunization was given at a specific location, we point at a Location resource that is contained in the Immunization with the details.
We do updates based on the .identifier. HAPI will find that resource, compare what it has with what we put in the bundle, and NOT do an update if there is no change. Thus we rely on HAPI to properly detect changes, so MHV code does not have to.
The current/historic list could be used to place the current id on entries with the given identifier, these entries can be then marked as conditional update. Where as today it is a conditional update based on a lookup on the .identifier. This will improve the performance of the HAPI server as it will remove an indirect lookup. We can also know which entries are NEW, so we can mark them as create. MHV-54038
Entered-in-Error
As data are removed or marked as entered-in-error on Vista, the MHV often is simply not informed about that object any more. With MHV eVault, this was handled by simply purging all PHR data each refresh. With FHIR database, we are a step away from the database and thus purging the database is not possible. We thus need some way to handle the cases where we previously learned of a resource, but it was then deleted, and we now are no longer told about it. The following are potential candidates. Wipe-and-Replace was used for atime, but it resulted in a large historic version filling up the FHIR database with no value.
Now using Index-Update-and-Delete, with the exception that Allergies we mark them with entered-in-error as we receive that status from HDR.
Index-Update-and-Delete: This model:
pulls current FHIR resource .identifier values (use _elementsparameter to limit results to just identifiers, id),
When updating the new data, remember the .identifier that were refreshed.
At the end, we can know which .identifier values were not updated. (most of the time there will be no unrefreshed data)
We can delete those that were not updated
– Note: Did not require moving to new HAPI Server.
Index-Update-and-Expunge: This model:
pulls current FHIR resource .identifier values (use _elementsparameter to limit results to just identifiers, id, status),
When updating the new VIA feed data, remember the .identifier that were refreshed.
At the end, we can know which .identifier values were not updated. (most of the time there will be no unrefreshed data)
We can patch those that were not updated, by .id, status to entered-in-error,
– Note: Patch is not supported in our current HAPI server.
Update-and-Expunge: This model is made available with an updated HAPI Server (6.10.0) that has the ability to disable history. However with this version we can't use Wipe-and-Replace as that will result in new id values being assigned at each refresh. So Update-and-Expunge is designed. Each VIA feed we convert to FHIR and request an update, but the HAPI server is smart enough to notice that nothing changed so it will not update the meta.lastUpdated. So we will add to our update the use of the http://hl7.org/fhir/R4/StructureDefinition/lastSourceSync extension, with todays date/time (now). This will force an update. Thus after we have fully processed the VIA feed, we can then look for entries older than now that are still active. This will most of the time return an empty set, but if it does return resources, we will change them to entered-in-error and update them.
Wipe-and-Replace: Delete the patient's specific Resource (e.g. delete all the Immunizations for this patient) and write using update current data from the VIA refresh – similar to eVault PHR today. The HAPI server notices an update, by business identifier, of a previously deleted resource, so it brings it back to non-deleted. Thus after a VIA refresh, only current resources are not-deleted. The drawback is that this keeps historic versions, with two versions per refresh, and _lastUpdated is always the refresh time. Also, the ones removed are not marked as entered-in-error. – January 2024, decided to abandon this as the database fills to fast with history, and we don't need this history
Get VIA updated
Get VDIF to expose their data
Get VDIF to expose their data in FHIR form
Use Lighthouse FHIR, and thus have the 24 hour problem
Use Lighthouse FHIR, and use a hack for short-term data. Where we only add vitals seen in VIA in the last 24 hours (or some timeframe).
Use HDR
Use CDW somehow
new event service? slack #ves-event-bus
track updates, and notice when a VIA update does not include a record we previously had. This would be very expensive and memory intensive. Thus might be something we do only occationally at low compute time.
References
Source of data received from VIA using a SOAP xml schema that might be from one of: