Our own product — clubs, schools and venues

Joinovo — administration for clubs, schools and venues

What began as a tool for one tennis club now also carries language schools and dance studios. What made that possible is not a longer feature list but a tenant boundary that holds everywhere.

Visit the site →

The brief

An administration platform for organisations rarely fails on a feature and almost always on the boundary between them: one person belongs to several organisations, with a different role in each, and none may ever see another's data. On top of that, a tennis club and a language school need the same building blocks and a different vocabulary.

The solution

Each organisation gets its own subdomain; the tenant is read from the host in nginx and passed on as a header, so no route has to carry it. Membership is a table of its own with a role per organisation, and each tenant switches its modules on individually.

The outcome

One application carries sports clubs, language schools and dance studios without becoming a separate edition for each kind.

A member's court booking on the phone: the day view with three courts from 8 am to 8 pm, booked slots shown without names, maintenance on court 1, and a red line marking the current time.
Booked slots show no names.
The same day view in dark mode: courts, times and bookings unchanged on a dark ground.
The same day in dark mode.
A club's course management: six courses with a status such as running, open or finished, and their dates, venue, number of participants and price.
Courses, enrolment and attendance — the same module runs a language school.
The booking statistics: utilisation per court as a bar, and beneath it the attendance rate per course.
Utilisation and attendance on one page.

The difference between an application for one club and a platform for many is not a question of the feature list. It lies in where the boundary between two organisations is drawn, and how often somebody has to draw it. Drawn afresh in every query, it is eventually forgotten somewhere — and that is the one mistake a platform like this cannot make.

In Joinovo it therefore sits in front of the application. Each organisation has its own subdomain, the tenant is read from the host in the web server and passed on as a header, and the routes are constrained on it. No path carries an organisation identifier, so no path can lose one. Membership is a table of its own: one person, several organisations, a role in each — rather than an account per club.

On top of that, the feature set is switchable per tenant, and that is precisely what carried the platform beyond where it came from. It started as a tool for consumption and payment in a tennis club; today it also runs course enrolment, scheduling and attendance for a language school. Membership cards and visits are scanned as QR codes, and billing keeps running in the background.

Work

Comparable projects from the same service areas.

All work →