Skip to content

Full-stack

reagiraj.ba: a lung cancer risk check for the EU LIFEGATE project

More than 2,300 completed assessments in the first weeks after launch: a lung cancer risk check for SKB Mostar and the EU LIFEGATE project, built with React, Node.js and MongoDB.

Client
SKB Mostar (University Clinical Hospital Mostar), within the EU Interreg IPA project LIFEGATE
Delivered by
ANODA
Year
2026
Role
Technical partner for the web application (activity A1.2): platform, admin panel and analytics
Product language
Bosnian / Croatian
React (SPA)Node.js / Express APIMongoDB AtlasAdmin dashboardGTMGA4
reagiraj.ba landing page ('Zdravlje pluća') in a browser window, with a phone showing a moderate risk result
Interreg IPA Croatia, Bosnia and Herzegovina, Montenegro; Co-funded by the European Union; LIFEGATE

Developed within the LIFEGATE project, co-funded by the European Union through the Interreg VI-A IPA Croatia, Bosnia and Herzegovina, Montenegro 2021 to 2027 programme.

At a glance

ClientSKB Mostar (University Clinical Hospital Mostar)
ProgrammeInterreg VI-A IPA Croatia, Bosnia and Herzegovina, Montenegro 2021 to 2027, co-funded by the European Union
ProjectLIFEGATE (HR-BA-ME00489)
My roleTechnical partner for the web application (activity A1.2): platform, admin panel and analytics.
TimelineDevelopment December 2025 to May 2026, public launch on 11 August 2026
PlatformPublic web app, API and admin panel
UsersThe general public, designed with older users in mind; the hospital team in the admin
StatusLive

The problem

Lung cancer is often found late, when treatment options are limited. The LIFEGATE project needed a simple public tool that helps people understand their own risk and encourages those at higher risk to see a doctor, across a region where many of the people who need it most are older and not used to online forms.

User journey

Free, anonymous and about two minutes long. Every step was designed with older users in mind: large answer cards, short steps and plain language.

  1. 1
    Landing: What the check is, how long it takes, and that it is anonymous.

    Landing

    What the check is, how long it takes, and that it is anonymous.

  2. 2
    Basic data: Age, canton, city, weight and height (BMI is calculated automatically), personal and family history.

    Basic data

    Age, canton, city, weight and height (BMI is calculated automatically), personal and family history.

  3. 3
    Smoking and symptoms: Smoking status, years and cigarettes per day (pack-years are calculated), symptoms and lung disease.

    Smoking and symptoms

    Smoking status, years and cigarettes per day (pack-years are calculated), symptoms and lung disease.

  4. 4
    Environment: Living environment and occupational exposure, such as asbestos.

    Environment

    Living environment and occupational exposure, such as asbestos.

  5. 5
    Result: A risk level with a clear recommendation and the detected factors.

    Result

    A risk level with a clear recommendation and the detected factors.

  6. 6
    Where to go: People at higher risk get the nearest pulmology referral location for their area and a referral code to verify at the institution.

    Where to go

    People at higher risk get the nearest pulmology referral location for their area and a referral code to verify at the institution.

Screenshots from production. Answers are non-personal samples and nothing was submitted. Clinical point weights and doctors' details are hidden.

The scoring algorithm

The model was defined together with the clinical experts on the project; my job was to implement it exactly, test it against edge cases and keep it explainable.

Answers
Alarming symptoms?
Yes ↓

Symptomatic / urgent: clinical assessment needed

A safety rule, not a screening score. Coughing up blood, or several serious symptoms at once.

No ↓

Additive screening score

Points across domains: age, smoking (status and pack-years), lung disease, family history of lung cancer, personal history of cancer, asbestos, other occupational exposure, living environment, passive smoking.

Booster check

20 or more pack-years plus at least one strong amplifier (asbestos, COPD, first-degree family history, or previous cancer) means at least High.

