Skip to content
sapiqa

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 →

APPS (PWA)BACKEND · DROPLETINTEGRATIONSClientbooking, packagesCoachpanel + assistantCompany (HR)company accountFastAPIbooking, B2B, paymentsAvailabilitycourts, calendar, weatherSeleniumcourt auto-bookingAssistant coretool-use, auditPostgreSQLclients, contractsSchedulerreminders, invoiceskluby.org3 tennis clubsGoogle Calendarcoach's scheduleStripepayments, portalFakturowniaVAT invoicesfirma.devcontract e-signClaudeassistantsResende-mail PL/ENSupabase Authsign-in by code

Flows

From a live price to a court booked in the club's system.

Step 1 of 8

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.

Guide for companies
Wizard and live price

Data on the screens is fictional.

Stack

PythonFastAPISQLAlchemyPostgreSQLReactViteTailwindi18nextSeleniumStripeFakturowniafirma.devGoogle CalendarGoogle PlacesSupabase AuthResendClaude

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.

Book a call