Portfolio
Original project · Open Source Data Product · UX/UI · Full-stack

The risk map that arrives before the rain

Chuvarada covers 28,483 Brazilian neighborhoods with real-time hydrological data — so evacuation happens before, not after.

Real-time data Hydrological risk Cartography Open Source Social impact

Type

Real project
Public product

Product

Web app (PWA)
2024–2025

Focus

Hydrological risk
at national scale

Method

Open data, weighted model,
IBGE centroid

Principle

Public data + product decisions
= real protection tool

The problem

The alert exists. The granularity doesn't.

Brazil has weather alert systems. What it lacks is neighborhood-level precision: Defesa Civil alerts are issued per municipality — and someone living on a hillside in Recife doesn't know if the risk is on their street or three neighborhoods away.

What exists

CEMADEN issues municipal alerts. Defesa Civil makes regional announcements. gov.br centralizes data but doesn't translate it for people on the ground.

What's missing

Neighborhood-level granularity, in real time, accessible to anyone on a mobile phone — no login, no installation, no technical jargon.

28,483

neighborhoods covered

With risk scores recalculated every hour using six public data sources.

Product principle

If the georeferenced point is wrong, the risk score is wrong too — and a wrong alert is worse than no alert.

The technical challenge (that became a product decision)

Brazil has no neighborhood centroids

The problem wasn't missing data — it was incompatible data. Brazil organizes its administration by districts, not neighborhoods. The IBGE 2022 Census mapped neighborhoods but without centroids for geocoding.

Without a centroid, there's no reliable way to associate a geographic point with a neighborhood. The standard solution (geometric center of the polygon) would place the representative point in uninhabited areas — hills, rivers, vacant land.

The solution

Population-weighted centroid using IBGE 2022 Census data. Each neighborhood's representative point falls where people actually live, not at the geometric center of the polygon.

Why this matters for the product

If the georeferenced point is wrong, the risk score for that neighborhood is also wrong. This was a product decision disguised as a technical problem — and the most important one in the project.

Geometric center versus population-weighted centroid Two diagrams of the same neighborhood. On the left, the polygon's geometric center falls in an uninhabited area, over the river. On the right, the population-weighted centroid falls where people actually live. GEOMETRIC CENTER OF THE POLYGON river Lands in the void — hill, river, empty ground. POPULATION-WEIGHTED CENTROID river Lands where people actually live.

The solution

Six sources. Seven variables. One number per neighborhood.

Chuvarada combines six free public data sources, updated automatically, to calculate each neighborhood's risk every hour.

SourceProviderWhat it delivers
MERGE/CPTECINPESatellite + rain gauge precipitation
Open-MeteoOpen-MeteoWind, humidity, pressure, hourly rain, soil moisture
NASA SRTMNASATerrain elevation (~30m resolution)
ANA/BHONational Water AgencyNational hydrographic network
IBGE 2022 CensusIBGENeighborhood mesh for all of Brazil
TideCheckUHSLC / FES2022Real tide level (113 of 115 coastal cities)

How the score is calculated

The seven variables are combined with weights defined by each one's relevance to flood risk:

VariableWeight
Rain peak (3h)22%
72h rainfall16%
Last-hour rainfall15%
Terrain slope14%
Soil moisture14%
Water proximity11%
Tide8%

Result

Score of 1 to 10, recalculated hourly, translated into five levels: Normal / Watch / Moderate / High / Critical.

Automatic Critical escalation rules

  • i. More than 50mm of rain in the last hour
  • ii. Tide above 80% combined with rain in a coastal area

The interface

From the model to a map anyone can read

The model returns a number. The interface's job is to make that number legible for someone on a hillside, on their phone, with no login and no jargon — and to communicate not just the risk, but why.

Chuvarada map zoomed into metropolitan São Paulo, showing flood risk colored neighborhood by neighborhood, from green to yellow, with a context footer showing rain and humidity.
Neighborhood-level granularity, made visible. Zoomed into São Paulo, the fine mesh of neighborhoods stands out against the municipality — the product's central thesis stops being an argument and becomes evidence. The gradient shows the trend; the footer carries the context (rain, humidity) of the observed point.
Chuvarada map showing all of Brazil, with a search field for city or neighborhood, a legend, layer and light/dark theme toggles, and a national status indicator.
National scale, one screen. Search by city or neighborhood, a legend of the five levels, layer toggle (rain/temperature) and theme, and a "How it works" shortcut. No install and no sign-up to reach the information.
A neighborhood card in Chuvarada: area name, Attention level, score 3.2, a timeline of coming hours and days with colored dots, and a list of risk factors (rain, soil moisture, terrain, water proximity) each with its weight and bar.

