Skip to content
Flad Logic

← All work

Billing software built with AI, where the database guards the money

Studio Clarity is my own product: scheduling and billing for dance and martial arts studios, with online payments. Claude Code drafted much of the code. I designed the parts where a mistake charges a family twice or shows one studio another's data, and made the database and the tests enforce them.

The situation

Studio Clarity runs the business side of a dance or martial arts studio: classes across rooms, family accounts, check-in, and billing with monthly tuition, team fees, payment plans and sibling discounts. Every studio gets its own branded sign-in. It's in beta, and I'm building it alone, with Claude Code drafting much of the code.

The problem

Code is the cheap part now. An agent can draft a billing page in minutes. The expensive part is what happens when it's wrong: a double-clicked Pay button that charges a family twice, an edited payment that leaves the books not adding up, or a query that forgets which studio it's in. Agents make those mistakes as easily as people do, and in software that takes money for small businesses, one is enough to lose a customer.

So the real question was not how to write the code quickly. It was how to make the dangerous mistakes impossible, no matter who or what wrote the code.

What I did

  • Studios can't see each other, enforced twice. Every page and server action checks that the signed-in person belongs to that studio, and every query is scoped to it. Underneath, Postgres row-level security runs studio code as a restricted role, so a query that forgets the filter still sees only that studio's rows, and foreign keys carry the studio so a record can't point into another one. Tests fail if a new table skips either rule, and end-to-end tests sign in as one studio and try to open another's pages and files.
  • A ledger nobody can edit. Invoices, payments, credits and refunds are append-only: database triggers reject any update or delete, and an invoice can only move from open to paid or void. Mistakes are corrected with a credit, refund or void, the way an accountant would. Every money write runs in one transaction holding a per-studio lock, so double clicks and overlapping billing runs can't bill twice, and money, sign-in and settings changes all go in an audit log.
  • Payments through Stripe Connect. Each studio has its own Stripe account, and families pay by card, bank transfer, Apple Pay or Google Pay. A charge is recorded before Stripe is called, keyed so a retry or a replayed webhook can't create a second payment. Autopay runs on its own schedule with retries after 3 and 7 days, then marks the invoice past due and emails the family. Refunds go back through Stripe and roll back completely if Stripe refuses; disputes flag the invoices they paid and email the owner. Card details stay in Stripe's hosted fields and never reach the app.
  • Switching without retyping. Studios import families, students, classes and balances from CSV or Excel, with column presets for Jackrabbit, Studio Director, Akada, Zen Planner and Kicksite.
  • Running it like a business. Studio subscriptions with trial, past-due and read-only states; nightly database and file backups copied off the server, with a restore drill to prove they work; and an error log with email alerts. Every pull request runs lint and type checks, 31 test files against an in-memory Postgres, end-to-end browser tests and an OWASP ZAP security scan.

The result

Studio Clarity takes card and bank payments with autopay, refunds and disputes, on a ledger the database itself protects. The agents wrote a lot of the code. The rules that keep a studio's money and data safe live in the schema and the tests, where a bad draft can't get past them. That's the split I bring to client work too: use the fast tools for the code, and put an experienced engineer on the parts that have to be right.

Need something like this? See the First version project.

Next case studyFrom 2-hour manual releases to 15-minute deploys

Available now

Hiring, or need something built? Let's talk.