ProductionHealthcareFull-stack web app12 min read

TB Module

Digital replacement of paper and Excel-based tuberculosis documentation at a primary care clinic.

Quick read

Tuberculosis risk-group registries, fluorography records, and case logs at Ukrainian primary care clinics are kept in Excel and on paper. In one of my clinics this meant 28 risk-group sheets, a fluorography file with ~1,100 patients per location (two locations), and a paper WHO 4-symptom screening questionnaire. I designed and built a web module that replaces this paper workflow: a structured patient registry with risk groups and TB status, fluorography history with auto-scheduled next-due dates, sputum test tracking, auto-generated referrals, and an EHR-side companion that surfaces the operational updates back into the registry. Adopted at the clinic where I practice. Runs on managed cloud infrastructure with a clear path to production-grade compliance when scaled.

Context

Tuberculosis surveillance at the primary care level in Ukraine requires layered documentation: risk-group registries (medical risk: COPD, HIV, diabetes, etc; social risk: prisoners, migrants, contacts of detected cases), fluorography history per patient with annual scheduling, sputum test results from regional labs (GeneXpert / microscopy / culture / PCR), separate logs for detected and contact cases, and a paper-based WHO 4-symptom screening questionnaire (form Appendix 9) administered at each contact.

In my clinic this stack was:

  • 14 risk-group Excel sheets × 2 clinic locations = 28 sheets
  • 2 detected/contact registries × 2 locations = 4 sheets
  • 1 fluorography file with ~1,100 patients per location
  • ~5 xlsx files total, plus a folder of MoH order PDFs
  • Paper Appendix 9 questionnaires, stored in a binder

Updating risk groups required cross-referencing several files. Generating referrals required hand-writing the WHO 4-symptom form. There was no audit trail. Migration risk on disk was real — these were operations-critical files held in Excel.

Solution

A web module that replaces the above workflow with structured records:

  • Patient registry with medical and social risk groups, TB status (none / detected / contact), location, and contact info — built from declaration exports via xlsx-diff
  • Fluorography history with auto-scheduled next-due dates and conclusion text storage (e.g., "Висновок: норма")
  • Sputum test tracking (GeneXpert / microscopy / culture / PCR), with the result types regional labs report
  • WHO 4-symptom screening at point-of-care: digital questionnaire, ML-free decision (low_risk / needs_xray / needs_referral), auto-generated PDF referral via window.print()
  • MoH order library linking to source documents
  • Declaration import — operator uploads the declaration export (xlsx), the module computes the diff against current registry, operator confirms
  • EHR-side companion — a helper that carries the operational updates the doctor already records in the EHR (diagnoses, fluorography results) across into the TB module, so the registry stays fresh without dual entry

Designed for single-practice use; access controlled by a shared practice authentication mechanism. Data handling follows internal clinical workflows established with the clinic management, and the operational registry stays within the team that uses the system day-to-day.

TB Module patient registry with risk groups and TB status
Patient registry view with risk groups and TB status.

Impact

The TB Module is too new for adoption metrics — the integrated flow (companion extension auto-syncing into the module) shipped recently. The TLDR-level claim is what the system did at deploy: eliminated the paper journal contour and collapsed 28+ Excel sheets into a single, queryable structure.

A separate observation worth naming: the architectural choices (managed Postgres, serverless functions, transactional email) were deliberately optimized for a small clinical deployment, where infrastructure overhead matters more than maximum theoretical scale. Path to production-grade compliance infrastructure (dedicated tenancy, BAA-eligible providers, formal DPA) is clear when the system scales beyond a single practice.

Adoption metrics will follow as the system accumulates more usage data.

Replacing paper with software is mostly a schema design problem.

What I learned

  • Replacing paper with software is mostly a schema design problem. The hardest part wasn't the UI or the database setup — it was deciding what to model. "Risk group" turns out to be a relationship, not an attribute. "Detected" and "contact" are statuses, not separate registries. Getting the data model right first meant the UI fell out cleanly.
  • Infrastructure economics for a small primary care clinic are forgiving. A practice at the scale of one outpatient clinic runs comfortably on managed cloud infrastructure priced within a small-clinic budget. For a clinic considering digitization, this matters more than any feature comparison — the budget barrier to entry is often the actual blocker.
  • Extending an existing tool is a legitimate integration strategy. I could have built a separate sync API and rewritten the data flow. Instead I extended the existing companion extension's display callback to feed the module passively. Result: ~900 LOC of glue, no changes to the core extension logic, automatic sync of any patient record the doctor opens.
  • A blocking overlay turned out to be the right UX answer for an indicator workflow doctors otherwise skipped. The companion extension originally required a button click to run the indicator analysis — 15-20 seconds of compute, but worse, a friction pause that broke flow. Doctors quietly stopped using it. When I integrated with the TB Module and made it mandatory to check the last X-ray date, I added a blocking overlay on the patient card: it appears as soon as the card opens, runs the indicator analysis automatically, syncs the X-ray date to the module, then drops away. Counter-intuitively this was better UX than the optional button: removing the choice removed the skip. The lesson generalises — in clinical workflows, "make it easy to use" is often weaker than "make it the default path."

Next steps

The active priority is extending the same pattern to the other journals that primary care has to maintain: vaccination, HIV, cardiovascular risk, oncology screening. The TB module already proves the architecture works — patient registry + scheduled events + EHR companion sync is a generalisable shape. Each new module needs its own schema and rules, but the underlying frame transfers.

Equally important is the path to production-grade infrastructure for multi-practice deployment: dedicated tenancy, formal data processing agreements, audit logging, role-based access controls. The current architecture is intentionally a single-clinic MVP; scaling beyond requires compliance investments that are well-understood but not yet implemented.

Read next