Community cinema over SMS · In development
Back to the Big Screen
A monthly neighbourhood movie night you join by sending one text — pick a seat, pay what you can, get a check-in code.
Role: Concept, identity, flow design, and direction of the agents that wrote it.
Timeline: Built 2026 — awaiting carrier registration and film rights
- Kinds of information tracked
- 22
- Things it can do
- 35
- Files of code
- 61
Distinct record types in the data model, from counting the table definitions in the schema file. Counted on 21 September 2026.
Separate operations the system can perform, from counting the HTTP endpoints registered in the server code. Counted on 21 September 2026.
TypeScript files, excluding generated migrations and build output. Counted on 21 September 2026.
What was actually broken
A monthly community film night has to solve ticketing, capacity, money and the door — for an audience that includes people who will not install an app, will not make an account, and should not have to.
Every ticketing platform available assumes the opposite: that the audience is online, signed in, and willing to be onboarded. For a neighbourhood event, that assumption quietly excludes exactly the people you most want in the room.
The flow I designed
The whole reservation happens over text message. You text one word. It asks how many seats. It asks what you'd like to contribute. It sends a link to pay if you're paying by card, and a check-in code either way. That is the product.
No app. No account. No password. The device requirement is "a phone that can text", which is every phone.
Pay what you can, phrased as a ladder. Contribution options are presented as a small set of suggested amounts rather than an open box, because an open box makes people guess and guessing makes people leave. The same ladder maths is shared across SMS, web and the walk-in flow, so the three surfaces cannot drift into quoting different numbers.
The website is discovery, not transaction. It exists so someone who heard about it can find out what it is. The moment they want in, it hands them to the text thread.
The organiser app is designed for a dark lobby. Dark is the design, not a mode — light mode exists only so the legal pages are readable. Check-in is one-handed and one-thumbed, because the organiser is standing up with a phone in one hand and a queue in front of them.
The identity is a marquee, not a movie. Bulb light, neon, chrome, film grain, ticket stubs — the era, deliberately steering clear of any specific film's trademarks.
Interface notes
Suggested amounts, not an empty box
An open box makes people guess, and guessing makes them leave. One amount is marked suggested so nobody has to wonder what is normal.
It says what you get, before it asks for money
Admission, a meal, the film. Listed above the price, not after it.
Remaining seats, stated plainly
Fifty left. Real scarcity, shown once, with none of the countdown theatre.
The hard part
A text conversation you can actually test.
Anything that talks to people by text has to survive real behaviour. Somebody replies "2" to a question you asked four days ago. Somebody replies twice. Somebody replies while a reminder is going out. Getting that wrong means charging the wrong person or selling the same seat to two people.
So the part that decides what happens next was built to be completely self-contained. It takes the current situation and an incoming message, and says what should happen. It never touches the database and never sends anything — all of that lives outside it.
That single constraint is what makes it testable. Every strange sequence becomes an ordinary test with nothing to fake and no waiting around. Of all these projects it is the only one with real test coverage of its core logic, and that is not luck: it is testable because it was shaped to be.
One other fiddly piece — text messages are billed in fixed-size chunks, so the templates count their own length. An innocent wording change cannot silently turn one message into three.
Stack
| Frontend | React 18 + Vite, Wouter, TanStack Query |
|---|---|
| UI | A deliberately slim Radix subset, Tailwind |
| Backend | Express + TypeScript, one process serving API and client |
| Database | PostgreSQL (Neon) + Drizzle ORM |
| Auth | Passwordless organiser login codes over SMS, against an allowlist — There are five organisers. An accounts system would have been more code and less security. |
| SMS | Twilio, with signature verification and a compliant outbound queue |
| Payments | Stripe Checkout — the webhook is the only thing that confirms a reservation — The browser redirect is a hint, not a fact. |
| Testing | Vitest over the pure SMS state machine and contribution maths |
| Hosting | Render, on a plan that never sleeps so the reminder cron can't silently stop |
Outcome
Fully built and deployed to Render — SMS reservation, seat holds, Stripe payments confirmed strictly by webhook, an organiser app with QR check-in, reminder scheduling, and polling for which film to show next.
Not yet live, and the blockers are not software: carrier registration for the SMS number, and film screening rights. Both are real-world approvals, and the case study says so rather than implying a launch that hasn't happened.