A Monday morning at the lake
It rained all weekend in Ghent. On Monday morning the sun is out, and Blaarmeersen lake looks perfect: a family spreads a towel by the water, children run for the shallows, a dog bounds in after a stick.
Nothing about the water looks different. But overnight, the rain has washed sewage into the lake, and the bacteria are climbing. A lab sample will confirm it, a day or two later. By then, the swim has already happened.
Aheadwater exists so that the warning comes first.
It is an early-warning and response system for city lakes and rivers. It forecasts unsafe water a day ahead, alerts the right people at once, and follows every case until the water is safe again.
The problem, in numbers
That Monday is not one city's story. Unsafe water, sanitation and hygiene cost 1.4 million lives worldwide in 2019, about 498,000 in India and more than 33,000 across Europe (WHO).
City water changes fast. A storm pushes sewage into a lake overnight. A heatwave brings algae and drains the oxygen. Floods and spills arrive without warning. Today a city usually finds out from a lab sample, and that result comes back a day or more later, after people have already been in the water. When a problem is found, the water team, public health, labs, vets and volunteers each hear about it in a different place, at a different time.
The gap is not a lack of data. It is a lack of one shared, early picture.
What it does: six steps, one shared case
Predict. A model trained on 150,734 bathing-water samples from 7,246 lakes and rivers in 27 countries reads the weather before each day and scores every site for tomorrow. Weather rules watch for algae blooms, low oxygen and sewer overflow, and work in any city from day one.
Detect. The forecast, lab results, hazard rules and reports from people at the water arrive in one officer console. A citizen's photo is checked on their own phone for light, focus and open water before it is sent.
Verify. Each case gets a trust score from the sources behind it. Two sources must agree before anything goes public.
Act. The city's water officer owns the case. Public health and local vets are told at once, with the population cohorts living near the water. If the owner has not acknowledged within 30 minutes, the case reaches their supervisor. After two hours with no action, nearby verified labs, groups and volunteers can claim it.
Resolve. The team closes the case with evidence, and the public page shows every step, from the first warning to the all-clear.
Learn. A closed case with a dated lab sample becomes a new labelled example, so each city's forecast keeps getting sharper.
The officer console, the responder view and the public page share one live case: open them side by side and watch a single click update all three.
Proven on a real day
That Monday really happened. On the morning of 17 May 2021, after a wet weekend in Ghent, Aheadwater rated Blaarmeersen lake at 5.5 times its usual risk. The lab sample taken that day came back over the limit. The model behind that score had never seen a single Ghent sample.
Across Europe, on sites the model never saw in training, its alerts are right ten times more often than chance (1 in 5, against 1 in 50; ROC-AUC 0.79), and it holds up on a later year (trained on 2020 to 2023, tested on 2024: ROC-AUC 0.77).
The same workflow replays a second real event in Bengaluru: after the heaviest August rain in 127 years (as reported by NDTV), foam from Varthur Lake spilled onto the road on 16 August 2017. A citizen report and the Central Pollution Control Board's monitoring open the case, and the same code carries it through.
How it is built
- Model. LightGBM in Python on EEA bathing-water samples and E-OBS weather. Every feature uses only data from before the sample day, and testing is grouped by site, so each score is earned on places the model has never seen. The trained trees are exported to JSON and scored inside the web app, with a test that checks the app's scores match Python's.
- App. Next.js on Vercel, with a live map (Leaflet, OpenStreetMap), today's forecast from Open-Meteo, and motion throughout. The escalation clock, trust score and hazard rules are pure functions with their own tests.
- Photo check. Brightness and sharpness are measured in the reporter's browser, and MobileNet looks for open water. The photo never leaves the device.
- Quality. 30 web tests and 4 Python tests: model parity, features, escalation, FHIR, hazards, photo checks and trust.
Built on the OneAquaHealth standard
Every step of a case is an HL7 FHIR R4 resource: the lake as a Location, the risk score and lab results as Observations, the nearby population as Group cohorts on the OneAquaHealth profiles, and the response as DetectedIssue, Task, CareTeam and Communication. I built the OneAquaHealth profiles from the guide's source and checked three full incident bundles with the official HL7 validator: 0 errors. The app serves them at a read-only FHIR endpoint, and its health page reads real Oslo cohorts live from the OneAquaHealth sandbox.
Impact
A day's head start. A warning arrives the morning the risk rises, while the lab is still at work.
One picture for everyone. Water, animals and people are looked after together: the water team, public health, vets, responders and the public see the same case at the same moment.
Help arrives even when someone is busy. The escalation clock makes sure every case is picked up.
Health systems can read it directly. Because every step is FHIR on the OneAquaHealth guide, a hospital or a lab can use a case without a custom integration.
Ready for the next city. The workflow, the rules and the records are the same code everywhere. A new city starts on reports and lab results on day one, and its forecast grows with every closed case.
Back at the lake
Run the same Monday again. At dawn, the forecast flags Blaarmeersen. A swimmer's photo of cloudy water agrees. By breakfast, the public page says avoid contact, keep dogs out, the volunteer wardens 400 metres away are on site, public health knows which neighbourhoods to watch, and the local vets know what to look for. The family picks a different beach. The dog chases its stick on the grass. When the follow-up sample comes back clean, the all-clear goes up for everyone at once.
Nothing dramatic happens. That is the point.
What comes next
Live sensors and city lab feeds flowing straight into the console, a trained forecast for every hazard as local data grows, the incident and citizen-report profiles offered back to the OneAquaHealth guide, and the next cities onboarded on the same code.
Built With
- computervision
- javascript
- next.js
- oneaquahealth
- pandas
- react
- scikit-learn
- tailwind
- typescript

Log in or sign up for Devpost to join the conversation.