Secret Santa
Every year, organizing Secret Santa is the same hassle. Drawing names, making sure couples don't get each other, sending individual messages. I went looking for tools to automate it and found a graveyard of ad-ridden websites that looked like they hadn't been updated since 2005. The ones that weren't ugly charged money for basic features like exclusions, or required everyone to create accounts. I just wanted to set up a game, add some constraints, share links, and be done with it.
JWTs
The first version was a pure SPA. All the data lived in JWTs embedded in URLs — the organizer would set up participants and constraints, the app would generate assignments, and each person would get a unique link with their assignment encoded in the token.
It worked for small groups, but the tokens got long fast. The more participants and exclusions you added, the longer the URLs grew. My extended family's exchange produced URLs that would wrap in messaging apps, get truncated, or just look suspicious enough that people wouldn't click them. The tokens also contained all the assignment data, so if someone shared their link publicly, the whole game's structure was visible to anyone who bothered to decode it.
The second version added a backend. A Lambda function with DynamoDB stores the game data. URLs are short nanoid identifiers now, and links can be regenerated if someone loses theirs.
Constraints
The interesting problem is constraint satisfaction. People specify who can't give to whom — typically partners or family members. The algorithm needs to find a valid assignment that respects all constraints while ensuring everyone gives to exactly one person and receives from exactly one person.
The AI implemented a randomized backtracking algorithm. It shuffles participants, attempts assignments, and backtracks when it hits a dead end. For typical group sizes it finds a solution instantly. I haven't tested what happens with adversarial constraint sets, but I suspect it would just fail gracefully.
The monorepo
This came together quickly because my monorepo already has shared configs and deployment patterns. I've been building it out over time, and at this point spinning up a new mini-project doesn't require much setup. The AI follows the patterns already in the codebase, so I describe what I want and review what it produces.
The app also supports English and Spanish via i18next. Setting up i18n is tedious but it's a solved problem — the AI just did it.
The whole thing deploys via Pulumi. The Lambda publishes as a function URL, the frontend goes to Amplify. Use it at santa.reb.nz for your next gift exchange.