Platform · automation · B2B
A one-coach tennis business with a system that books courts, bills companies and issues invoices
Live prices and free courts from three clubs, automatic booking in the clubs' own system, packages, vouchers, company accounts with contracts and attendance-based billing, plus two AI assistants: one for the coach and one for clients.
- Status
- In production, used daily
- Period
- April – November 2026
- clubs with live court availability
- 3clubs with live court availability
- API endpoints
- 112API endpoints
- AI assistants on one shared core
- 2AI assistants on one shared core
- commits, PL and EN
- 422commits, PL and EN
The problem
The coach teaches at three clubs and books every court by hand in an external system. Clients ask for slots on WhatsApp, companies want contracts, invoices and billing for actual employee attendance. One person does all of it between sessions.
What I built
- An availability engine: free courts from three clubs (kluby.org) matched against the coach's calendar, seasonal summer/winter prices, the weather next to each slot and a cache with invalidation.
- Automatic court booking in the club's system through Selenium (with a dry-run mode). If the slot is gone, the coach gets an e-mail and nothing is refunded automatically, because a person decides.
- Stripe payments, hour packages, a credit wallet, vouchers with any amount and a dedication (generated artwork), discounts, group bookings and racket rental.
- Company accounts (B2B): a company builds an offer in a wizard with a live price, the coach confirms the slot with the club, then a contract to sign, QR attendance and a monthly invoice in Fakturownia.
- Two assistants (coach and client) on one tool-use core that audits every turn and its cost. The coach's assistant checks courts at every club, the schedule and packages, books courts and blocks time.
- Growth: an Instagram Stories generator with UTM links that open a specific slot, sales-channel attribution and Cloudflare analytics. In design: training recordings cut automatically into clips (the coach's voice + the sound of the hit).
Architecture
The interesting part is underneath
Pick a flow to see data move through the system. Click any part for details.
← swipe the diagram →
Flows
From a live price to a court booked in the club's system.
Click a part of the diagram for details.
- hardware
- edge / network
- service
- data
- AI
- third party
- people / apps
- radio
- tunnel
- HTTPS
- local
- event
Every element, described
- Client · booking, packages
- Picks a court, time and club with live prices, pays, has a wallet, packages, vouchers and an assistant.
- Coach · panel + assistant
- Schedule, clients, companies, QR attendance, invoices, time blocks and an assistant that does it on request.
- Company (HR) · company account
- A separate, isolated account: offer wizard, employees, attendance, billing. Employees get regular accounts with a “Company” tab.
- FastAPI · booking, B2B, payments
- One function computes the price for both preview and save, so the price never drifts. E-mails and errors in PL and EN.
- Availability · courts, calendar, weather
- Free slots from the clubs, filtered by the coach's calendar and blocks, with seasonal pricing and weather.
- Selenium · court auto-booking
- Signs in to the club's system and walks the booking form like a person. Dry-run mode stops before the final click.
- Assistant core · tool-use, audit
- A shared tool-use loop for both assistants: tool rounds, dispatch, a log of every turn with tokens and cost.
- PostgreSQL · clients, contracts
- Clients, bookings, packages, wallets, companies, contracts, attendance and assistant history.
- Scheduler · reminders, invoices
- Reminders for companies, monthly billing, calendar clean-up.
- kluby.org · 3 tennis clubs
- The clubs' external system with no public API: availability from its AJAX endpoint, booking through its form.
- Google Calendar · coach's schedule
- Every booking and company block lands in the coach's calendar.
- Stripe · payments, portal
- Checkout for bookings, packages and vouchers, the customer portal, webhooks.
- Fakturownia · VAT invoices
- Invoices for companies based on actual attendance, sent automatically.
- firma.dev · contract e-sign
- B2B contract signing. Stage 2: the document is generated and sent automatically once the club slot is confirmed.
- Claude · assistants
- A model with domain tools: courts at every club, the schedule, package status, booking, blocks.
- Resend · e-mail PL/EN
- Confirmations, reminders, vouchers and alerts for the coach, in the client's language.
- Supabase Auth · sign-in by code
- Sign-in with an e-mailed code, no passwords. The same mechanism for clients, the coach and companies.
Decisions that make the difference
Two systems side by side, not one bloated one
B2B is seasonal blocks bought upfront, not single bookings. It has its own data model and shares only accounts, e-mail and pricing with the rest.
A bot, with a human on failure
Automating without an API has its risks. When a slot vanishes the system doesn't refund on its own; it calls the coach, who negotiates with the club.
One price function
Preview and save use the same function, so a company never sees a different amount from the contract.
i18n down to the last e-mail
Two languages across the UI, API errors, e-mails, Stripe Checkout and the assistants, checked by an audit for missed strings.
How it works
Three panels, one contract
A company buys a tennis season for its staff, the coach runs it, employees sign up and pay their share. Each has their own panel and their own manual on the client's site.
From registering an account to the first invoice: twelve steps, exactly what you see on screen.










The company covers part of the sessions: this is how an employee signs up, pays their share and checks in.





Data on the screens is fictional.
Stack
Service lines
Got a process that should run itself?
30 minutes, free. I'll tell you if it makes sense, how I'd build it and what it would cost to run.