import { PatientDataForRiskAssessment, RiskDetectionResult, RiskFactor } from "./types"; import { RISK_FACTORS, RISK_THRESHOLDS } from "./config"; function checkRedFlags(data: PatientDataForRiskAssessment): { isRedFlag: boolean; reasons: string[] } { const reasons: string[] = []; if (data.bloodPressureSystolic && data.bloodPressureDiastolic) { if (data.bloodPressureSystolic >= 160 || data.bloodPressureDiastolic >= 110) { reasons.push("Severely elevated blood pressure (≥160/110 mmHg)"); } } else if (data.bloodPressureSystolic && data.bloodPressureSystolic >= 160) { reasons.push("Severely elevated systolic blood pressure (≥160 mmHg)"); } else if (data.bloodPressureDiastolic && data.bloodPressureDiastolic >= 110) { reasons.push("Severely elevated diastolic blood pressure (≥110 mmHg)"); } if (data.hasConvulsions) { reasons.push("Convulsions present"); } if (data.hasLossOfConsciousness) { reasons.push("Loss of consciousness"); } if (data.hasHeavyVaginalBleeding) { reasons.push("Heavy vaginal bleeding"); } if (data.hasAbsentFetalMovement) { reasons.push("Absent fetal movement"); } return { isRedFlag: reasons.length > 0, reasons }; } function evaluateRiskFactors(data: PatientDataForRiskAssessment): { contributingFactors: RiskFactor[]; totalScore: number; reasons: string[]; } { const contributingFactors: RiskFactor[] = []; const reasons: string[] = []; let totalScore = 0; if (data.age !== undefined && data.age >= 35) { const factor = RISK_FACTORS.find((f) => f.id === "advanced-maternal-age"); if (factor) { contributingFactors.push(factor); reasons.push(factor.description); totalScore += factor.points; } } else if (data.age !== undefined && data.age < 18) { const factor = RISK_FACTORS.find((f) => f.id === "teen-pregnancy"); if (factor) { contributingFactors.push(factor); reasons.push(factor.description); totalScore += factor.points; } } if (data.bmi !== undefined && data.bmi >= 35) { const factor = RISK_FACTORS.find((f) => f.id === "bmi-over-35"); if (factor) { contributingFactors.push(factor); reasons.push(factor.description); totalScore += factor.points; } } if (data.parity !== undefined && data.parity >= 5) { const factor = RISK_FACTORS.find((f) => f.id === "grand-multiparity"); if (factor) { contributingFactors.push(factor); reasons.push(factor.description); totalScore += factor.points; } } if (data.previousCaesareans && data.previousCaesareans > 0) { const factor = RISK_FACTORS.find((f) => f.id === "previous-caesarean"); if (factor) { contributingFactors.push(factor); reasons.push(factor.description); totalScore += factor.points; } } if (data.previousStillbirths && data.previousStillbirths > 0) { const factor = RISK_FACTORS.find((f) => f.id === "previous-stillbirth"); if (factor) { contributingFactors.push(factor); reasons.push(factor.description); totalScore += factor.points; } } if (data.previousIufd) { const factor = RISK_FACTORS.find((f) => f.id === "previous-iufd"); if (factor) { contributingFactors.push(factor); reasons.push(factor.description); totalScore += factor.points; } } if (data.previousPreeclampsia) { const factor = RISK_FACTORS.find((f) => f.id === "previous-preeclampsia"); if (factor) { contributingFactors.push(factor); reasons.push(factor.description); totalScore += factor.points; } } if (data.previousEclampsia) { const factor = RISK_FACTORS.find((f) => f.id === "previous-eclampsia"); if (factor) { contributingFactors.push(factor); reasons.push(factor.description); totalScore += factor.points; } } if (data.gestationalHypertension) { const factor = RISK_FACTORS.find((f) => f.id === "gestational-hypertension"); if (factor) { contributingFactors.push(factor); reasons.push(factor.description); totalScore += factor.points; } } if (data.chronicHypertension || data.chronicHypertensionBeforePregnancy) { const factor = RISK_FACTORS.find((f) => f.id === "chronic-hypertension"); if (factor) { contributingFactors.push(factor); reasons.push(factor.description); totalScore += factor.points; } } if (data.diabetesMellitus) { const factor = RISK_FACTORS.find((f) => f.id === "diabetes-mellitus"); if (factor) { contributingFactors.push(factor); reasons.push(factor.description); totalScore += factor.points; } } if (data.kidneyDisease) { const factor = RISK_FACTORS.find((f) => f.id === "kidney-disease"); if (factor) { contributingFactors.push(factor); reasons.push(factor.description); totalScore += factor.points; } } if (data.heartDisease) { const factor = RISK_FACTORS.find((f) => f.id === "heart-disease"); if (factor) { contributingFactors.push(factor); reasons.push(factor.description); totalScore += factor.points; } } if (data.previousPlacentalAbruption) { const factor = RISK_FACTORS.find((f) => f.id === "previous-placental-abruption"); if (factor) { contributingFactors.push(factor); reasons.push(factor.description); totalScore += factor.points; } } if (data.previousPlacentaPrevia) { const factor = RISK_FACTORS.find((f) => f.id === "placenta-previa"); if (factor) { contributingFactors.push(factor); reasons.push(factor.description); totalScore += factor.points; } } if (data.previousMultiplePregnancy) { const factor = RISK_FACTORS.find((f) => f.id === "twin-pregnancy"); if (factor) { contributingFactors.push(factor); reasons.push(factor.description); totalScore += factor.points; } } if (data.previousGestationalDiabetes) { const factor = RISK_FACTORS.find((f) => f.id === "previous-gestational-diabetes"); if (factor) { contributingFactors.push(factor); reasons.push(factor.description); totalScore += factor.points; } } if (data.familyPreeclampsia) { const factor = RISK_FACTORS.find((f) => f.id === "family-preeclampsia"); if (factor) { contributingFactors.push(factor); reasons.push(factor.description); totalScore += factor.points; } } if (data.familyHypertension) { const factor = RISK_FACTORS.find((f) => f.id === "family-hypertension"); if (factor) { contributingFactors.push(factor); reasons.push(factor.description); totalScore += factor.points; } } if (data.previousPretermBirth) { const factor = RISK_FACTORS.find((f) => f.id === "previous-preterm-birth"); if (factor) { contributingFactors.push(factor); reasons.push(factor.description); totalScore += factor.points; } } if (data.previousLowBirthWeight) { const factor = RISK_FACTORS.find((f) => f.id === "previous-low-birth-weight"); if (factor) { contributingFactors.push(factor); reasons.push(factor.description); totalScore += factor.points; } } if (data.previousPostpartumHemorrhage) { const factor = RISK_FACTORS.find((f) => f.id === "previous-postpartum-hemorrhage"); if (factor) { contributingFactors.push(factor); reasons.push(factor.description); totalScore += factor.points; } } if (data.smokingStatus === "CURRENT") { const factor = RISK_FACTORS.find((f) => f.id === "current-smoking"); if (factor) { contributingFactors.push(factor); reasons.push(factor.description); totalScore += factor.points; } } if (data.alcoholUse === "REGULAR") { const factor = RISK_FACTORS.find((f) => f.id === "current-alcohol"); if (factor) { contributingFactors.push(factor); reasons.push(factor.description); totalScore += factor.points; } } return { contributingFactors, totalScore, reasons }; } function calculateRiskLevel(score: number): "LOW" | "MODERATE" | "HIGH" | "EMERGENCY" { for (const threshold of RISK_THRESHOLDS) { if (threshold.maxPoints === null) { if (score >= threshold.minPoints) return threshold.level; } else { if (score >= threshold.minPoints && score <= threshold.maxPoints) { return threshold.level; } } } return "LOW"; } function collectRecommendations(factors: RiskFactor[]): string[] { const recommendations = new Set(); factors.forEach((factor) => { factor.recommendations.forEach((rec) => recommendations.add(rec)); }); return Array.from(recommendations); } export function detectRisks(data: PatientDataForRiskAssessment): RiskDetectionResult { const { isRedFlag, reasons: redFlagReasons } = checkRedFlags(data); const { contributingFactors, totalScore, reasons: riskFactorReasons } = evaluateRiskFactors(data); let riskLevel = calculateRiskLevel(totalScore); const recommendations = collectRecommendations(contributingFactors); if (isRedFlag) { riskLevel = "EMERGENCY"; } return { riskLevel, score: totalScore, reasons: isRedFlag ? redFlagReasons : riskFactorReasons, contributingFactors, recommendations, isRedFlag, redFlagReasons: isRedFlag ? redFlagReasons : undefined, }; }