A private, invite-only RSVP app for a recurring home poker game — magic-link login, auto-waitlist, live table talk — running on a fully serverless stack for $0/month.
The hero diagram of the set — a real five-system production app, with the parts a dev shop would charge for marked out.
The interactive data-flow diagram is built for a larger screen.
Open the full diagram in its own tab ↗
Kill the group-text RSVP scramble for a recurring home poker game. One private place where the regulars log in, see who is in, claim or release a seat, get auto-waitlisted when the game is full, and talk per game — all synced to the Airtable base the group already ran on. The deeper why: prove a non-developer can ship a real, production, multi-system web app end to end with AI.
Players log in by magic link, no passwords. Authorization is gated server-side on an Airtable access checkbox — you are in only if you are a known player and access has been granted. Once in, you RSVP against a capacity limit; a full game auto-waitlists you and auto-promotes the next person in line, by timestamp, the moment someone drops. The app shows a live roster, a per-game Table Talk thread, direct messages between players who have actually shared a game, and one unified real-time notification feed. A host console manages games, capacity, RSVP windows and day-of check-in. Airtable stays the system of record for everything reservation-related; ephemeral data — comments, DMs, sessions, notifications — lives in Cloudflare D1, and the real-time layer runs on Durable Objects. Transactional email goes out through Resend.
Real-time through the adapter. Cloudflare Durable Objects are the WebSocket layer behind live chat, DMs and notifications, and getting them to export and run through the OpenNext adapter for Next.js is not a documented happy path. It needed a custom Worker entry that re-exports the Durable Object class and intercepts WebSocket upgrades, de-risked with a throwaway echo room before the real notification and DM rooms were built on top of it.
Auth and authz, split clean. Authentication — Auth.js plus Resend proving you own the email address — is deliberately separate from authorization, which is server code reading Airtable to ask two questions: are you a known player, and has access been granted? Every rule runs server-side. The browser renders and relays; it never decides. Revoking someone is one unchecked box in Airtable.
No-lock concurrency guard. Rather than real locking, the RSVP route re-reads the live Going count from Airtable at click time. At 30 seats that is enough — a rare tie just waitlists one extra person. A conscious "simple beats robust" call, not a shortcut.
Poker Night ships with a built-in Learn tutorial — a walkthrough of how to actually play, at poker.drost.us/learn. It's ungated: anyone can open it and learn the game without an invite or a login. Because it sits outside the access wall, it's the one piece of this project I can share freely — a public front door to an otherwise private app.