One room, sold once an hour, with the money accounted for.
Booking, roster, invoicing and staff commission for a one-room recording studio, with the rules that matter enforced in the database rather than the interface.
- Client
- A booking and payments system
- Practice
- ERP Systems
- Published
- 14 August 2026
Two bands, one door, seven o’clock.
Both groups booked it. Both paid something to hold it. One of them is going home, and there is no version of the evening where an apology fixes that, because what was sold was not a product anyone can restock. It was seven o’clock on a Friday in the only room the studio has, and there is only ever one of those.
Any business that sells a room, a chair, a table or an appointment sits one row away from that evening. The cost of it is not the refund. It is that a venue like this one is booked on a friend’s recommendation, and the story that travels afterwards is never the one about the session that went well.
The money has the same shape. A session is quoted at one figure, an advance is collected before the room is held, and the balance is taken in person on the day, frequently by whoever happens to be on shift rather than by the owner. Once staff earn a percentage of what they collect, the person writing the number down is the person the number pays. Nobody has done anything wrong. The arrangement is simply one that cannot be audited from the outside, and an arrangement is fixed by changing the arrangement.
- 01One room, so a scheduling clash is a lost customer, not a delay
- 02Advance collected before the hour is held, balance taken in person
- 03Staff on shift record money they are later paid a percentage of
- 04Three kinds of user, with genuinely different reach, on one screen
- 05No staging environment and no rehearsal: it takes real payments from day one
Put the rules where they cannot be bypassed.
The ordinary way to stop a double booking is to check for one in the booking screen. That works until something reaches the data another way: a second tab, a retried request, two people tapping confirm in the same second, or any future screen written by anyone who forgets the rule. An interface check is a request. We wanted a refusal.
So the rules that would be expensive to get wrong live in the database itself. An overlapping hour is rejected by the table, not by the form. A staff member's reach is decided by a role-gated function, written as a list of who is allowed rather than a list of who is barred, so that adding a fourth role next year fails closed instead of quietly granting it everything. The interface is where the studio works. It is not the arbiter.
The same principle decided how the studio handles a booking it wants off the books. Nothing deletes. A cancelled or mistaken session is archived, keeping the row and the audit trail, because a hard delete would orphan an invoice that had already been issued and would hand the person who records the money the ability to erase the record of it. Deleting is easy to build and impossible to undo, which is the wrong trade for a business whose books are the thing being protected.
On top of that foundation the studio got what it actually runs the day on: a public site and booking flow with a real calendar and a UPI advance, and an owner panel that installs to the phone's home screen — the day's bookings, history and takings over any date range, invoices, the rate card, the site's own copy, staff and their roster, and commission and payouts. Three roles, each with a different and deliberately limited reach: the owner, a co-admin who handles bookings and invoices, and an assistant who can see the whole day but can only act inside the hours he is actually rostered for.
Measured, not estimated.
Thirty-one days from an empty repository to a studio running its own bookings, invoices, roster and staff payouts, live on real payments. Six hundred and twenty-five automated checks run green on the current code. An overlapping booking is not merely discouraged, it is refused by the table, so the count of double-bookings the system can accept is zero and stays zero no matter what is built on top of it later.
The result we would put first is one nobody would have noticed if we had not gone looking.
The staff commission formula was implemented exactly as the approved specification wrote it. Rather than trust that, we ran it against the live database across every plausible combination of hours, rate and amount: 324 wrong answers in 314,600, each one a rupee short, and every single one in the assistant's disfavour. The cause was a rounding step in the wrong position. All four worked examples in the specification happened to divide evenly, so building precisely what was asked for and testing precisely what was specified would have shipped it, and the people underpaid would have been the people least able to audit it. It was corrected before a single payout was made.
That is what we mean by measuring instead of estimating, and it is worth being just as plain about the limits. At the time of writing, the roster and commission system is built, applied and reviewed, but no assistant has yet been invited on the live studio, so every commission figure on the panel currently reads zero and is correct in doing so. The next step is not more building. It is ten minutes of the owner's time putting a real person through it. We would rather say that than let a number imply a proof it has not earned.
- Supabase
- TypeScript
- Resend
- Vercel
- Claude