The neighborhood card is where design and model meet. Instead of hiding the calculation, it exposes each risk factor with the weight it carried in the score — soil moisture, terrain, water proximity, rain — and translates the raw data into interpretable language ("58% below the historical average for August"). Showing the reasoning, instead of handing over only the verdict, is what builds trust in whoever decides to evacuate.

Score + five levels

Number (1–10) and color together: legible for those who read by color and those who compare by value.

Timeline with uncertainty

Coming hours and days — and the interface warns that the forecast loses precision over time.

Transparent factors

Each model variable appears with its contribution. The weight stops being a technical detail and becomes information for the user.

Favorite the neighborhood

Follow where you live, or where your family is, with no account — the essentials on the phone, when it matters.

How it was built

Six sources, one score per hour, an app with no store

A nationwide product, built and maintained by one person. What makes it possible is a lean architecture and AI-assisted development.

Chuvarada architecture Six public data sources feed, every hour, a weighted model that computes the risk score for 28,483 neighborhoods; the data is stored in Supabase and served by a Next.js PWA with Leaflet, which shows the map and the neighborhood card. PUBLIC SOURCES INPE — MERGE/CPTEC Open-Meteo NASA SRTM ANA / BHO IBGE Census 2022 TideCheck PROCESSING · EVERY HOUR Hourly cron Weighted model7 variables · weights Score 1–10 per neighborhood28,483 neighborhoods DELIVERY Supabase PWA · Next.jsLeaflet.js Map + cardof the neighborhood

Stack

Next.js + TypeScript and Tailwind on the front end; Leaflet.js for cartography; Supabase as the database; continuous deploy on Vercel; installable PWA.

Pipeline

Every hour, the six public sources are consolidated and the weighted model recalculates the risk score for all 28,483 neighborhoods.

Method — Spec-Driven Development with AI

Built solo with Spec-Driven Development and Claude Code: the spec comes before the code, and AI speeds up implementation without taking the design and product decisions out of my hands. That's what lets one person ship — and maintain — a product this size.

Product decisions

What I left out — and why

Documenting what was cut, and why, is what holds each of the model's choices together.

Numeric scale, not traffic lights

Red/yellow/green collapses nuance. A score of 4.8 and one of 7.2 look identical on a traffic light but represent completely different risks. The 1–10 scale communicates trends and enables historical comparison.

Soil moisture as a variable (14%)

It's the most counterintuitive variable — and the most important in many scenarios. Light rain on saturated soil generates more flooding than heavy rain on dry soil. Dropping it for being hard to explain would trade precision for simplicity.

Neighborhood, not municipality

Municipal granularity already exists and doesn't solve the problem. The product only makes sense if the answer is more precise than what already exists. Neighborhood-level detail is the value proposition — without it, there's no product.

Community reports as validation, not primary source

Satellite data is accurate at scale; human reports are accurate locally. The model detects the event; the report confirms where it's impacting. Inverting this hierarchy would make the system easy to manipulate.

Honest limitations published on the platform

No urban drainage data (doesn't exist as public data in Brazil). Weights without formal regional calibration. São Paulo, Campinas and Sorocaba covered by districts, not neighborhoods. Publishing limitations doesn't weaken the product — it increases trust from decision-makers who rely on it.

Results

In production. Open source.

Coverage

28,483 neighborhoods covered

Updates

Score recalculated every hour

Data

6 public data sources integrated

Platform

Installable PWA — works like an app, no store

Access the project

View Chuvarada → Code on GitHub →

Articles published on Substack (PT) and Medium (EN).

Takeaway

Real-time data without product decisions is noise. Every model variable exists because there's a real user question behind it — “is my neighborhood at risk right now?” — and the answer needs to arrive before the question becomes too urgent.

The project's hardest technical problem (neighborhood centroids) was actually a product problem. If the geographic point is wrong, the score is wrong — and a wrong alert is worse than no alert.