ROF
Full-stack platform for managing university clubs
A full-stack platform where club execs create clubs, register and verify members, and track engagement — and students join and manage their memberships. Built T3-stack (Next.js, tRPC, Prisma, Postgres), with each feature owned end-to-end from UI to API to database, and shipped live on Vercel.
9 pages shipped
role-based auth
live on Vercel
Stack
Next.js · TypeScript · tRPC · Prisma · PostgreSQL (Neon) · NextAuth · UploadThing · Tailwind

the problem
University clubs run on scattered Excel sheets and Google Forms that fall apart when leadership graduates — with no single place to register members, verify them, and hand the whole club off intact.
how it works
Two roles share one system. Club execs create a club, register and verify members (custom ID checks, email confirmation, and double-registration prevention), and track engagement through a membership dashboard and an analytics view of enrollment trends and demographics — plus an event scheduler. Students sign in, verify their registration, and manage which clubs they've joined. It's 9 pages in all, gated by role-based access control.

full-stack, per feature
We built on the T3 stack — Next.js, tRPC, Prisma, and Postgres (Neon) — so a change to the database schema surfaces as a type error in the UI before it can ship broken. Rather than splitting into frontend and backend people, each of us owned whole features end-to-end: the React UI, the tRPC API routes, and the schema behind them. Auth runs on NextAuth, file uploads on UploadThing, and the whole thing deploys to Vercel.
built for the handoff
The real workflow isn't the day-to-day — it's May, when leadership graduates and two years of muscle memory walks out the door. Every feature was scored against one question: *does this make next year's exec team better off?* Structured member data, verified rosters, and a live dashboard mean a club can be handed off intact instead of rebuilt from scratch.
more



key decisions
T3 for end-to-end type safety
Next.js + tRPC + Prisma meant a change to the Postgres schema showed up as a type error in the UI. A 3-person team shipped 9 pages in a semester without an API contract silently drifting.
Own features, not layers
Instead of a frontend person and a backend person, each of us owned whole features — UI, tRPC routes, and schema. Fewer handoffs, faster iteration, clearer ownership.
A roster you can trust
Custom ID verification, email confirmation, and double-registration prevention — because a membership list is only useful if it's real.
outcomes
- Shipped to production on Vercel — adopted by the Blockchain at McGill leadership team
- 9 pages, 5 fully database-backed, with role-based access control
- Each feature owned end-to-end: React UI → tRPC API → Prisma → Postgres
- Integrated NextAuth (auth), UploadThing (uploads), and Neon (Postgres)
up next
BCI Decoder
Offline CSP + LDA decoder for a motor-imagery cursor BCI