feat: match MRN, Gender, DOB, and Age only (removed Name check)
This commit is contained in:
@@ -324,7 +324,6 @@ def _calculate_age(dob_str: str) -> Optional[int]:
|
|||||||
@router.get("/match-patient")
|
@router.get("/match-patient")
|
||||||
def match_patient(
|
def match_patient(
|
||||||
mrn: str = None,
|
mrn: str = None,
|
||||||
name: str = None,
|
|
||||||
gender: str = None,
|
gender: str = None,
|
||||||
dob: str = None,
|
dob: str = None,
|
||||||
age: int = None,
|
age: int = None,
|
||||||
@@ -332,15 +331,16 @@ def match_patient(
|
|||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Match incoming patient demographics to an active Contec monitor.
|
Match incoming patient demographics to an active Contec monitor.
|
||||||
|
Uses 4-point verification: MRN, Gender, DOB, Age.
|
||||||
|
|
||||||
Call this from the dashboard iframe URL:
|
Call this from the dashboard iframe URL:
|
||||||
/api/dashboard?minimal=true&mrn=MRN001&name=John+Doe&gender=M&dob=19900115&age=36
|
/api/dashboard?minimal=true&mrn=MRN001&gender=M&dob=19900115&age=36
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
{ matched: true/false, device_id, patient_id, bed_id, device_status, ... }
|
{ matched: true/false, device_id, patient_id, bed_id, device_status, ... }
|
||||||
"""
|
"""
|
||||||
if not mrn and not name:
|
if not mrn:
|
||||||
return {"matched": False, "reason": "No patient identifiers supplied"}
|
return {"matched": False, "reason": "No MRN supplied"}
|
||||||
|
|
||||||
# Fetch all patients
|
# Fetch all patients
|
||||||
all_patients = db.query(Patient).all()
|
all_patients = db.query(Patient).all()
|
||||||
@@ -348,7 +348,6 @@ def match_patient(
|
|||||||
|
|
||||||
# Normalize incoming params
|
# Normalize incoming params
|
||||||
in_mrn = (mrn or "").strip().upper()
|
in_mrn = (mrn or "").strip().upper()
|
||||||
in_name = _normalize_name(name or "")
|
|
||||||
in_gender = _gender_code(gender or "")
|
in_gender = _gender_code(gender or "")
|
||||||
in_dob = _normalize_dob(dob or "")
|
in_dob = _normalize_dob(dob or "")
|
||||||
in_age = age
|
in_age = age
|
||||||
@@ -359,23 +358,17 @@ def match_patient(
|
|||||||
for p in all_patients:
|
for p in all_patients:
|
||||||
score = 0
|
score = 0
|
||||||
|
|
||||||
# --- MRN check (primary) ---
|
# --- MRN check (primary, required) ---
|
||||||
p_mrn = (p.mrn or p.patient_id or "").strip().upper()
|
p_mrn = (p.mrn or p.patient_id or "").strip().upper()
|
||||||
if in_mrn and p_mrn == in_mrn:
|
if in_mrn and p_mrn == in_mrn:
|
||||||
score += 10
|
score += 10
|
||||||
elif in_mrn:
|
else:
|
||||||
continue # MRN supplied but doesn't match → skip
|
continue # MRN must match
|
||||||
|
|
||||||
# --- Name check ---
|
|
||||||
if in_name:
|
|
||||||
p_name = _normalize_name(p.name or "")
|
|
||||||
if p_name and any(w in p_name for w in in_name):
|
|
||||||
score += 3
|
|
||||||
|
|
||||||
# --- Gender check ---
|
# --- Gender check ---
|
||||||
if in_gender and p.gender:
|
if in_gender and p.gender:
|
||||||
if _gender_code(p.gender) == in_gender:
|
if _gender_code(p.gender) == in_gender:
|
||||||
score += 2
|
score += 3
|
||||||
|
|
||||||
# --- DOB check ---
|
# --- DOB check ---
|
||||||
if in_dob and p.dob:
|
if in_dob and p.dob:
|
||||||
@@ -392,10 +385,9 @@ def match_patient(
|
|||||||
match_score = score
|
match_score = score
|
||||||
matched_patient = p
|
matched_patient = p
|
||||||
|
|
||||||
# To be matched, MRN must be found, and name/gender/dob must also be validated
|
# Require MRN match (10) + at least one secondary attribute (gender/dob/age)
|
||||||
# (Require at least a score of 12: MRN + Name, or MRN + Gender, etc.)
|
|
||||||
if not matched_patient or match_score < 12:
|
if not matched_patient or match_score < 12:
|
||||||
return {"matched": False, "reason": "No matching patient found in monitor database with 4-point verification"}
|
return {"matched": False, "reason": "No matching patient found in monitor database with 4-point verification (MRN + Gender + DOB + Age)"}
|
||||||
|
|
||||||
# Find the most recent vital reading for this patient
|
# Find the most recent vital reading for this patient
|
||||||
latest = (
|
latest = (
|
||||||
|
|||||||
@@ -1148,14 +1148,13 @@
|
|||||||
|
|
||||||
// Extract matching credentials from URL query params
|
// Extract matching credentials from URL query params
|
||||||
const mrn = urlParams.get('mrn');
|
const mrn = urlParams.get('mrn');
|
||||||
const name = urlParams.get('name');
|
|
||||||
const gender = urlParams.get('gender');
|
const gender = urlParams.get('gender');
|
||||||
const dob = urlParams.get('dob');
|
const dob = urlParams.get('dob');
|
||||||
const age = urlParams.get('age');
|
const age = urlParams.get('age');
|
||||||
|
|
||||||
if (mrn || name) {
|
if (mrn) {
|
||||||
isMatchingMode = true;
|
isMatchingMode = true;
|
||||||
matchParams = { mrn, name, gender, dob, age };
|
matchParams = { mrn, gender, dob, age };
|
||||||
|
|
||||||
// Show verification loading overlay initially
|
// Show verification loading overlay initially
|
||||||
const overlay = document.getElementById('verificationOverlay');
|
const overlay = document.getElementById('verificationOverlay');
|
||||||
@@ -1163,7 +1162,7 @@
|
|||||||
overlay.className = 'verification-overlay loading';
|
overlay.className = 'verification-overlay loading';
|
||||||
document.getElementById('verificationIcon').textContent = '🔄';
|
document.getElementById('verificationIcon').textContent = '🔄';
|
||||||
document.getElementById('verificationTitle').textContent = 'Verifying Patient Credentials...';
|
document.getElementById('verificationTitle').textContent = 'Verifying Patient Credentials...';
|
||||||
document.getElementById('verificationMsg').textContent = 'Matching MRN, Name, Gender, DOB, and Age with live patient monitors...';
|
document.getElementById('verificationMsg').textContent = 'Matching MRN, Gender, DOB, and Age with live patient monitors...';
|
||||||
}
|
}
|
||||||
|
|
||||||
initWaveforms();
|
initWaveforms();
|
||||||
|
|||||||
Reference in New Issue
Block a user