85 lines
2.5 KiB
Python
85 lines
2.5 KiB
Python
"""
|
|
Deterministic completion evaluation engine. Single source of truth for onboarding completion.
|
|
"""
|
|
|
|
from typing import Dict, Any, List
|
|
|
|
|
|
def field_status(field_val: Any) -> str:
|
|
"""
|
|
Returns field status: 'not_collected' | 'reported' | 'confirmed_none' | 'unknown' | 'declined'
|
|
"""
|
|
if field_val is None:
|
|
return "not_collected"
|
|
|
|
if isinstance(field_val, dict):
|
|
status = field_val.get("status")
|
|
if status in ["reported", "confirmed_none", "unknown", "declined"]:
|
|
return status
|
|
items = field_val.get("items", [])
|
|
return "reported" if items else "not_collected"
|
|
|
|
if isinstance(field_val, list):
|
|
return "reported" if len(field_val) > 0 else "not_collected"
|
|
|
|
if isinstance(field_val, str) and field_val.strip():
|
|
return "reported"
|
|
|
|
return "not_collected"
|
|
|
|
|
|
def check_required_missing(state: Dict[str, Any]) -> List[str]:
|
|
"""
|
|
Single source of truth evaluating missing clinical fields for onboarding completion.
|
|
Required fields: reason_for_visit, symptoms, duration, medical_history, medications, allergies.
|
|
"""
|
|
if not isinstance(state, dict):
|
|
state = {}
|
|
|
|
missing: List[str] = []
|
|
|
|
# 1. Reason for Visit
|
|
if field_status(state.get("reason_for_visit")) == "not_collected":
|
|
missing.append("reason_for_visit")
|
|
|
|
# 2. Symptoms
|
|
symptoms = state.get("symptoms", [])
|
|
sym_status = field_status(symptoms)
|
|
if sym_status == "not_collected":
|
|
missing.append("symptoms")
|
|
|
|
# 3. Duration
|
|
has_duration = False
|
|
if isinstance(symptoms, list) and symptoms:
|
|
for s in symptoms:
|
|
if isinstance(s, dict) and s.get("duration"):
|
|
has_duration = True
|
|
break
|
|
if not has_duration and state.get("duration"):
|
|
has_duration = True
|
|
|
|
if sym_status != "not_collected" and not has_duration:
|
|
missing.append("duration")
|
|
|
|
# 4. Medical History
|
|
if field_status(state.get("medical_history")) == "not_collected":
|
|
missing.append("medical_history")
|
|
|
|
# 5. Medications
|
|
if field_status(state.get("medications")) == "not_collected":
|
|
missing.append("medications")
|
|
|
|
# 6. Allergies
|
|
if field_status(state.get("allergies")) == "not_collected":
|
|
missing.append("allergies")
|
|
|
|
return missing
|
|
|
|
|
|
def is_onboarding_complete(state: Dict[str, Any]) -> bool:
|
|
"""
|
|
Returns True ONLY if all required fields are collected or confirmed_none.
|
|
"""
|
|
missing = check_required_missing(state)
|
|
return len(missing) == 0
|