LowModerateHigh
LevelScoreRecommendation
Low0 to 7 pointsEducation, quitting smoking, no routine screening
Moderate8 to 15 pointsConsider a chest X-ray, with AI support where available, and/or low-dose CT according to guidelines and individual risk
High16 points or moreScreening with X-ray plus AI and low-dose CT, and a pulmology examination
UrgentAlarming symptomsClinical assessment needed, regardless of the score

Pack-years

Pack-years = (cigarettes per day ÷ 20) × years smoked

One pack a day for 20 years is 20 pack-years, and so is two packs a day for 10 years. The app calculates it from the answers, so nobody has to do the maths.

Architecture

Browser

React single-page app at reagiraj.ba

Admin panel

admin.reagiraj.ba, cookie-based authentication

API

Node.js and Express at api.reagiraj.ba

Database

MongoDB Atlas

Analytics

GTM and GA4, in the browser only

The risk level never leaves the app

Data model

Field groupExamplesWhy it exists
DemographicsGender, age, canton, cityRisk factors and geographic analytics for the hospital team
Body measurements and BMIWeight, height, calculated BMIShown in the result and used in the analytics
Smoking and pack-yearsStatus, years, cigarettes per day, calculated pack-yearsThe strongest risk factor in the model
Symptoms and historySymptoms, lung disease, personal and family historySafety override and screening score
ExposureLiving environment, asbestos, occupational exposureEnvironmental and occupational risk factors
ResultScore, level, detected factors, recommendationWhat the person sees, and what the clinic can verify
ReferralReferral codeVerifying results at the institution
PrivacyIP address hash, excluded-from-analytics flagAbuse protection without storing IP addresses, and clean statistics without test submissions

Translations are managed in the admin, so the hospital team can change wording without a release. Consent is handled with Google Consent Mode: Cookiebot can be switched on from the admin, with a built-in consent banner as the default.

Admin panel

The hospital team works in an admin panel with five sections: Dashboard, Analytics, Applications, Translations and Settings. The analytics views cover demographics, geographic breakdown, risk distribution, cross-factor analysis and the daily trend.

Illustration, sample data

Completed

1,234

Today

56

High or urgent

28%

Risk distribution

  • Low: 38%
  • Moderate: 34%
  • High: 21%
  • Urgent: 7%

By canton

  • Canton A
  • Canton B
  • Canton C
  • Canton D

Daily trend

Measurement with care

Because this is a health tool, I designed the analytics around one rule: nothing about a person's health may leave the app.

DecisionWhy
Risk level is never sent to analyticsGA4 knows that an assessment was completed, never what the result was
Steps are tracked from the app's code, not from the page HTMLA single-page app without URL changes needs events pushed from code
IP addresses are stored only as a hashAbuse protection without keeping personal data
Test submissions can be excludedStatistics stay clean for the hospital team and the project reports
No advertising profilesNothing about a person's health is shared with any third party.

Results

Figures from the project reports of 27 August and 10 September 2026.

  • 2,300+

    completed assessments in the first weeks after launch

  • ~30%

    assessed as high or urgent risk

  • 11,000+

    visits

Timeline
  1. Dec 2025Development starts
  2. May 2026Platform delivered
  3. Jul 2026Analytics and privacy review
  4. 11 Aug 2026Public launch
  5. Sep 20262,300+ completed assessments

What I learned

  • Implementing a clinical model means implementing it exactly and testably: every rule covered by edge-case tests, and every result explainable to the person who gets it.
  • Analytics around health data has to be designed from day one. Deciding what must never be tracked is as important as deciding what to measure.
  • Single-page app tracking needs hooks in the code, not CSS selectors. The app knows which step a person is on; the DOM does not.

Stack

LayerTechnology
FrontendReact single-page app
APINode.js and Express
DatabaseMongoDB Atlas
AdminReact admin panel with cookie-based authentication
AnalyticsGoogle Tag Manager, GA4, Google Consent Mode

Like what you see?
Let us talk about your project.