Cervical Cancer Screening CDS for OpenMRS
0.1.0 - ci-build International flag

Cervical Cancer Screening CDS for OpenMRS, published by Hopena Health. This guide is not an authorized publication; it is the continuous build for version 0.1.0 built by the FHIR (HL7® FHIR® Standard) CI Build. This version is based on the current content of https://github.com/dhes/cervical-cancer-cds/tree/main and changes regularly. See the Directory of published versions

Library: Cervical Cancer Screening Decision Logic (Experimental)

Official URL: https://hopenahealth.com/fhir/cervical-cancer-cds/Library/CervicalCancerScreeningDecision Version: 0.1.0
Draft as of 2026-04-21 Computable Name: CervicalCancerScreeningDecision
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

Parameters:
NameTypeMinMaxIn/Out
PatientPatient01Out
Meets Age Criteriaboolean01Out
Is Within Screening Age Rangeboolean01Out
Is Eligible For Screeningboolean01Out
Years Since Last HPV Testinteger01Out
Has Never Been Screenedboolean01Out
Screening Interval Has Elapsedboolean01Out
Is Due For Screeningboolean01Out
Most Recent HPV Test Is Negativeboolean01Out
Needs Triage After Positive HPVboolean01Out
Has Positive Triage Resultboolean01Out
Triage Was Negativeboolean01Out
Is In Post Treatment Follow Upboolean01Out
Recommended Actionstring01Out
Cascade Statusstring01Out
Screening Interval Displaystring01Out
Population Classificationstring01Out
Needs Attentionboolean01Out
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)