← funsho cornelius
case study 03 — realtime Q&A · solo full-stack

Rhema BTC

A live classroom Q&A portal used in a real venue — four screens, one reactive data source, and the fairness rules a room full of students will always try to break. Built and deployed solo, front to back.

role
Solo full-stack — frontend, backend, auth, deploy
frontend
TanStack Start + Router · React 19 · Tailwind v4
backend
Convex reactive · jose + bcrypt auth · Vitest
surfaces
Student · instructor · projector · admin

Four surfaces, one truth.

Studentmobile · qr join
Rhema student view showing the live question feed
Instructorconsole
Rhema instructor console showing student questions
Projectorroom display
Rhema projector view displaying a vote-sorted question
Admincampus · super-admin
Rhema admin dashboard with session controls and QR codes

The best questions in a full room never get asked.

Shy students stay quiet, loud ones dominate, and the instructor can't tell what most people actually want answered. The fix needed a projector view the whole room sees, an instructor console to drive it, and a student view with no sign-up friction — all showing the same thing at the same instant, live.

What a live room actually throws at you.

—

Four surfaces, always in agreement. Student, instructor, projector, and admin views must never disagree about what's on screen — even for a second.

—

Students will try to game it. Double-voting, voting for themselves, spamming questions — fairness had to be guaranteed by the server, not trusted to the client.

—

No accounts for students. Asking a room to sign up would kill participation — identity had to be anonymous but still one-vote-per-person.

Let the database push, and enforce every rule server-side.

// one reactive source
Four surfaces off the same Convex queries

Every view subscribes to the same Convex reactive queries — the backend pushes changes to all of them. No socket wiring, no manual refetching, no cache to keep in sync. The data source is the sync.

// server-enforced fairness
Invariants the client can't override

One open session per campus, one projected question, one question per student, no self-voting or double-voting, and cron auto-close — all enforced in the backend where they can't be faked.

// anonymous identity
No accounts, still one vote each

Students join by QR into a UUID-based anonymous identity — zero sign-up friction, while the server still ties one vote and one question to each person.

// production auth
Real auth for staff

Dual-token JWT with silent refresh, bcrypt hashing in a Convex node action, httpOnly SameSite=Strict cookies, route guards, and campus vs super-admin roles.

// exports
Take the session with you

Instructors export the full Q&A to Excel or PowerPoint, and generate a QR join-poster for the room.

The whole thing — frontend, reactive backend, auth, and deploy — was built and shipped solo.

Making four screens agree without wiring them together.

The obvious build is sockets: broadcast every change to every client and reconcile on each end. That's a lot of plumbing — and four chances for the projector to lag behind the instructor. Instead I leaned on Convex's reactive queries as the source of truth: each surface simply subscribes to the state it cares about, and the backend recomputes and pushes when anything changes.

That decision collapsed a class of bugs before they existed. There's no client cache to invalidate and no socket reconnect logic — consistency is a property of the data layer, so the projector and the instructor are looking at the same query result by construction.

Used live, in a real venue — and it just kept up.

Students joined by QR, the top questions rose on the projector as votes landed, and the instructor ran the whole session from one console. Fairness held under a room actively testing it, and every session archived itself to Excel and PowerPoint. A complete solo build — frontend, reactive backend, auth, and deployment.

4
live surfaces off one reactive source
0
sockets wired or caches to invalidate
Solo
full-stack build, front to back
TanStack StartTanStack RouterReact 19Convexjose (JWT)bcryptTailwind v4VitestVercel
back to →
All work
01 — Pikkam ↗