healthcare-cdss-patterns
affaan-m/ecc
Clinical Decision Support System patterns: drug interactions, dose validation, and clinical scoring for EMR integration.
What is healthcare-cdss-patterns?
Patterns for building patient-safety-critical Clinical Decision Support Systems that integrate into EMR workflows. Provides pure-function libraries for drug interaction checking, dose validation, clinical scoring (NEWS2, qSOFA), and alert severity classification with zero tolerance for false negatives.
- Drug interaction checking against current medications and allergies with severity classification
- Dose validation accounting for weight, age, renal function, and route of administration
- Clinical scoring systems (NEWS2, qSOFA, APACHE, GCS) with risk stratification and escalation guidance
- Alert severity classification (critical, major, minor) with appropriate UI blocking behavior
- Pure function architecture with zero side effects for full testability
- Integration patterns for medication order entry and lab result interpretation in EMR workflows
How to install healthcare-cdss-patterns
npx skills add null --skill healthcare-cdss-patterns- Understanding of clinical pharmacology and drug interactions
- Familiarity with dose adjustment principles (weight-based, age-adjusted, renal-adjusted)
- Knowledge of clinical scoring systems (NEWS2, qSOFA) or access to clinical specifications
- EMR system with medication order entry and alert display capabilities
How to use healthcare-cdss-patterns
- 1.Install the skill and review the three primary modules: checkInteractions, validateDose, and calculateNEWS2
- 2.Populate your drug interaction database with bidirectional interaction pairs including severity, mechanism, and clinical effect
- 3.Define dose validation rules for each drug including weight-based limits, age brackets, renal adjustment thresholds, and absolute maximums
- 4.Implement the NEWS2 scoring function using Royal College of Physicians specification tables
- 5.Integrate CDSS functions into your EMR UI: critical alerts block actions with non-dismissable modals, major alerts require acknowledgment, minor alerts display as inline notes
- 6.Configure audit logging to capture all override reasons when clinicians bypass critical alerts
- 7.Write comprehensive test suites with 100% pass rate, including bidirectional interaction detection and missing-data blocking scenarios
Use cases
- Implementing medication order entry with real-time safety checks before prescription
- Detecting drug-drug interactions and cross-reactive allergies during medication reconciliation
- Validating pediatric and renal-adjusted doses based on patient demographics
- Calculating National Early Warning Score 2 from vital signs to trigger escalation protocols
- Building alert systems that block critical safety issues while allowing minor warnings to proceed
- EMR/EHR developers integrating clinical safety modules
- Healthcare software engineers building medication management systems
- Clinical informaticists designing decision support workflows
- Hospital IT teams implementing CDSS at scale
- Developers working on patient safety-critical healthcare applications
healthcare-cdss-patterns FAQ
The validator BLOCKS the dose with a 'weight_missing' factor and returns valid: false. This is intentional—missing safety-critical data must never silently pass.
Yes, required. If Drug A interacts with Drug B, then Drug B must also be detected as interacting with Drug A. Both directions must be tested.
Critical alerts must be non-dismissable modals that block the action entirely. They must never be toast notifications or auto-dismissed. Clinicians must document an override reason in the audit trail to proceed.
The skill provides NEWS2 (National Early Warning Score 2) as a primary example. The pattern supports other systems like qSOFA, APACHE, and GCS using the same pure-function architecture.
Zero tolerance for false negatives. Test pass rate must be 100%. A single missed interaction or undetected safety issue is a patient safety event.
Full instructions (SKILL.md)
Source of truth, from affaan-m/ecc.
name: healthcare-cdss-patterns description: Clinical Decision Support System (CDSS) development patterns. Drug interaction checking, dose validation, clinical scoring (NEWS2, qSOFA), alert severity classification, and integration into EMR workflows. metadata: origin: Health1 Super Speciality Hospitals — contributed by Dr. Keyur Patel version: "1.0.0"
Healthcare CDSS Development Patterns
Patterns for building Clinical Decision Support Systems that integrate into EMR workflows. CDSS modules are patient safety critical — zero tolerance for false negatives.
When to Use
- Implementing drug interaction checking
- Building dose validation engines
- Implementing clinical scoring systems (NEWS2, qSOFA, APACHE, GCS)
- Designing alert systems for abnormal clinical values
- Building medication order entry with safety checks
- Integrating lab result interpretation with clinical context
How It Works
The CDSS engine is a pure function library with zero side effects. Input clinical data, output alerts. This makes it fully testable.
Three primary modules:
checkInteractions(newDrug, currentMeds, allergies)— Checks a new drug against current medications and known allergies. Returns severity-sortedInteractionAlert[]. UsesDrugInteractionPairdata model.validateDose(drug, dose, route, weight, age, renalFunction)— Validates a prescribed dose against weight-based, age-adjusted, and renal-adjusted rules. ReturnsDoseValidationResult.calculateNEWS2(vitals)— National Early Warning Score 2 fromNEWS2Input. ReturnsNEWS2Resultwith total score, risk level, and escalation guidance.
EMR UI
↓ (user enters data)
CDSS Engine (pure functions, no side effects)
├── Drug Interaction Checker
├── Dose Validator
├── Clinical Scoring (NEWS2, qSOFA, etc.)
└── Alert Classifier
↓ (returns alerts)
EMR UI (displays alerts inline, blocks if critical)
Drug Interaction Checking
interface DrugInteractionPair {
drugA: string; // generic name
drugB: string; // generic name
severity: 'critical' | 'major' | 'minor';
mechanism: string;
clinicalEffect: string;
recommendation: string;
}
function checkInteractions(
newDrug: string,
currentMedications: string[],
allergyList: string[]
): InteractionAlert[] {
if (!newDrug) return [];
const alerts: InteractionAlert[] = [];
for (const current of currentMedications) {
const interaction = findInteraction(newDrug, current);
if (interaction) {
alerts.push({ severity: interaction.severity, pair: [newDrug, current],
message: interaction.clinicalEffect, recommendation: interaction.recommendation });
}
}
for (const allergy of allergyList) {
if (isCrossReactive(newDrug, allergy)) {
alerts.push({ severity: 'critical', pair: [newDrug, allergy],
message: `Cross-reactivity with documented allergy: ${allergy}`,
recommendation: 'Do not prescribe without allergy consultation' });
}
}
return alerts.sort((a, b) => severityOrder(a.severity) - severityOrder(b.severity));
}
Interaction pairs must be bidirectional: if Drug A interacts with Drug B, then Drug B interacts with Drug A.
Dose Validation
interface DoseValidationResult {
valid: boolean;
message: string;
suggestedRange: { min: number; max: number; unit: string } | null;
factors: string[];
}
function validateDose(
drug: string,
dose: number,
route: 'oral' | 'iv' | 'im' | 'sc' | 'topical',
patientWeight?: number,
patientAge?: number,
renalFunction?: number
): DoseValidationResult {
const rules = getDoseRules(drug, route);
if (!rules) return { valid: true, message: 'No validation rules available', suggestedRange: null, factors: [] };
const factors: string[] = [];
// SAFETY: if rules require weight but weight missing, BLOCK (not pass)
if (rules.weightBased) {
if (!patientWeight || patientWeight <= 0) {
return { valid: false, message: `Weight required for ${drug} (mg/kg drug)`,
suggestedRange: null, factors: ['weight_missing'] };
}
factors.push('weight');
const maxDose = rules.maxPerKg * patientWeight;
if (dose > maxDose) {
return { valid: false, message: `Dose exceeds max for ${patientWeight}kg`,
suggestedRange: { min: rules.minPerKg * patientWeight, max: maxDose, unit: rules.unit }, factors };
}
}
// Age-based adjustment (when rules define age brackets and age is provided)
if (rules.ageAdjusted && patientAge !== undefined) {
factors.push('age');
const ageMax = rules.getAgeAdjustedMax(patientAge);
if (dose > ageMax) {
return { valid: false, message: `Exceeds age-adjusted max for ${patientAge}yr`,
suggestedRange: { min: rules.typicalMin, max: ageMax, unit: rules.unit }, factors };
}
}
// Renal adjustment (when rules define eGFR brackets and eGFR is provided)
if (rules.renalAdjusted && renalFunction !== undefined) {
factors.push('renal');
const renalMax = rules.getRenalAdjustedMax(renalFunction);
if (dose > renalMax) {
return { valid: false, message: `Exceeds renal-adjusted max for eGFR ${renalFunction}`,
suggestedRange: { min: rules.typicalMin, max: renalMax, unit: rules.unit }, factors };
}
}
// Absolute max
if (dose > rules.absoluteMax) {
return { valid: false, message: `Exceeds absolute max ${rules.absoluteMax}${rules.unit}`,
suggestedRange: { min: rules.typicalMin, max: rules.absoluteMax, unit: rules.unit },
factors: [...factors, 'absolute_max'] };
}
return { valid: true, message: 'Within range',
suggestedRange: { min: rules.typicalMin, max: rules.typicalMax, unit: rules.unit }, factors };
}
Clinical Scoring: NEWS2
interface NEWS2Input {
respiratoryRate: number; oxygenSaturation: number; supplementalOxygen: boolean;
temperature: number; systolicBP: number; heartRate: number;
consciousness: 'alert' | 'voice' | 'pain' | 'unresponsive';
}
interface NEWS2Result {
total: number; // 0-20
risk: 'low' | 'low-medium' | 'medium' | 'high';
components: Record<string, number>;
escalation: string;
}
Scoring tables must match the Royal College of Physicians specification exactly.
Alert Severity and UI Behavior
| Severity | UI Behavior | Clinician Action Required |
|---|---|---|
| Critical | Block action. Non-dismissable modal. Red. | Must document override reason to proceed |
| Major | Warning banner inline. Orange. | Must acknowledge before proceeding |
| Minor | Info note inline. Yellow. | Awareness only, no action required |
Critical alerts must NEVER be auto-dismissed or implemented as toast notifications. Override reasons must be stored in the audit trail.
Testing CDSS (Zero Tolerance for False Negatives)
describe('CDSS — Patient Safety', () => {
INTERACTION_PAIRS.forEach(({ drugA, drugB, severity }) => {
it(`detects ${drugA} + ${drugB} (${severity})`, () => {
const alerts = checkInteractions(drugA, [drugB], []);
expect(alerts.length).toBeGreaterThan(0);
expect(alerts[0].severity).toBe(severity);
});
it(`detects ${drugB} + ${drugA} (reverse)`, () => {
const alerts = checkInteractions(drugB, [drugA], []);
expect(alerts.length).toBeGreaterThan(0);
});
});
it('blocks mg/kg drug when weight is missing', () => {
const result = validateDose('gentamicin', 300, 'iv');
expect(result.valid).toBe(false);
expect(result.factors).toContain('weight_missing');
});
it('handles malformed drug data gracefully', () => {
expect(() => checkInteractions('', [], [])).not.toThrow();
});
});
Pass criteria: 100%. A single missed interaction is a patient safety event.
Anti-Patterns
- Making CDSS checks optional or skippable without documented reason
- Implementing interaction checks as toast notifications
- Using
anytypes for drug or clinical data - Hardcoding interaction pairs instead of using a maintainable data structure
- Silently catching errors in CDSS engine (must surface failures loudly)
- Skipping weight-based validation when weight is not available (must block, not pass)
Examples
Example 1: Drug Interaction Check
const alerts = checkInteractions('warfarin', ['aspirin', 'metformin'], ['penicillin']);
// [{ severity: 'critical', pair: ['warfarin', 'aspirin'],
// message: 'Increased bleeding risk', recommendation: 'Avoid combination' }]
Example 2: Dose Validation
const ok = validateDose('paracetamol', 1000, 'oral', 70, 45);
// { valid: true, suggestedRange: { min: 500, max: 4000, unit: 'mg' } }
const bad = validateDose('paracetamol', 5000, 'oral', 70, 45);
// { valid: false, message: 'Exceeds absolute max 4000mg' }
const noWeight = validateDose('gentamicin', 300, 'iv');
// { valid: false, factors: ['weight_missing'] }
Example 3: NEWS2 Scoring
const result = calculateNEWS2({
respiratoryRate: 24, oxygenSaturation: 93, supplementalOxygen: true,
temperature: 38.5, systolicBP: 100, heartRate: 110, consciousness: 'voice'
});
// { total: 13, risk: 'high', escalation: 'Urgent clinical review. Consider ICU.' }
Related skills
More from affaan-m/ecc and the wider catalog.
healthcare-emr-patterns
EMR/EHR development patterns with clinical safety, encounter workflows, and accessibility-first design.
healthcare-eval-harness
Patient safety verification harness for healthcare deployments with automated CDSS, PHI, and data integrity testing.
healthcare-phi-compliance
PHI/PII compliance patterns for healthcare applications—data classification, access control, audit trails, and leak prevention.
hermes-imports
Convert Hermes workflows into sanitized, reusable ECC skills without leaking credentials or private state.
hexagonal-architecture
Design domain-centric systems with clear boundaries, dependency inversion, and testable use-case orchestration.
hipaa-compliance
HIPAA-specific entrypoint for healthcare privacy and security work.