Inspiration

I'm a mechanical engineering student, and I built this with a chemical engineering friend — we both taught ourselves software and AI/ML development because we wanted to build things that actually solve problems around us. When we read OneAquaHealth's own research — pharmaceuticals detected in 91% of monitored urban stream sites, and diatom deformities showing up as early-warning signs of contamination that standard monitoring misses entirely — it reframed the problem for us. Citizen science apps already exist to collect water observations, including OneAquaHealth's own. The gap isn't data collection. It's that ordinary citizens don't always know which signs are scientifically meaningful, and even good citizen data often stays trapped in app-specific formats that never reach the standardized systems public health actually runs on. We wanted to build the layer that closes that gap.

What it does

Riparia is a validation middleware that sits behind citizen-science reporting. A citizen submits a photo and description of a stream. An AI model assesses it against real, published OneAquaHealth indicators — riparian vegetation loss, artificial light at night, visible contamination signs — and returns not just a verdict but a confidence score and a plain-language explanation of what it saw and why it matters. A human reviewer then sees that full reasoning and decides whether to approve or reject it. Nothing is ever committed automatically. Only on approval does the observation get mapped into a standards-compliant HL7 FHIR Observation resource — the same data format real health systems use — making it something a municipality or public-health researcher could actually act on, not just another entry in a proprietary database.

How we built it

The backend is Python/FastAPI, backed by PostgreSQL. Citizen submissions go through an upload-sanitization step (content-type verification, EXIF/GPS stripping for privacy) before being sent to a Gemini vision model prompted specifically against OneAquaHealth's own indicators rather than generic pollution language. Approved observations are mapped into FHIR resources and posted to a FHIR server. The reviewer console is session-authenticated with CSRF protection, since giving anyone with a URL the power to approve or reject observations was never acceptable. The whole stack is deployed on Render via a version-controlled Blueprint, with photo storage on Cloudflare R2.

We reviewed and tested every architectural decision, security requirement, and piece of research grounding ourselves — running the full pipeline end-to-end, checking the actual deploy logs rather than trusting a green checkmark, and verifying every research claim against OneAquaHealth's real published findings before it went anywhere near the submission.

Challenges we ran into

The biggest one: we initially tried to self-host a HAPI FHIR server as a second Render service so we'd fully control uptime for the demo, instead of depending on a public test server. It looked fine in local testing, but in production it crashed on boot with an OutOfMemoryError — HAPI's FHIR server is a full Java/Spring Boot application that needs more memory than Render's free tier provides, just to load the FHIR specification into memory before serving a single request. We made the call to fall back to the public HAPI test server for the live demo rather than burn the remaining time fighting a resource ceiling we couldn't remove. We'd rather ship something that reliably works than something ambitious that might not.

We also had to catch and fix a real security mistake along the way — we'd temporarily hardcoded our Gemini API key directly into a config file to get things working quickly, then caught it before committing and moved it into proper environment-variable handling instead.

Accomplishments that we're proud of

Getting the AI's reasoning to be genuinely explainable, not just a black-box confidence score, so a human reviewer has something real to evaluate. Getting real FHIR interoperability working end-to-end, not an invented JSON shape pretending to be a standard. And catching our own security and infrastructure mistakes before they became demo-day failures, rather than after.

What we learned

That grounding an AI project in a domain's actual published research — rather than assumptions about what the problem probably is — changes what you build. We also learned to treat nothing as done until we'd verified it ourselves: testing every endpoint directly instead of trusting a status report, and catching a real memory-limit failure by reading the actual crash logs rather than assuming a deploy that looked finished actually was.

What's next

Self-hosting a properly resourced FHIR server so the pipeline doesn't depend on a public test instance. Multi-reviewer accounts with role-based access, since the current build supports one reviewer by design for the hackathon scope. And working with OneAquaHealth's team directly to see whether the validation layer could plug into their existing Citizen Science App rather than staying a standalone demo.

Share this project:

Updates

Submission history