You know that moment when you discover a cool new app or game, only to hit a wall that says “Invite Only”? And then you spend the next hour scrolling through Reddit threads and Discord servers, hoping someone will drop a code before it gets snatched up by a bot?
That’s a broken system. The Buzzer is my attempt to fix it.
What It Actually Does
The Buzzer is a community-driven platform where people share invite codes for exclusive apps and games. But here’s the twist: instead of creating a chaotic free-for-all where the fastest clickers win, I built a First-Come-First-Served queue system that actually works.
Here’s the flow:
- Someone donates an invite code to the pool
- If codes are available, you claim one instantly
- If they’re gone, you join a queue
- When a new code arrives, the system automatically assigns it to the next person in line
- You get notified via email and in-app
No camping. No bots. No racing to refresh the page every five seconds.
The Technical Bits That Matter
I chose Supabase as the backbone because I didn’t want to spend three months building auth, database hosting, and edge functions from scratch. The platform handles all of that, plus it gave me:
- PostgreSQL with Row Level Security: Users can only touch their own data
- Database triggers: When a code gets submitted,
process_invite_queuefires automatically and assigns it to the next person in line - Edge Functions: Background jobs (like email processing) run on Deno at the edge
The frontend is Next.js 15 with the App Router, styled with Tailwind 4. I used TanStack Query for state management because watching network requests succeed or fail in real-time during development is oddly satisfying.
The Scarcity Problem
One challenge: how do you show “availability” without making the UI feel like a pressure cooker?
I added a Scarcity Bar—a visual indicator showing how many codes are available versus how many have been claimed. Apps get status badges:
- Locked: No codes, join the queue
- Low: A few left, act soon
- Live: Codes available, come and get one
It’s honest without being manipulative.
Security: The Unsexy Part That Matters
If unvalidated codes could enter the pool, they’d poison the entire queue system. Someone joins the queue, waits their turn, gets assigned a bad code, and now they’re stuck. Do they rejoin? Do they contact support? The whole point of automation breaks down.
So The Buzzer validates every invite code against app-specific regex patterns stored in the database. If someone tries to submit garbage, it gets rejected before it touches the pool. The queue only processes codes that match the expected format.
Sensitive operations—like viewing available codes or claiming invites—are wrapped in PostgreSQL functions with SECURITY DEFINER. This means users can’t just query the invites table directly and scrape codes. They have to go through controlled functions.
Anonymous users can submit codes (to lower friction), but they can’t claim them. That’s a deliberate trade-off: make it easy to contribute, but require commitment to take.
The Features I Actually Use
Admin Dashboard: Since users can submit new apps and games, there’s a moderation queue. I built a simple admin panel where I can approve submissions, edit metadata, and ban spam. It’s not glamorous, but it keeps the platform clean.
Profile System: Users earn reputation and credits based on their contributions. Right now it’s mostly just tracking, but the system’s set up so reputation could matter later—priority queue access, early feature testing, that kind of thing.
Screenshot Galleries: Apps can have multiple screenshots uploaded to Supabase Storage. This helps users decide if they actually want to join the queue for something.
What I’d Do Differently
The queue system initially didn’t enforce uniqueness. Same user could join the same app’s queue multiple times, which meant they could potentially get multiple codes for something they only needed once. The fix was simple—a database constraint—but I should have added it from day one.
The notification timing is still something I’m tweaking. Right now it’s immediate, which works, but I’m considering batching for users who join multiple queues at once to avoid email spam.
Lessons from the Trenches
Vertical Slice Architecture was a game-changer. Instead of organizing code by “components” and “services” and “utils,” I grouped everything by feature (/auth, /invites, /apps). When I need to touch the queue logic, everything I need is in /features/invites. No more hunting across five directories to change one thing.
Supabase’s RLS policies are both incredible and infuriating. They force you to think about security from day one, but debugging them feels like solving a riddle written in SQL. My advice: write RLS policies before you write the client code, not after.
TanStack Query’s caching saved my bacon. The app feels fast because it aggressively caches data and only re-fetches when necessary. Combined with Next.js’s App Router, pages load almost instantly.
Why This Project Exists
I wanted to try Raycast on Windows. Went to Reddit, found a codes thread, and spent 20 minutes copy-pasting codes that had already been claimed. Every single one: “Invalid.” By the time I found one that worked, I was more annoyed than excited.
The Buzzer started as a weekend hackathon project to solve that specific problem. No grand vision, just: what if codes were actually marked as claimed? What if there was a queue instead of a race?
It turned into a good excuse to play with Supabase’s queue system and learn how PostgreSQL triggers work in practice.
If you’ve ever refreshed a “Codes Available” thread 47 times in one evening, this one’s for you.