Web · 2024–25
Quiz Tournament Platform
Three roles (admin, host, participant), JWT-secured Spring Boot services, PostgreSQL, and a React frontend. Tournament state is the interesting part — synchronising participant scores across rounds without races and without a websocket layer.

The problem
Build a multi-role tournament platform: admins set up tournaments, hosts run rounds in real time, participants answer questions and watch the leaderboard update. The hard part is tournament state — when a host advances a round, every participant's screen should reflect the new round, scores should reconcile correctly, and concurrent submissions can't double-count.
Approach
Spring Boot microservices on the backend with JWT auth and role-based access control (admin, host, participant). PostgreSQL for tournaments, rounds, questions, and submissions — relational because the foreign keys matter and the consistency guarantees matter more than horizontal scale.
React on the frontend, deployed to Vercel. Rather than reaching for websockets, I used a polling strategy with a server-side round version number — clients poll the round endpoint, and the response carries a version that the client compares against the last seen version. State changes propagate within the polling interval (~1s) without the operational cost of a websocket layer.
Key decisions
JWT with role-claims, not session cookies
JWT made the three-role permissioning trivially expressible (role claim in the token, single check at each endpoint) and kept the backend stateless. For a workload this size, session cookies would have added a Redis dependency for no real gain.
Polling over websockets
Websockets are right for chat and live-cursors. For a tournament that advances every 30+ seconds, a 1-second poll feels live and ships in a fraction of the time. The server returns 304 if no change, so the cost is a header round-trip per second per active client.
Frontend / backend in separate repos
Separate repos kept the deployment story clean — Vercel for the frontend, a different host for the Spring service — and made it easier to teach the project to other students who only wanted to look at one side.
Outcome
Live on Vercel. Three working roles end-to-end. State synchronisation works under simulated concurrent participants without race conditions or double-counting.