EEEddieEzekiel
All posts

8 July 2026

Building Usalama Voice

Case study · Usalama Voice · Next.js · Supabase

Building Usalama Voice

Usalama Voice is the most important thing I have built so far, and it has humbled me more than anything else I've worked on. It is a platform for responding to gender-based violence in Kenya. At the moment it is being readied for a pilot, so I'd like to write down how I approached it while it is still fresh.

Why It Exists

When someone in Kenya reaches out after an assault, help does exist. The trouble is that it sits in separate places. Each service, whether a police station or a shelter, keeps its own records. A survivor tells their story to one person and is referred to another, where they have to start over. Every handoff is a chance for the case to fall apart, and it tends to happen when the person has the least energy left to repeat themselves.

Usalama Voice keeps the case connected, from the first call for help through to recovery. Everyone involved works from the same record.

The Panic Button

The panic button cost me the most sleep. It has to work when someone taps it once, quickly, possibly on a cheap phone with one bar of signal.

A normal web request assumes the network is there, and I couldn't assume that here. The app installs as a PWA and uses Background Sync. An alert raised offline is queued on the device and sent the moment a connection returns. It captures location and can record audio, and none of that depends on the person staying on the page.

Nobody is ever going to admire a panic button. If it failed even once, though, the rest of the platform would hardly matter, which is why it got more of my attention than anything else.

Privacy

Every role on the platform sees a different slice of the data. A counsellor should never see a shelter operator's full view, and a survivor's evidence should never leak sideways.

I leaned on row-level security in Postgres, which puts the access rules in the database itself. Rules kept only in the front end are far too easy to get wrong. There is a public side too, the Mwananchi portal, and it only ever shows anonymised trends. The principle I kept coming back to is that private data should be hard to reach even by accident.

Not everyone has a smartphone or data, and a tool like this quietly fails the people who don't. Africa's Talking lets the system reach them by SMS, so it isn't tied to one expensive device.

The Stack

It runs on Next.js, installable as a PWA so that it behaves offline. Supabase and Postgres hold the data and handle sign-in, with the access rules in the database. Upstash Redis rate-limits the sensitive endpoints, since a panic and notification system is exactly the sort of thing someone might abuse. Email goes through Resend and SMS through Africa's Talking. Vercel hosts the lot. I picked each one to close a specific gap, and fashion didn't come into it much.

Where It Is Now

The pilot is the honest and slightly terrifying stage where real people start using it and tell you what you got wrong. I expect a long list. I'd be more worried if I didn't get one.

Building it has changed how I think about my work. It is easy to care about software when the stakes are a smoother checkout. When the person on the other side is having the worst day of their life, it becomes another matter entirely, and I find I'd much rather ship something small that holds up.

Fin