2026
Core in production
PlayOne
A SaaS for sports schools: students, classes, attendance and monthly fees in one product — and the coach takes attendance courtside, with no signal.
RoleFounder, CEO and developer
Year2026
SourceCommercial product, closed source
Overview
PlayOne puts the four people around a sports school in one product: the owner, the admin, the coach and the parent. There is a Flutter app for Android and iOS, a Next.js panel for the computer, and a FastAPI backend both of them talk to. Every school is a separate tenant, and every query is scoped to it.
Problem
A sports school is a real business. It charges monthly fees, employs coaches, and has families waiting for information — and it is almost always run on a notebook, a spreadsheet and a WhatsApp group. Nobody is sure who paid, attendance sheets get lost, and the owner spends the evening answering parents about training times.
Solution
The coach takes attendance at the side of the court, and it works with no signal — the app queues it and syncs when the connection comes back. The owner opens the app and sees the month: what was due, what came in, who is late. Each family sees only their own child, with an assistant that answers the questions they used to send to the group.
My role
I founded PlayOne and I run it: what gets built, what gets cut, how it is priced. I also write it — the FastAPI backend and the data model, the Flutter app, and the Next.js panel.
Architecture
Technologies
- BackendPython · FastAPI · SQLAlchemy 2 (async) · Alembic
- DatabasePostgreSQL (Supabase)
- MobileFlutter · Riverpod · go_router · Dio
- WebNext.js · React · TypeScript · Tailwind
- AuthSupabase JWT · JWKS (ES256)
- PaymentsStripe
- OperationsSentry · GitHub Actions · 111 tests
Business
Four plans, priced by how big the school is rather than by locking essential features: free up to 20 students, then Starter and Pro, then Enterprise for chains. Seven days of trial, and when it ends writing is blocked but reading never is — a school should not lose access to its own records. The limits are enforced in the code, not only on the pricing page.
Challenges
Attendance has to work with no signal. Courts and pools rarely have a usable connection, so the app keeps a local cache and a queue of pending changes, and reconciles on sync — including the awkward case of a sheet created while the queue is being flushed.
Multi-tenancy is where a product like this leaks. The school is always derived from the authenticated profile, never from the request, and a coach is scoped to his own classes at the query level rather than in the interface.
Money is Decimal serialised as a string, never a float. And an absolute instant is not the same thing as a civil date: a school was losing access at 21:00 instead of midnight until the business timezone was pulled into one place.
What I learned
Deciding what not to build turned out to be most of the work. Every feature I wanted had to lose to the two things a school actually opens the app for: taking attendance and knowing who paid. Three schools used it in the field during testing, and what they asked for was never the feature I was proud of.
Next