Title: Cervical Cancer Screening Decision Logic Id: CervicalCancerScreeningDecision Version: 0.1.0 Url: Cervical Cancer Screening Decision Logic Status: draft Experimental: true Type: system: http://terminology.hl7.org/CodeSystem/library-type code: logic-library Date: 2026-04-21 19:55:49+0000 Publisher: Hopena Health Jurisdiction: 001 Related Artifacts: Dependencies Cervical Cancer Screening Common Definitions version: 0.1.0 Parameters: Name Type Min Max In/Out Patient Patient 0 1 Out Meets Age Criteria boolean 0 1 Out Is Within Screening Age Range boolean 0 1 Out Is Eligible For Screening boolean 0 1 Out Years Since Last HPV Test integer 0 1 Out Has Never Been Screened boolean 0 1 Out Screening Interval Has Elapsed boolean 0 1 Out Is Due For Screening boolean 0 1 Out Most Recent HPV Test Is Negative boolean 0 1 Out Needs Triage After Positive HPV boolean 0 1 Out Has Positive Triage Result boolean 0 1 Out Triage Was Negative boolean 0 1 Out Is In Post Treatment Follow Up boolean 0 1 Out Recommended Action string 0 1 Out Cascade Status string 0 1 Out Screening Interval Display string 0 1 Out Population Classification string 0 1 Out Needs Attention boolean 0 1 Out Content: text/cql /* * CervicalCancerScreeningDecision * * Screening eligibility and scheduling logic for cervical cancer CDS, * implementing WHO guideline Algorithm 5 (HPV DNA + VIA triage). * * This library determines: * - Whether a patient is eligible for cervical cancer screening * - Whether screening is currently due * - The patient's current position in the screening cascade * - The recommended next action * * WHO Recommendations covered: * General population: 1, 2, 5, 6, 7, 8, 14 * WLHIV: 21, 22, 25, 26, 27, 28, 34 * * @author Dan Heslinga / Hopena Health * @version 0.1.0 * @date 2026-03-08 */ library CervicalCancerScreeningDecision version '0.1.0' using FHIR version '4.0.1' include FHIRHelpers version '4.0.1' include CervicalCancerScreeningCommon version '0.1.0' called Common /* * ============================================================================= * SCREENING ELIGIBILITY * ============================================================================= * * @guidance WHO Rec 5 (general): Start at age 30 * WHO Rec 25 (WLHIV): Start at age 25 * WHO Rec 6/26: Stop after age 50 with adequate prior screening * WHO Rec 7/27: Prioritize ages 30-49 (general) / 25-49 (WLHIV) */ context Patient /* * @output Boolean — true if patient meets basic demographic criteria * @pseudocode Patient is female AND age >= minimum screening age */ define "Meets Age Criteria": Common."Is Female" and Common."Age In Years" >= Common."Minimum Screening Age" /* * @output Boolean — true if patient is within the target screening age range * @pseudocode Patient age <= maximum screening age (50) */ define "Is Within Screening Age Range": Common."Age In Years" <= Common."Maximum Screening Age" /* * @output Boolean — true if patient is eligible for cervical cancer screening * @pseudocode Patient is female, meets age criteria, no cervical cancer diagnosis * @guidance Patients with known cervical cancer should be managed through * oncology, not the screening pathway. */ define "Is Eligible For Screening": "Meets Age Criteria" and not Common."Has Cervical Cancer Diagnosis" /* * ============================================================================= * SCREENING DUE DETERMINATION * ============================================================================= * * @guidance WHO Rec 8 (general): Every 5-10 years with HPV DNA * WHO Rec 28 (WLHIV): Every 3-5 years with HPV DNA * Using lower bound (most conservative) for "due" calculation */ /* * @output Integer — years since most recent HPV DNA test, or null if never screened */ define "Years Since Last HPV Test": if Common."Has Ever Been Screened With HPV" then years between Common."Date Of Most Recent HPV Test" and Today() else null /* * @output Boolean — true if patient has never been screened with HPV DNA */ define "Has Never Been Screened": not Common."Has Ever Been Screened With HPV" /* * @output Boolean — true if screening interval has elapsed since last HPV test * @pseudocode Years since last test >= screening interval for this population */ define "Screening Interval Has Elapsed": Common."Has Ever Been Screened With HPV" and "Years Since Last HPV Test" >= Common."Screening Interval Years" /* * @output Boolean — true if patient is due for routine screening * @pseudocode Patient is eligible AND (never screened OR interval elapsed) */ define "Is Due For Screening": "Is Eligible For Screening" and ("Has Never Been Screened" or "Screening Interval Has Elapsed") /* * ============================================================================= * CASCADE POSITION — Where is the patient in the screening pathway? * ============================================================================= * * Algorithm 5 cascade: * 1. Not yet screened → Screen * 2. HPV negative, interval not elapsed → Routine recall * 3. HPV negative, interval elapsed → Re-screen * 4. HPV positive, no VIA yet → Needs VIA triage * 5. HPV positive, VIA negative → Follow-up retest (12/24 months) * 6. HPV positive, VIA positive → Needs treatment * 7. Treated → Post-treatment follow-up * 8. Cervical cancer → Refer to oncology * * This library determines cascade position; downstream libraries * (TriageDecision, TreatmentDecision, FollowUpDecision) handle * the detailed logic for positions 4-7. */ /* * @output Boolean — true if most recent HPV test was negative */ define "Most Recent HPV Test Is Negative": Common."Has Ever Been Screened With HPV" and not Common."Most Recent HPV Test Is Positive" /* * @output Boolean — true if patient has a positive HPV result that * has not yet been followed up with VIA triage * @pseudocode HPV+ AND (no VIA result OR most recent VIA is before the HPV test) */ define "Needs Triage After Positive HPV": Common."Most Recent HPV Test Is Positive" and ( not exists(Common."VIA Screening Results") or Common."Date Of Most Recent VIA" before Common."Date Of Most Recent HPV Test" ) /* * @output Boolean — true if HPV+ and VIA triage was positive (needs treatment) * @pseudocode HPV+ AND VIA+ AND VIA was after HPV test */ define "Has Positive Triage Result": Common."Most Recent HPV Test Is Positive" and Common."Most Recent VIA Is Positive" and Common."Date Of Most Recent VIA" on or after Common."Date Of Most Recent HPV Test" /* * @output Boolean — true if HPV+ but VIA triage was negative (needs follow-up retest) * @pseudocode HPV+ AND VIA- AND VIA was after HPV test */ define "Triage Was Negative": Common."Most Recent HPV Test Is Positive" and not Common."Most Recent VIA Is Positive" and Common."Date Of Most Recent VIA" on or after Common."Date Of Most Recent HPV Test" /* * @output Boolean — true if patient is in post-treatment follow-up window * @pseudocode Patient has been treated AND months since treatment < 24 * (covers both 12-month and 12+12-month WLHIV windows) */ define "Is In Post Treatment Follow Up": Common."Has Been Treated" and Common."Months Since Treatment" is not null and Common."Months Since Treatment" < 24 /* * ============================================================================= * RECOMMENDED ACTION — Clinician-facing guidance * ============================================================================= * * @guidance These are the primary outputs consumed by CDS hooks / alerts. * Each returns a human-readable recommendation string. */ /* * @output String — the recommended next action for this patient * @pseudocode Decision tree based on cascade position */ define "Recommended Action": case // Exclusion: cervical cancer diagnosed when Common."Has Cervical Cancer Diagnosis" then 'Refer to oncology for cervical cancer management' // Not eligible (wrong sex or too young) when not "Meets Age Criteria" then 'Not yet eligible for cervical cancer screening' // Post-treatment follow-up in progress when "Is In Post Treatment Follow Up" then 'Post-treatment follow-up: retest with HPV DNA at 12 months post-treatment' // HPV+ needs VIA triage when "Needs Triage After Positive HPV" then 'HPV test is positive — perform VIA triage' // HPV+ VIA+ needs treatment when "Has Positive Triage Result" then 'HPV-positive and VIA-positive — assess ablation eligibility and treat' // HPV+ VIA- needs follow-up retest when "Triage Was Negative" then 'HPV-positive but VIA-negative — retest with HPV DNA in ' + ToString(Common."Post Triage Negative Retest Months") + ' months' // Never screened and eligible when "Has Never Been Screened" and "Is Eligible For Screening" then 'Screen with HPV DNA test' // Interval elapsed and eligible when "Screening Interval Has Elapsed" and "Is Eligible For Screening" then 'Routine re-screening due — screen with HPV DNA test' // HPV negative, not yet due when "Most Recent HPV Test Is Negative" and not "Screening Interval Has Elapsed" then 'Last HPV test was negative — next screening due in ' + ToString(Common."Screening Interval Years" - "Years Since Last HPV Test") + ' years' // Over age 50 — evaluate for cessation when Common."Age In Years" > Common."Maximum Screening Age" then 'Age over 50 — assess for screening cessation (requires 2 consecutive negative HPV tests)' else 'Unable to determine recommendation — review patient data' end /* * @output String — coded cascade position for downstream logic * @pseudocode Returns a machine-readable status for integration */ define "Cascade Status": case when Common."Has Cervical Cancer Diagnosis" then 'cervical-cancer' when not "Meets Age Criteria" then 'not-eligible' when "Is In Post Treatment Follow Up" then 'post-treatment-follow-up' when "Needs Triage After Positive HPV" then 'needs-triage' when "Has Positive Triage Result" then 'needs-treatment' when "Triage Was Negative" then 'triage-negative-follow-up' when "Has Never Been Screened" and "Is Eligible For Screening" then 'due-for-screening' when "Screening Interval Has Elapsed" and "Is Eligible For Screening" then 'due-for-screening' when "Most Recent HPV Test Is Negative" then 'routine-recall' when Common."Age In Years" > Common."Maximum Screening Age" then 'assess-cessation' else 'unknown' end /* * ============================================================================= * SCREENING INTERVAL DISPLAY — For clinician-facing display * ============================================================================= */ /* * @output String — human-readable screening interval for this patient */ define "Screening Interval Display": if Common."Is WLHIV" then '3-5 years (WLHIV)' else '5-10 years (general population)' /* * @output String — human-readable population classification */ define "Population Classification": if Common."Is WLHIV" then 'Woman living with HIV (WLHIV) — WHO Recommendations 21-34' else 'General population — WHO Recommendations 1-14' /* * ============================================================================= * SUMMARY OUTPUTS — Structured data for CDS integration * ============================================================================= */ /* * @output Boolean — overall flag: does this patient need clinical attention? * @pseudocode True if any action is recommended (screening, triage, treatment, follow-up) */ define "Needs Attention": "Is Due For Screening" or "Needs Triage After Positive HPV" or "Has Positive Triage Result" or "Is In Post Treatment Follow Up" or Common."Has Cervical Cancer Diagnosis" Content: application/elm+json Encoded data (66632 characters)
Cervical Cancer Screening Decision Logic