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

Add endpoint to check auto, potential,conflict matches #128

Merged
merged 6 commits into from
Mar 12, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
221 changes: 218 additions & 3 deletions server/lib/routes/match.js
Original file line number Diff line number Diff line change
Expand Up @@ -1081,6 +1081,218 @@ router.get(`/count-new-auto-matches`, (req, res) => {
});
});

router.post('/matches', (req, res) => {
logger.info("Received a request to get all matches");
let matchResults = {
parent: [],
auto: [],
potential: [],
conflict: []
};
const patientJson = req.body;

generateScoreMatrix({patient: patientJson, level: 'childMatches',type: 'parent'}, () => {
return res.status(200).send(matchResults);
});

function matrixExist(sourceID) {
let found = false;
for (let key in matchResults) {
let matrixArray = matchResults[key];
for (let matrix of matrixArray) {
if (matrix.source_id === sourceID) {
found = true;
break;
}
}
if (found) {
break;
}
}
return found;
}

function generateScoreMatrix({patient, level, type}, callback) {
let matchingTool;
if (config.get("matching:tool") === "mediator") {
matchingTool = medMatching;
} else if (config.get("matching:tool") === "elasticsearch") {
matchingTool = esMatching;
}

matchingTool.performMatch({
sourceResource: patient,
ignoreList: [],
}, ({
error,
FHIRAutoMatched,
FHIRPotentialMatches,
FHIRConflictsMatches,
ESMatches
}) => {

let link = patient.link && patient.link.length > 0 ? patient.link[0].other.reference : null;
let goldenLink = null;

if (link) {
goldenLink = link.split('/')[1];
} else {

}

const validSystem = generalMixin.getClientIdentifier(patient);
let name = patient.name.find((name) => {
return name.use === 'official';
});
let given = '';
if(name && name.given) {
given = name.given.join(' ');
}
let clientUserId;
if (patient.meta && patient.meta.tag) {
for (let tag of patient.meta.tag) {
if (
tag.system === "http://openclientregistry.org/fhir/clientid"
) {
clientUserId = tag.code;
}
}
}
let systemName = generalMixin.getClientDisplayName(clientUserId);
let phone = '';
if(patient.telecom) {
for(let telecom of patient.telecom) {
if(telecom.system === 'phone' && telecom.value !== '' && telecom.value !== undefined) {
if (phone) {
phone += ', ';
}
phone += telecom.value;
}
}
}

let primaryPatient = {
id: patient.id,
gender: patient.gender,
given,
family: name.family,
birthDate: patient.birthDate,
phone,
uid: goldenLink,
ouid: goldenLink,
source_id: validSystem && validSystem.value ? validSystem.value : null,
source: systemName ? systemName: null,
scores: {}
};

if (patient.extension) {
for (let id of patient.extension) {
let propertyName = "extension_" + id.url;
primaryPatient[propertyName]= ( id.valueString ? id.valueString : id.valueDate );

}
}

if(patient.identifier) {
for(let identifier of patient.identifier) {
let propertyName = "identifier_" + identifier.system;
primaryPatient[propertyName]= identifier.value;
}
}

populateScores(primaryPatient, ESMatches, FHIRPotentialMatches, FHIRAutoMatched, FHIRConflictsMatches);
if (type == 'parent'){
matchResults.parent.push(primaryPatient);
} else if (type == 'auto') {
matchResults.auto.push(primaryPatient);
} else if (type == 'potential') {
matchResults.potential.push(primaryPatient);
} else if (type == 'conflict') {
matchResults.conflict.push(primaryPatient);
} else {
// Handle cases where 'type' doesn't match any of the known values.
}
if(level != 'childMatches' && !config.get('matching:resolvePotentialOfPotentials')) {
return callback();
}
async.series({
auto: (callback) => {
async.eachSeries(FHIRAutoMatched.entry, (autoMatched, nxtAutoMatched) => {
const validSystem = generalMixin.getClientIdentifier(autoMatched.resource);
if(matrixExist(validSystem.value)) {
return nxtAutoMatched();
}
generateScoreMatrix({patient: autoMatched.resource, level: 'grandChildMatches', type: 'auto'}, () => {
return nxtAutoMatched();
});
}, () => {
return callback(null);
});
},
potential: (callback) => {
async.eachSeries(FHIRPotentialMatches.entry, (potentialMatch, nxtPotMatch) => {
const validSystem = generalMixin.getClientIdentifier(potentialMatch.resource);
if(matrixExist(validSystem.value)) {
return nxtPotMatch();
}
generateScoreMatrix({patient: potentialMatch.resource, level: 'grandChildMatches', type: 'potential'}, () => {
return nxtPotMatch();
});
}, () => {
return callback(null);
});
},
conflicts: (callback) => {
async.eachSeries(FHIRConflictsMatches.entry, (conflictMatch, nxtConflictMatch) => {
const validSystem = generalMixin.getClientIdentifier(conflictMatch.resource);
if(matrixExist(validSystem.value)) {
return nxtConflictMatch();
}
generateScoreMatrix({patient: conflictMatch.resource, level: 'grandChildMatches', type: 'conflict'}, () => {
return nxtConflictMatch();
});
}, () => {
return callback(null);
});
}
}, () => {
return callback();
});
});
}
function populateScores(patient, ESMatches, FHIRPotentialMatches, FHIRAutoMatched, FHIRConflictsMatches) {
for(let esmatch of ESMatches) {
for(let autoMatch of esmatch.autoMatchResults) {
let patResource = FHIRAutoMatched.entry.find((entry) => {
return entry.resource.id === autoMatch['_id'];
});
const validSystem = generalMixin.getClientIdentifier(patResource.resource);
patient.scores[validSystem.value] = autoMatch['_score'];
}
for(let potMatch of esmatch.potentialMatchResults) {
let patResource = FHIRPotentialMatches.entry.find((entry) => {
return entry.resource.id === potMatch['_id'];
});
if(!patResource) {
continue;
}
const validSystem = generalMixin.getClientIdentifier(patResource.resource);
patient.scores[validSystem.value] = potMatch['_score'];
}
for(let conflMatch of esmatch.conflictsMatchResults) {
let patResource = FHIRConflictsMatches.entry.find((entry) => {
return entry.resource.id === conflMatch['_id'];
});
if(!patResource) {
continue;
}
const validSystem = generalMixin.getClientIdentifier(patResource.resource);
patient.scores[validSystem.value] = conflMatch['_score'];
}
}
}
});

router.get('/potential-matches/:id', (req, res) => {
logger.info("Received a request to get potential matches");
let matchResults = [];
Expand Down Expand Up @@ -1150,11 +1362,14 @@ router.get('/potential-matches/:id', (req, res) => {
}
}
let systemName = generalMixin.getClientDisplayName(clientUserId);
let phone;
let phone = '';
if(patient.telecom) {
for(let telecom of patient.telecom) {
if(telecom.system === 'phone') {
phone = telecom.value;
if(telecom.system === 'phone' && telecom.value !== '' && telecom.value !== undefined) {
if (phone) {
phone += ', ';
}
phone += telecom.value;
}
}
}
Expand Down
Loading