From f9a0687abcc50d73d59f53cec14c53b0adfa794e Mon Sep 17 00:00:00 2001 From: Mike Moyer <87040148+mmoyer-va@users.noreply.github.com> Date: Fri, 10 Jan 2025 11:50:51 -0500 Subject: [PATCH] MHV-65416 Hash only the date portion of a CVIX timestamp (#34001) --- .../tests/util/radiologyUtil.unit.spec.js | 45 ++++++++++++++++++- .../mhv-medical-records/util/radiologyUtil.js | 16 +++++-- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/src/applications/mhv-medical-records/tests/util/radiologyUtil.unit.spec.js b/src/applications/mhv-medical-records/tests/util/radiologyUtil.unit.spec.js index 2df37e9f1a98..11bcca45e1f0 100644 --- a/src/applications/mhv-medical-records/tests/util/radiologyUtil.unit.spec.js +++ b/src/applications/mhv-medical-records/tests/util/radiologyUtil.unit.spec.js @@ -4,6 +4,7 @@ import { findMatchingCvixReport, findMatchingPhrAndCvixStudies, parseRadiologyReport, + radiologyRecordHash, radiologyReportsMatch, } from '../../util/radiologyUtil'; @@ -265,7 +266,7 @@ describe('findMatchingPhrAndCvixStudies', () => { const cvixResponse = [{ id: '12345', performedDatePrecise: 1712264604902 }]; const record = await findMatchingPhrAndCvixStudies( - 'rXXXXX-5c4d0c86', + 'rXXXXX-4ec8b4e4', null, cvixResponse, ); @@ -315,3 +316,45 @@ describe('findMatchingPhrAndCvixStudies', () => { expect(record.cvixDetails).to.be.null; }); }); + +describe('radiologyRecordHash', () => { + const record = { + procedureName: 'CT THORAX W/O CONT', + radiologist: 'JOHNSON,JOHN', + stationNumber: '660', + }; + + it('returns the different hashes for timestamps on different days', () => { + const record1 = { + ...record, + performedDatePrecise: 1296052117949, // January 26, 2011 9:28:37.949 AM ET + }; + + const record2 = { + ...record, + performedDatePrecise: 1296138517949, // January 27, 2011 9:28:37.949 AM ET (one day later) + }; + + const hash1 = radiologyRecordHash(record1); + const hash2 = radiologyRecordHash(record2); + + expect(hash1).to.not.eq(hash2); // Assert that the hashes are different. + }); + + it('returns the same hash for slightly differing timestamps', () => { + const record1 = { + ...record, + performedDatePrecise: 1296052117949, // January 26, 2011 9:28:37.949 AM ET + }; + + const record2 = { + ...record, + performedDatePrecise: 1296052177949, // January 26, 2011 9:29:37.949 AM ET (one minute later) + }; + + const hash1 = radiologyRecordHash(record1); + const hash2 = radiologyRecordHash(record2); + + expect(hash1).to.eq(hash2); // Assert that the hashes are the same. + }); +}); diff --git a/src/applications/mhv-medical-records/util/radiologyUtil.js b/src/applications/mhv-medical-records/util/radiologyUtil.js index 5c0c6f9942fe..d7a58f6595ab 100644 --- a/src/applications/mhv-medical-records/util/radiologyUtil.js +++ b/src/applications/mhv-medical-records/util/radiologyUtil.js @@ -184,11 +184,21 @@ const generateHash = data => { return hash.toString(16).padStart(8, '0'); // Convert to hexadecimal, pad to 8 chars }; -export const radiologyRecordHash = async record => { +export const radiologyRecordHash = record => { const { procedureName, radiologist, stationNumber } = record; - const date = record.eventDate || record.performedDatePrecise; + let date = record.eventDate || record.performedDatePrecise; + + if (!Number.isNaN(Number(date))) { + // If the date is a timestamp, convert it to a date (with no time). This is because subsequent + // fetches of the same study from CVIX can have timestamps that differ by a few seconds. This + // ensures the hash will remain consistent across fetches. + const timestamp = parseInt(date, 10); + const dateObj = new Date(timestamp); + [date] = dateObj.toISOString().split('T'); // Extract the date part + } + const dataString = `${procedureName}|${radiologist}|${stationNumber}|${date}`; - return (await generateHash(dataString)).substring(0, 8); + return generateHash(dataString).substring(0, 8); }; /**