← All builds

product · solo build · 2026

Keeping track of every coffee chat, without sharing a thing.

Sign in and keep a list of the people you meet: company, role, where you met, notes, and priority. Sort, filter, and search it. Every row is private to the person who wrote it, and the database enforces that, not just the app.

Role Builder · Team Solo · Timeline September 2026

The problem

At Berkeley you meet a lot of people quickly, and notes on them end up scattered. A tool for that has to answer one question before any other: can anyone else see my contacts?

What I did

  • Built sign-up, sign-in, and a contact list with create, edit, delete, sort, filter, and search, in Next.js on Vercel.
  • Stored contacts in Neon Postgres and isolated them with row-level security in the database, so even a direct call to the public Data API can't read someone else's rows.
  • Proved it. Queried as the role the API uses while two rows existed, and got zero back.
  • Validated input three times: in the form, on the server, and with a database constraint. The friendly message is a courtesy, not the defense.
  • Designed all four list states: loading skeletons, two distinct empty states, a plain-language error with one-click retry, and success.
  • Captured every screenshot in the write-up from the deployed app, not localhost.

Results

0rows visible to the wrong user
3layers of input validation
4list states designed
15screenshots from the live app

What I'd do differently

Check the security boundary on every push. The isolation test needs two real accounts and a live database, so today it runs on demand. Next: run it in CI against a throwaway database branch that seeds its own accounts.

Artifacts

Try it ↗ · Source on GitHub ↗

An empty name, rejected with the reason in plain language. Demo data.
An empty name, rejected with the reason in plain language. Demo data.
The contact list on a phone. Demo data.
The contact list on a phone. Demo data.
Live preview Open in new tab ↗