Skip to content

In production · 2026

Rebote — Basketball club management

Multi-club SaaS for youth basketball: teams, call-ups, attendance, fees, treasury and public sign-ups.

Role
Design and development, end to end
Dashboard sections
20
Entities in the model
13
See it in production

Try it yourself

Live
The sign-in screen has a button: “Entrar como club demo”. One click and you are in — no sign-up, no asking anyone for credentials.

Worth a look inside

  • The club dashboard: teams, players, call-ups and attendance
  • Treasury: fees, payments and transaction categories
  • The family portal, which is the same application seen through a different role
  • The club’s public sign-up page

It is a fake club with fake data. Poke at whatever you like — it gets reseeded.

Problem

A youth basketball club is usually run on a WhatsApp group per team, a spreadsheet for the fees and the coach’s memory for the call-ups. That holds until the club grows.

Decision

Multi-tenant in the data model, not in the interface: everything hangs off the club identifier, and each person’s role is defined per club through a memberships table.

That lets the same user be a coach at one club and a parent at another without duplicate accounts. Isolating per query is what lets one small server serve several clubs — at the cost of never writing a query without its scope.

Implementation

Seasons, teams, players, guardians, events, call-ups, attendance, fees, payments, documents and messaging, across thirteen entities.

Each club gets a public page with its standings and its own sign-up form. Families log into their own portal to see call-ups, documents and where their fees stand.

Authentication runs on Sanctum tokens rather than cookie sessions: the front end is a separate application, and talking in tokens avoids the whole shared-domain and cross-origin CSRF tangle.

Treasury covers fees, payments, transaction categories and reconciliation, with optional integration into GoCardless’ bank data API.

Deployment

Three containers on Coolify: the Next.js front end compiled in standalone mode, the Laravel back end served by FrankenPHP, and MySQL on a private network with no route out to the internet.

The back end does get a public domain, because the caller is the visitor’s browser, not the front-end server.