/** * Drug Interaction and Safety Checking System * * Provides comprehensive drug safety checks: * - Drug-drug interactions * - Contraindication checking * - Dosing validation * - Allergy cross-reactivity * - Organ function-based adjustments * - Pregnancy/lactation safety * - QT prolongation risk assessment * - CYP450 interaction analysis * * Data sources would include: * - FDA drug labels * - DrugBank * - PharmGKB * - Clinical Pharmacology databases */ import { EventEmitter } from 'events'; // ═══════════════════════════════════════════════════════════════════════════════ // DRUG INTERACTION TYPES // ═══════════════════════════════════════════════════════════════════════════════ export interface Drug { name: string; genericName: string; brandNames?: string[]; drugClass: string; rxNormId?: string; ndc?: string; atcCode?: string; mechanism?: string; metabolism?: { cyp450?: CYP450Profile; renalExcretion?: number; // percentage hepaticMetabolism?: number; }; } export interface CYP450Profile { substrates?: string[]; // CYP enzymes this drug is metabolized by inhibitors?: string[]; // CYP enzymes this drug inhibits inducers?: string[]; // CYP enzymes this drug induces } export interface DrugInteraction { drug1: string; drug2: string; severity: 'contraindicated' | 'major' | 'moderate' | 'minor'; type: 'pharmacokinetic' | 'pharmacodynamic' | 'additive' | 'synergistic' | 'antagonistic'; mechanism: string; clinicalEffect: string; management: string; documentation: 'established' | 'theoretical' | 'case-report'; references?: string[]; } export interface Contraindication { drug: string; condition: string; severity: 'absolute' | 'relative'; reason: string; alternatives?: string[]; } export interface DosingGuideline { drug: string; indication: string; standardDose: string; renalAdjustment?: { gfrThreshold: number; adjustment: string; }[]; hepaticAdjustment?: { childPughClass: 'A' | 'B' | 'C'; adjustment: string; }[]; ageAdjustment?: { ageThreshold: number; adjustment: string; }[]; weightBasedDosing?: { formula: string; maxDose?: string; }; } export interface AllergyCheck { reportedAllergy: string; drugToCheck: string; crossReactivity: boolean; riskLevel: 'high' | 'moderate' | 'low' | 'none'; relatedAllergens: string[]; recommendation: string; } export interface SafetyAlert { id: string; type: 'interaction' | 'contraindication' | 'allergy' | 'dosing' | 'organ-function' | 'pregnancy' | 'qt-prolongation' | 'black-box'; severity: 'critical' | 'high' | 'moderate' | 'low'; title: string; description: string; affectedDrugs: string[]; recommendation: string; overridable: boolean; requiresDocumentation: boolean; references?: string[]; } export interface PatientSafetyProfile { patientId: string; allergies: { allergen: string; reactionType: 'anaphylaxis' | 'rash' | 'angioedema' | 'gi' | 'other'; severity: 'severe' | 'moderate' | 'mild'; }[]; renalFunction: { gfr: number; creatinine: number; dialysis: boolean; }; hepaticFunction: { childPughClass?: 'A' | 'B' | 'C'; bilirubin?: number; albumin?: number; inr?: number; ascites?: 'none' | 'mild' | 'moderate-severe'; encephalopathy?: 'none' | 'grade-1-2' | 'grade-3-4'; }; cardiacStatus: { qtcInterval?: number; lvef?: number; arrhythmiaHistory?: boolean; pacemakerIcd?: boolean; }; currentMedications: { drug: string; dose: string; frequency: string; startDate?: Date; }[]; demographics: { age: number; weight: number; gender: 'male' | 'female'; pregnant?: boolean; breastfeeding?: boolean; }; geneticFactors?: { cyp2d6?: 'poor' | 'intermediate' | 'normal' | 'rapid' | 'ultra-rapid'; cyp2c19?: 'poor' | 'intermediate' | 'normal' | 'rapid' | 'ultra-rapid'; dpyd?: 'deficient' | 'intermediate' | 'normal'; ugt1a1?: '*28/*28' | '*28/*1' | '*1/*1'; tpmt?: 'poor' | 'intermediate' | 'normal'; }; } // ═══════════════════════════════════════════════════════════════════════════════ // DRUG SAFETY SERVICE // ═══════════════════════════════════════════════════════════════════════════════ export class DrugSafetyService extends EventEmitter { private interactionDatabase: Map = new Map(); private contraindicationDatabase: Map = new Map(); private dosingGuidelines: Map = new Map(); private allergenCrossReactivity: Map = new Map(); private qtProlongingDrugs: Set = new Set(); private blackBoxWarnings: Map = new Map(); constructor() { super(); this.initializeDatabases(); } /** * Perform comprehensive safety check */ async performSafetyCheck( patient: PatientSafetyProfile, proposedDrugs: { drug: string; dose: string; route: string }[] ): Promise<{ safe: boolean; alerts: SafetyAlert[]; summary: { criticalAlerts: number; highAlerts: number; moderateAlerts: number; lowAlerts: number; overallRisk: 'critical' | 'high' | 'moderate' | 'low' | 'minimal'; }; recommendations: string[]; }> { const alerts: SafetyAlert[] = []; const recommendations: string[] = []; // Get all drugs (current + proposed) const allDrugs = [ ...patient.currentMedications.map(m => m.drug), ...proposedDrugs.map(d => d.drug) ]; // 1. Check drug-drug interactions const interactionAlerts = await this.checkDrugInteractions(allDrugs); alerts.push(...interactionAlerts); // 2. Check contraindications based on patient conditions const contraindicationAlerts = await this.checkContraindications(proposedDrugs.map(d => d.drug), patient); alerts.push(...contraindicationAlerts); // 3. Check allergies and cross-reactivity const allergyAlerts = await this.checkAllergies(proposedDrugs.map(d => d.drug), patient.allergies); alerts.push(...allergyAlerts); // 4. Check dosing based on organ function const dosingAlerts = await this.checkDosing(proposedDrugs, patient); alerts.push(...dosingAlerts); // 5. Check QT prolongation risk const qtAlerts = await this.checkQTProlongation(allDrugs, patient); alerts.push(...qtAlerts); // 6. Check pregnancy/lactation if (patient.demographics.pregnant || patient.demographics.breastfeeding) { const pregnancyAlerts = await this.checkPregnancySafety(proposedDrugs.map(d => d.drug), patient); alerts.push(...pregnancyAlerts); } // 7. Check black box warnings const blackBoxAlerts = await this.checkBlackBoxWarnings(proposedDrugs.map(d => d.drug)); alerts.push(...blackBoxAlerts); // 8. Check pharmacogenomic considerations if (patient.geneticFactors) { const pgxAlerts = await this.checkPharmacogenomics(proposedDrugs.map(d => d.drug), patient.geneticFactors); alerts.push(...pgxAlerts); } // Count alerts by severity const criticalAlerts = alerts.filter(a => a.severity === 'critical').length; const highAlerts = alerts.filter(a => a.severity === 'high').length; const moderateAlerts = alerts.filter(a => a.severity === 'moderate').length; const lowAlerts = alerts.filter(a => a.severity === 'low').length; // Determine overall risk let overallRisk: 'critical' | 'high' | 'moderate' | 'low' | 'minimal'; if (criticalAlerts > 0) overallRisk = 'critical'; else if (highAlerts > 0) overallRisk = 'high'; else if (moderateAlerts > 0) overallRisk = 'moderate'; else if (lowAlerts > 0) overallRisk = 'low'; else overallRisk = 'minimal'; // Generate recommendations for (const alert of alerts.filter(a => a.severity === 'critical' || a.severity === 'high')) { recommendations.push(alert.recommendation); } // Determine if safe to proceed const safe = criticalAlerts === 0 && !alerts.some(a => !a.overridable); // Emit event this.emit('safety-check-completed', { patientId: patient.patientId, safe, alertCount: alerts.length }); return { safe, alerts: alerts.sort((a, b) => { const severityOrder = { critical: 0, high: 1, moderate: 2, low: 3 }; return severityOrder[a.severity] - severityOrder[b.severity]; }), summary: { criticalAlerts, highAlerts, moderateAlerts, lowAlerts, overallRisk }, recommendations }; } /** * Check drug-drug interactions */ async checkDrugInteractions(drugs: string[]): Promise { const alerts: SafetyAlert[] = []; const checkedPairs = new Set(); for (let i = 0; i < drugs.length; i++) { for (let j = i + 1; j < drugs.length; j++) { const drug1 = drugs[i].toLowerCase(); const drug2 = drugs[j].toLowerCase(); const pairKey = [drug1, drug2].sort().join('|'); if (checkedPairs.has(pairKey)) continue; checkedPairs.add(pairKey); const interaction = this.findInteraction(drug1, drug2); if (interaction) { alerts.push({ id: `DDI-${Date.now()}-${i}-${j}`, type: 'interaction', severity: this.mapInteractionSeverity(interaction.severity), title: `Drug Interaction: ${drugs[i]} + ${drugs[j]}`, description: interaction.clinicalEffect, affectedDrugs: [drugs[i], drugs[j]], recommendation: interaction.management, overridable: interaction.severity !== 'contraindicated', requiresDocumentation: interaction.severity === 'major' || interaction.severity === 'contraindicated', references: interaction.references }); } } } return alerts; } /** * Check contraindications */ async checkContraindications(drugs: string[], patient: PatientSafetyProfile): Promise { const alerts: SafetyAlert[] = []; // Check renal contraindications if (patient.renalFunction.gfr < 30) { const renalContraindicated = ['metformin', 'nsaids', 'lithium', 'gadolinium']; for (const drug of drugs) { if (renalContraindicated.some(c => drug.toLowerCase().includes(c))) { alerts.push({ id: `CI-RENAL-${Date.now()}`, type: 'contraindication', severity: patient.renalFunction.gfr < 15 ? 'critical' : 'high', title: `Renal Contraindication: ${drug}`, description: `${drug} is contraindicated or requires significant dose adjustment with GFR ${patient.renalFunction.gfr} mL/min`, affectedDrugs: [drug], recommendation: `Consider alternative therapy or significant dose reduction. Consult nephrology if essential.`, overridable: patient.renalFunction.gfr >= 15, requiresDocumentation: true }); } } } // Check hepatic contraindications if (patient.hepaticFunction.childPughClass === 'C') { const hepaticContraindicated = ['methotrexate', 'valproic-acid', 'isoniazid', 'ketoconazole']; for (const drug of drugs) { if (hepaticContraindicated.some(c => drug.toLowerCase().includes(c))) { alerts.push({ id: `CI-HEPATIC-${Date.now()}`, type: 'contraindication', severity: 'critical', title: `Hepatic Contraindication: ${drug}`, description: `${drug} is contraindicated in Child-Pugh Class C liver disease`, affectedDrugs: [drug], recommendation: `Avoid use. Consider alternative therapy.`, overridable: false, requiresDocumentation: true }); } } } // Check cardiac contraindications if (patient.cardiacStatus.lvef && patient.cardiacStatus.lvef < 40) { const cardiacCaution = ['anthracycline', 'trastuzumab', 'sunitinib', 'sorafenib']; for (const drug of drugs) { if (cardiacCaution.some(c => drug.toLowerCase().includes(c))) { alerts.push({ id: `CI-CARDIAC-${Date.now()}`, type: 'contraindication', severity: 'high', title: `Cardiac Caution: ${drug}`, description: `${drug} has cardiotoxicity risk. Patient LVEF is ${patient.cardiacStatus.lvef}%`, affectedDrugs: [drug], recommendation: `Baseline and serial cardiac monitoring required. Consider cardiology consultation.`, overridable: true, requiresDocumentation: true }); } } } return alerts; } /** * Check allergy cross-reactivity */ async checkAllergies(drugs: string[], allergies: PatientSafetyProfile['allergies']): Promise { const alerts: SafetyAlert[] = []; for (const allergy of allergies) { for (const drug of drugs) { const crossReactivity = this.checkCrossReactivity(allergy.allergen, drug); if (crossReactivity.crossReactivity) { const severity = allergy.severity === 'severe' && crossReactivity.riskLevel === 'high' ? 'critical' : allergy.severity === 'severe' || crossReactivity.riskLevel === 'high' ? 'high' : 'moderate'; alerts.push({ id: `ALLERGY-${Date.now()}`, type: 'allergy', severity, title: `Allergy Alert: ${drug}`, description: `Patient allergic to ${allergy.allergen}. ${drug} has ${crossReactivity.riskLevel} cross-reactivity risk.`, affectedDrugs: [drug], recommendation: crossReactivity.recommendation, overridable: allergy.severity !== 'severe' || crossReactivity.riskLevel !== 'high', requiresDocumentation: true }); } } } return alerts; } /** * Check dosing based on organ function */ async checkDosing( drugs: { drug: string; dose: string; route: string }[], patient: PatientSafetyProfile ): Promise { const alerts: SafetyAlert[] = []; for (const drugOrder of drugs) { const guidelines = this.dosingGuidelines.get(drugOrder.drug.toLowerCase()); if (!guidelines) continue; for (const guideline of guidelines) { // Check renal adjustment if (guideline.renalAdjustment) { for (const adj of guideline.renalAdjustment) { if (patient.renalFunction.gfr < adj.gfrThreshold) { alerts.push({ id: `DOSE-RENAL-${Date.now()}`, type: 'dosing', severity: 'moderate', title: `Dose Adjustment Required: ${drugOrder.drug}`, description: `Patient GFR ${patient.renalFunction.gfr} requires dose adjustment`, affectedDrugs: [drugOrder.drug], recommendation: adj.adjustment, overridable: true, requiresDocumentation: true }); break; } } } // Check hepatic adjustment if (guideline.hepaticAdjustment && patient.hepaticFunction.childPughClass) { const adj = guideline.hepaticAdjustment.find(a => a.childPughClass === patient.hepaticFunction.childPughClass); if (adj) { alerts.push({ id: `DOSE-HEPATIC-${Date.now()}`, type: 'dosing', severity: patient.hepaticFunction.childPughClass === 'C' ? 'high' : 'moderate', title: `Hepatic Dose Adjustment: ${drugOrder.drug}`, description: `Child-Pugh Class ${patient.hepaticFunction.childPughClass} requires dose adjustment`, affectedDrugs: [drugOrder.drug], recommendation: adj.adjustment, overridable: patient.hepaticFunction.childPughClass !== 'C', requiresDocumentation: true }); } } // Check age-based adjustment if (guideline.ageAdjustment) { for (const adj of guideline.ageAdjustment) { if (patient.demographics.age >= adj.ageThreshold) { alerts.push({ id: `DOSE-AGE-${Date.now()}`, type: 'dosing', severity: 'low', title: `Age-Based Consideration: ${drugOrder.drug}`, description: `Patient age ${patient.demographics.age} may require adjustment`, affectedDrugs: [drugOrder.drug], recommendation: adj.adjustment, overridable: true, requiresDocumentation: false }); break; } } } } } return alerts; } /** * Check QT prolongation risk */ async checkQTProlongation(drugs: string[], patient: PatientSafetyProfile): Promise { const alerts: SafetyAlert[] = []; const qtDrugs = drugs.filter(d => this.qtProlongingDrugs.has(d.toLowerCase())); if (qtDrugs.length > 0) { // Check baseline QTc const baselineQTc = patient.cardiacStatus.qtcInterval; let riskLevel: 'critical' | 'high' | 'moderate' | 'low' = 'moderate'; if (baselineQTc && baselineQTc > 500) { riskLevel = 'critical'; } else if (baselineQTc && baselineQTc > 470) { riskLevel = 'high'; } else if (qtDrugs.length >= 2) { riskLevel = 'high'; } // Check for additional risk factors const riskFactors: string[] = []; if (patient.demographics.gender === 'female') riskFactors.push('Female gender'); if (patient.demographics.age > 65) riskFactors.push('Age > 65'); if (patient.cardiacStatus.arrhythmiaHistory) riskFactors.push('Arrhythmia history'); // Would also check electrolytes (K, Mg) if available if (qtDrugs.length >= 2 || riskLevel === 'critical' || riskLevel === 'high') { alerts.push({ id: `QT-${Date.now()}`, type: 'qt-prolongation', severity: riskLevel, title: `QT Prolongation Risk: ${qtDrugs.join(', ')}`, description: `${qtDrugs.length} QT-prolonging drug(s) ordered. ${riskFactors.length > 0 ? 'Risk factors: ' + riskFactors.join(', ') : ''}`, affectedDrugs: qtDrugs, recommendation: `Monitor QTc. Consider ECG at baseline and after steady state. Avoid if QTc > 500ms.`, overridable: riskLevel !== 'critical', requiresDocumentation: true }); } } return alerts; } /** * Check pregnancy and lactation safety */ async checkPregnancySafety( drugs: string[], patient: PatientSafetyProfile ): Promise { const alerts: SafetyAlert[] = []; // Known teratogenic drugs const categoryX: string[] = [ 'methotrexate', 'thalidomide', 'lenalidomide', 'pomalidomide', 'isotretinoin', 'warfarin', 'ribavirin', 'leflunomide' ]; const categoryD: string[] = [ 'doxorubicin', 'cyclophosphamide', 'imatinib', 'tamoxifen', 'carbamazepine', 'phenytoin', 'valproic acid', 'lithium' ]; for (const drug of drugs) { const drugLower = drug.toLowerCase(); if (categoryX.some(x => drugLower.includes(x))) { alerts.push({ id: `PREG-X-${Date.now()}`, type: 'pregnancy', severity: 'critical', title: `Pregnancy Contraindication: ${drug}`, description: `${drug} is absolutely contraindicated in pregnancy (Category X equivalent)`, affectedDrugs: [drug], recommendation: `Do not use. Use alternative therapy. Ensure contraception.`, overridable: false, requiresDocumentation: true }); } else if (categoryD.some(d => drugLower.includes(d))) { alerts.push({ id: `PREG-D-${Date.now()}`, type: 'pregnancy', severity: 'high', title: `Pregnancy Risk: ${drug}`, description: `${drug} has evidence of fetal risk but may be used if benefit outweighs risk`, affectedDrugs: [drug], recommendation: `Document informed consent. Discuss risks with patient. Consider alternatives.`, overridable: true, requiresDocumentation: true }); } } return alerts; } /** * Check black box warnings */ async checkBlackBoxWarnings(drugs: string[]): Promise { const alerts: SafetyAlert[] = []; for (const drug of drugs) { const warnings = this.blackBoxWarnings.get(drug.toLowerCase()); if (warnings && warnings.length > 0) { alerts.push({ id: `BBW-${Date.now()}`, type: 'black-box', severity: 'high', title: `Black Box Warning: ${drug}`, description: warnings.join('; '), affectedDrugs: [drug], recommendation: `Ensure appropriate monitoring and patient education. Document informed consent.`, overridable: true, requiresDocumentation: true }); } } return alerts; } /** * Check pharmacogenomic considerations */ async checkPharmacogenomics( drugs: string[], genetics: NonNullable ): Promise { const alerts: SafetyAlert[] = []; // DPYD and fluoropyrimidines if (genetics.dpyd && genetics.dpyd !== 'normal') { const fluoropyrimidines = ['5-fu', 'fluorouracil', 'capecitabine']; const affected = drugs.filter(d => fluoropyrimidines.some(f => d.toLowerCase().includes(f))); if (affected.length > 0) { const severity = genetics.dpyd === 'deficient' ? 'critical' : 'high'; alerts.push({ id: `PGX-DPYD-${Date.now()}`, type: 'organ-function', severity, title: `DPYD Deficiency: ${affected.join(', ')}`, description: `Patient is DPYD ${genetics.dpyd}. High risk of severe/fatal toxicity with fluoropyrimidines.`, affectedDrugs: affected, recommendation: genetics.dpyd === 'deficient' ? 'Contraindicated. Use alternative therapy.' : 'Reduce dose by 50%. Consider alternative.', overridable: genetics.dpyd !== 'deficient', requiresDocumentation: true }); } } // UGT1A1 and irinotecan if (genetics.ugt1a1 === '*28/*28') { const irinotecan = drugs.filter(d => d.toLowerCase().includes('irinotecan')); if (irinotecan.length > 0) { alerts.push({ id: `PGX-UGT1A1-${Date.now()}`, type: 'organ-function', severity: 'high', title: `UGT1A1 Polymorphism: Irinotecan`, description: `Patient is UGT1A1*28/*28. Increased risk of severe neutropenia and diarrhea.`, affectedDrugs: irinotecan, recommendation: `Reduce initial dose by 1 level. Monitor closely.`, overridable: true, requiresDocumentation: true }); } } // TPMT and thiopurines if (genetics.tpmt && genetics.tpmt !== 'normal') { const thiopurines = ['azathioprine', '6-mercaptopurine', 'thioguanine']; const affected = drugs.filter(d => thiopurines.some(t => d.toLowerCase().includes(t))); if (affected.length > 0) { const severity = genetics.tpmt === 'poor' ? 'critical' : 'high'; alerts.push({ id: `PGX-TPMT-${Date.now()}`, type: 'organ-function', severity, title: `TPMT Deficiency: ${affected.join(', ')}`, description: `Patient is TPMT ${genetics.tpmt} metabolizer. Risk of severe myelosuppression.`, affectedDrugs: affected, recommendation: genetics.tpmt === 'poor' ? 'Reduce dose by 90% or use alternative.' : 'Reduce dose by 50%. Monitor CBC closely.', overridable: genetics.tpmt !== 'poor', requiresDocumentation: true }); } } return alerts; } /** * Get recommended alternatives for a contraindicated drug */ getAlternatives(drug: string, reason: string, patientProfile: PatientSafetyProfile): string[] { const alternatives: string[] = []; // Drug class-based alternatives const alternativeMap: Record = { // Chemotherapy 'cisplatin': ['carboplatin', 'oxaliplatin'], 'doxorubicin': ['liposomal doxorubicin', 'epirubicin'], 'ifosfamide': ['cyclophosphamide'], // Targeted therapy 'osimertinib': ['afatinib', 'erlotinib', 'gefitinib'], 'alectinib': ['brigatinib', 'lorlatinib', 'crizotinib'], // Immunotherapy (generally fewer direct alternatives) 'pembrolizumab': ['nivolumab', 'atezolizumab'], 'nivolumab': ['pembrolizumab', 'atezolizumab'], // Supportive care 'ondansetron': ['granisetron', 'palonosetron'], 'metoclopramide': ['prochlorperazine', 'promethazine'] }; const drugLower = drug.toLowerCase(); for (const [key, alts] of Object.entries(alternativeMap)) { if (drugLower.includes(key)) { alternatives.push(...alts); break; } } // Filter alternatives based on patient's contraindications return alternatives.filter(alt => { const interaction = this.findInteraction(alt, drug); if (interaction?.severity === 'contraindicated') return false; return true; }); } // ═══════════════════════════════════════════════════════════════════════════════ // HELPER METHODS // ═══════════════════════════════════════════════════════════════════════════════ private initializeDatabases(): void { // Initialize drug interactions (simplified - production would have comprehensive database) this.addInteraction({ drug1: 'pembrolizumab', drug2: 'corticosteroids', severity: 'moderate', type: 'pharmacodynamic', mechanism: 'High-dose corticosteroids may reduce immunotherapy efficacy', clinicalEffect: 'Reduced antitumor immune response', management: 'Use lowest effective steroid dose. Consider steroid-sparing agents for irAE management.', documentation: 'established' }); this.addInteraction({ drug1: 'warfarin', drug2: 'capecitabine', severity: 'major', type: 'pharmacokinetic', mechanism: 'Capecitabine inhibits CYP2C9, increasing warfarin effect', clinicalEffect: 'Increased INR and bleeding risk', management: 'Monitor INR closely. Consider LMWH alternative.', documentation: 'established' }); this.addInteraction({ drug1: 'osimertinib', drug2: 'strong cyp3a4 inducers', severity: 'major', type: 'pharmacokinetic', mechanism: 'CYP3A4 inducers decrease osimertinib exposure', clinicalEffect: 'Reduced efficacy', management: 'Avoid concomitant use with strong CYP3A4 inducers', documentation: 'established' }); // Initialize QT-prolonging drugs const qtDrugs = [ 'ondansetron', 'granisetron', 'haloperidol', 'droperidol', 'methadone', 'sotalol', 'amiodarone', 'dofetilide', 'ibutilide', 'quinidine', 'procainamide', 'disopyramide', 'arsenic trioxide', 'crizotinib', 'lapatinib', 'nilotinib', 'pazopanib', 'sunitinib', 'vandetanib', 'vemurafenib' ]; qtDrugs.forEach(d => this.qtProlongingDrugs.add(d.toLowerCase())); // Initialize black box warnings this.blackBoxWarnings.set('pembrolizumab', [ 'Immune-mediated adverse reactions can be severe and fatal', 'Monitor for immune-mediated pneumonitis, colitis, hepatitis, endocrinopathies, nephritis, and dermatologic reactions' ]); this.blackBoxWarnings.set('trastuzumab', [ 'Cardiomyopathy: Evaluate LVEF prior to and during treatment', 'Infusion reactions including fatal cases' ]); this.blackBoxWarnings.set('bevacizumab', [ 'Gastrointestinal perforation', 'Surgery and wound healing complications', 'Hemorrhage' ]); // Initialize allergy cross-reactivity this.allergenCrossReactivity.set('penicillin', ['amoxicillin', 'ampicillin', 'piperacillin', 'cephalosporins']); this.allergenCrossReactivity.set('sulfa', ['sulfamethoxazole', 'sulfasalazine', 'celecoxib', 'furosemide']); this.allergenCrossReactivity.set('platinum', ['cisplatin', 'carboplatin', 'oxaliplatin']); // Initialize dosing guidelines this.dosingGuidelines.set('carboplatin', [{ drug: 'carboplatin', indication: 'solid tumors', standardDose: 'AUC 5-6 (Calvert formula)', renalAdjustment: [ { gfrThreshold: 60, adjustment: 'Use Calvert formula with measured or estimated GFR' }, { gfrThreshold: 30, adjustment: 'Reduce target AUC. Consider nephrology consult' }, { gfrThreshold: 15, adjustment: 'Avoid or significant dose reduction' } ], weightBasedDosing: { formula: 'Dose (mg) = Target AUC × (GFR + 25)', maxDose: 'Cap GFR at 125 mL/min' } }]); this.dosingGuidelines.set('cisplatin', [{ drug: 'cisplatin', indication: 'solid tumors', standardDose: '75-100 mg/m²', renalAdjustment: [ { gfrThreshold: 60, adjustment: 'Standard dose with aggressive hydration' }, { gfrThreshold: 45, adjustment: 'Reduce dose 25-50%' }, { gfrThreshold: 30, adjustment: 'Avoid - use carboplatin alternative' } ] }]); } private addInteraction(interaction: DrugInteraction): void { const key1 = interaction.drug1.toLowerCase(); const key2 = interaction.drug2.toLowerCase(); if (!this.interactionDatabase.has(key1)) { this.interactionDatabase.set(key1, []); } if (!this.interactionDatabase.has(key2)) { this.interactionDatabase.set(key2, []); } this.interactionDatabase.get(key1)!.push(interaction); this.interactionDatabase.get(key2)!.push(interaction); } private findInteraction(drug1: string, drug2: string): DrugInteraction | null { const interactions = this.interactionDatabase.get(drug1.toLowerCase()); if (!interactions) return null; return interactions.find(i => i.drug2.toLowerCase() === drug2.toLowerCase() || i.drug1.toLowerCase() === drug2.toLowerCase() ) || null; } private mapInteractionSeverity(severity: DrugInteraction['severity']): SafetyAlert['severity'] { switch (severity) { case 'contraindicated': return 'critical'; case 'major': return 'high'; case 'moderate': return 'moderate'; case 'minor': return 'low'; } } private checkCrossReactivity(allergen: string, drug: string): AllergyCheck { const relatedAllergens = this.allergenCrossReactivity.get(allergen.toLowerCase()) || []; const crossReacts = relatedAllergens.some(a => drug.toLowerCase().includes(a)); let riskLevel: AllergyCheck['riskLevel'] = 'none'; if (crossReacts) { // Platinum cross-reactivity is high if (allergen.toLowerCase().includes('platinum')) { riskLevel = 'high'; } // Penicillin-cephalosporin is lower risk else if (allergen.toLowerCase().includes('penicillin') && drug.toLowerCase().includes('cephalosporin')) { riskLevel = 'low'; // ~2% cross-reactivity } else { riskLevel = 'moderate'; } } return { reportedAllergy: allergen, drugToCheck: drug, crossReactivity: crossReacts, riskLevel, relatedAllergens, recommendation: crossReacts ? `Consider alternative. If essential, administer with caution and monitor.` : `No known cross-reactivity. Standard precautions.` }; } /** * Generate a medication reconciliation report */ async generateMedicationReconciliation(patient: PatientSafetyProfile): Promise<{ currentMedications: string[]; interactions: DrugInteraction[]; recommendations: string[]; summary: string; }> { const currentMeds = patient.currentMedications.map(m => m.drug); const interactionAlerts = await this.checkDrugInteractions(currentMeds); const interactions: DrugInteraction[] = []; for (let i = 0; i < currentMeds.length; i++) { for (let j = i + 1; j < currentMeds.length; j++) { const int = this.findInteraction(currentMeds[i], currentMeds[j]); if (int) interactions.push(int); } } const recommendations: string[] = []; for (const int of interactions.filter(i => i.severity === 'major' || i.severity === 'contraindicated')) { recommendations.push(int.management); } return { currentMedications: currentMeds, interactions, recommendations, summary: interactions.length > 0 ? `Found ${interactions.length} drug interaction(s), including ${interactions.filter(i => i.severity === 'major' || i.severity === 'contraindicated').length} major interaction(s).` : 'No significant drug interactions identified.' }; } } export default DrugSafetyService;