The Prize Hunt
A prize competition platform with instant wins.

Overview
A prize competition platform where users buy tickets for a chance to win, with instant wins revealed at the point of purchase. Built end to end as the sole engineer for a startup client.
Accounts and authentication, competition listings with countdowns and bulk pricing, a basket, wallet funded purchases, randomised ticket allocation, instant win prizes and payouts, transactional emails, and an admin dashboard for running competitions.
The client is now live on RaffleX rather than on this platform. I recommended the move, set their site up there, wrote the custom code it needed, and handled branding, domains and mailing lists. That call is covered in the decisions below.
Stack
- Next.js
- React
- TypeScript
- Tailwind CSS
- Radix UI
- Zustand
- Prisma
- Zod
- PostgreSQL
- Supabase
- JWT
- Resend
- React Email
Decisions
Allocating tickets under concurrent load
Two people buying the last tickets at the same moment must never get the same number. Tickets are selected in raw SQL that locks the rows it takes and skips any that another transaction is already holding, picking at random from the rest. The wallet debit, the ticket assignment and the purchase record all run in one transaction, so a purchase either completes fully or not at all.
Instant wins decided before the competition opens
Each instant win is attached to a specific ticket number when the competition is created, rather than rolled when someone buys. Buying that ticket reveals a result that was already set. Prizes cannot be changed mid competition, but every outcome is fixed in advance and can be checked afterwards, which matters when people are paying for a chance to win.
Buying instead of building
The platform was taking too long and the client needed to be selling. RaffleX already did what I was building, for a monthly fee that barely registers, plus a few pence on every sale. I recommended it, moved them across, and they launched months earlier than finishing the custom build would have allowed. It also meant their site did not end up depending on one person to keep it running.