Hello CHT Community 
I want to share a real challenge we face when running health campaigns using CHT, and propose a better way to handle it.
What is the Problem?
Imagine your program is running a malaria prevention campaign. This campaign:
-
Only covers some regions, not all
-
Within those regions, only targets specific Community Health Units (CHUs) — not every one of them
-
Runs between a specific start and end date
-
Should only be done by Community Health Workers (CHWs), not supervisors
Simple enough, right? But here is what actually happens in CHT today to make this work.
How It Works Today (and Why It Hurts)
Right now, to activate a campaign for specific CHUs and a specific date range, a developer has to open the source code, manually type in the IDs of the CHUs, type in the start and end dates, and then deploy the entire application to push the change live. It looks something like this under the hood:
// A developer has to write/change this code every single time
const CAMPAIGN_CHUS = ['chu_id_001', 'chu_id_002', 'chu_id_008', ...];
const CAMPAIGN_START = new Date('2025-10-01');
const CAMPAIGN_END = new Date('2025-11-30');
That may sound like a small thing, but consider a national or regional program with:
-
20 campaigns running at the same time — malaria, nutrition, immunization catch-up, WASH, etc.
-
Each campaign covering different CHUs across different areas
-
Campaign dates shifting constantly based on updated disease data
-
New CHUs or other adaptable parameters being added mid-campaign as scope expands
Every single one of those changes — even just moving an end date by one week, or adding one CHU — requires a developer to change code, run a deployment tool, and push the update live. This means:
-
Program officers cannot adjust campaigns themselves — they always need a developer
-
Every change risks breaking something else in the app if a mistake slips in
-
Rolling back a mistake means another full code deployment
-
With 20 campaigns, the technical team is doing 10–20 code deployments per quarter just for routine operational adjustments — not actual feature work.
Take it lightly: This is like needing a software engineer every time you want to update a spreadsheet.
What We Are Proposing
Campaign parameters — who, where, and when — should be manageable as simple settings, not code. Program officers or system administrators should be able to:
-
Set the start and end date of a campaign
-
Choose which CHUs or facilities are in scope
-
Turn a campaign on or off with a single switch
-
Change the scope mid-campaign (add/remove CHUs) without touching any code
-
etc
When a CHW opens the CHT app, the system automatically checks this configuration and shows campaign tasks only to the right workers in the right places during the right period — no code change needed.
Why This Matters
-
Program staff stay in control. No more waiting for a developer to change a date or add a facility.
-
Zero risk of breaking the app. Because you are changing settings, not code, a mistake is easy to undo — just update the setting.
-
Easy rollback. If a campaign was activated by mistake or needs to stop early, you flip a switch. Done.
-
Scales to any number of campaigns. Managing 20 campaigns becomes as straightforward as managing 2.
-
Less developer time wasted on operational tasks. Developers can focus on actual improvements, not re-deploying because an end date shifted by a week.
A Real Example
A program operating across multiple regions has:
-
Dozens of CHUs spread across several administrative areas
-
Hundreds of CHWs on the ground
-
3–5 campaigns running at the same time
-
Campaign scopes that shift periodically based on updated data from DHIS2 or the MOH
Today, their technical team fields requests like “Can you add CHU X to the malaria campaign? They have just been confirmed in scope.” — which triggers a code change, a build, and a full deployment. This should be a two-minute admin task, not a development ticket.
What Would Change Under the Hood (for the Developers in the Room)
-
A
campaignsblock added toapp_settings.json— similar to how roles, hierarchies, and transitions are already configured there -
The CHT API (
cht.v1) gets acampaignshelper so task/target logic can simply ask “is this contact in an active campaign?” without any hardcoded values -
cht-confgets support for managing campaigns as modular config files -
Optionally, a campaign management screen in the admin panel for non-technical program staff
Questions for the Community
-
Is anyone else dealing with this pain today? How are you currently managing multiple simultaneous campaigns?
-
Has anyone built a workaround — like storing campaign config in a CouchDB document? How did that hold up in practice?
-
Would a simpler first step — just adding date-windowed feature flags to
app_settingsthat tasks can read — already solve most of your problems?
Would love to hear how others are handling this. I believe this would make CHT significantly more practical for any program running multiple overlapping campaigns across different areas.
Thank you for reading!
cc: @Karim_K_Kanji @AdrianO @Emmanuel_Barasa @andra @diana @antony