Centauri Studios
Self-serve studio hire, checkout to door code

About Centauri Studios
Centauri Studios runs a self-serve creative studio in Birmingham: an equipped photography studio, a styled set, and a podcast room, each bookable by the hour, plus the whole floor for larger productions. There is no front desk. Customers book and pay online and let themselves in, so the business runs on software rather than staff, and a done-for-you arm (product shoots, UGC and headshots) sells the same space as a service.
Objectives
- Let customers book, pay for and access an unmanned studio entirely online, with no staff handover.
- Make double-booking impossible across three independent spaces and a whole-floor option.
- Issue time-limited gate and room codes automatically, but only once a booking is paid.
- Take deposits, balances and cancellations without anyone at a desk to manage them.
- Build it API-first so the same engine can run more than one location.
The Challenge
An unmanned studio has no one to hand over keys, take a deposit, chase a balance, or stop two people booking the same room. Every rule a receptionist would enforce has to be enforced by the system instead, and it has to hold under real conditions: two people hitting book for the same slot in the same second, a payment that fails after a room was reserved, a booking made months before the studio even opens.
The Approach
The core decision was to treat the booking rules as invariants the database guarantees, not checks the app hopes to run in time. No-double-booking is a Postgres exclusion constraint, so a room can be held twice only if the database itself is wrong (it can't be), rather than relying on an availability check that two concurrent requests can both pass. And access codes are made a consequence of a confirmed payment, issued exactly once from the Stripe webhook, so the door can never open on an unpaid booking.
The Solution
A booking wizard prices the selection server-side, holds the room, and hands off to Stripe Checkout. When payment confirms, the booking settles, time-limited access codes for the gate and the room are issued and emailed, and the slot is locked. Deposits, balance reminders, cancellations and refunds all run on a clock rather than a person, and members get their own rates and a waived deposit automatically.
Built on Next.js and Supabase (Postgres), with Stripe for payments and subscriptions and Resend for email. No-double-booking is a GiST exclusion constraint over a time-range column, so a whole-floor booking writes one blocking slot per studio and still can't clash with a single-room one. The payment webhook is idempotent, so a booking confirms and issues its codes exactly once however many times Stripe retries. The access layer is a pluggable seam, a mock today and a real smart-lock API (gate and studio doors) later, so the engine was built for hardware it doesn't have yet, and for more than the one location.
Two people can never book the same room
Three spaces book independently, and a whole-floor option takes the two studios at once. Rather than check availability in the app and hope the check wins the race, the system makes overlap impossible in the database: reserving a room writes a time range the schema refuses to let overlap another. A whole-floor booking writes one blocking range per studio, so it can't collide with a single-room booking, while two different rooms book at the same time without issue.
- Three independent spaces plus a whole-floor option
- Overlap is refused by the database, not by an app-level check
- Whole-floor blocks each studio without touching the podcast
Putting the guarantee in Postgres means the app has to translate a raw constraint error back into a friendly “that slot just went” message, and the rule lives in the schema rather than the code. The trade is deliberate: it is the only place a rule can hold when two people book the same second, which no application check can promise.

Payment issues the codes that open the door
There is no reception to buzz you in, so a paid booking is the key. When Stripe confirms it, the gate and room codes are issued, time-limited to the session window, and emailed with the address and parking. Bookings made before the studio opens defer their codes until shortly before the date, and a scheduled job releases them on time. Deposits are held and released, balances chased, and cancellations refunded, all on a clock rather than by anyone at a desk.
- Codes issued only on a confirmed payment, and only for the booked window
- A damage deposit is held automatically before the session, released after
- Balance reminders and refunds run on a schedule, unattended

Members get their rates without asking
Regulars subscribe to one of three tiers, and the studio recognises them at checkout: member rates and a waived damage deposit apply on their own, with no code to enter or staff to ask. Billing is a Stripe subscription, so if a membership lapses or a payment fails, the perks come off automatically the next time they book.
- Member rates and a waived deposit apply automatically at checkout
- A lapsed or past-due membership revokes the perks on its own

Buy a shoot without booking a minute of studio time
Not everyone wants to run the room themselves. A separate services arm sells finished work, product photography, short-form UGC and headshots, bought online against a fixed brief. The customer pays, sends what they want shot, and the studio schedules and delivers, so the same space earns as a service as well as by the hour.

Technologies
Conclusion
Before the doors even open, the studio already runs itself: bookings that can't collide, codes that only a paid session can produce, and deposits, balances and memberships that manage themselves. What would normally be a receptionist's job is the software's, and because the engine was built API-first behind a swappable lock, the same system is ready to run the next location as easily as the first.
Have a project in mind? Let's talk