docs/methodology/disease-alert-level.mdx
The "Disease Outbreaks" panel labels each item with one of three categorical levels: ALERT, WARNING, or WATCH. This page documents how that label is derived so the value is reproducible from the inputs displayed on the panel.
Levels are assigned by a keyword classifier in
scripts/_disease-outbreaks-helpers.mjs::detectAlertLevel that matches
whole-word tokens (case-insensitive) in the concatenated item title and
description.
| Level | Keywords (any match) |
|---|---|
alert | outbreak, emergency, epidemic, pandemic |
warning | warning, spread, cases increasing |
watch | (fallback when no keyword matches) |
The keyword set is editorial — it is not derived from a published classification index (ECDC, WHO EWARN, ProMED). Treat the level as an opinionated newsroom triage signal, not a clinical assessment.
The classifier sees the item's title and desc fields after they are
normalized by the per-source parser:
whoNormalizeItem)rssNormalizeItem)tghNormalizeItem)There are no numeric scoring weights. The label is purely categorical and
the order shown in the panel is alert > warning > watch.
alert even if the situation
is minor. Conversely, a serious situation reported without any of the
keywords will fall through to watch.outbreak and be promoted to alert.These limitations are accepted for now because the source feeds are predominantly English-language press releases and the panel is positioned as a "what to look at next" surface rather than a risk score.
If the keyword sets in DISEASE_ALERT_KEYWORDS or DISEASE_WARNING_KEYWORDS
change:
ALERT_LEVEL_METHODOLOGY_VERSION in the same file. The seeder
stamps this onto the published payload as alertLevelMethodologyVersion,
so a bump observably propagates to clients and the canonical key.tests/disease-outbreaks-seed.test.mjs covering
the new keyword behavior + at least one expected non-match (substring
guard).scripts/_disease-outbreaks-helpers.mjs → detectAlertLevelsrc/components/DiseaseOutbreaksPanel.tstests/disease-outbreaks-seed.test.mjs