Skip to main content
SportIQ

SportIQ — multi-tenant SaaS for sports federations

Several applications around one shared record: licences, competitions, communication and treasury for a sports federation, with strict isolation between federations.

The challenge

A federation is not a club, and it is not a company

A sports federation administers an ecosystem rather than an organisation: clubs with their own managers, licence holders who move between clubs, competitions that involve both, and accounts that have to follow all of it. Off-the-shelf tools address the club. Very few address the federation tier, and those that do are built for one federation at a time.

Four structural constraints ruled out a generic product:

  • Several federations on one platform. Each has its own rules, roles, age categories and fee scales — and none may ever see another's data. That is not a configuration preference, it is a security requirement.
  • Human-readable public identifiers. A licence number gets printed, read out over the phone and copied onto paper forms. It has to be short and sequential — which it cannot be if it doubles as the technical key of a database shared by several federations.
  • Permissions that are not just "admin" and "user". A club manager sees their club; a federal department sees every club but does not approve licences; a treasurer sees amounts but not medical files. And the exact split differs between federations.
  • Business areas that do not move at the same speed. Licence administration, competition organisation and the public website share neither users, release cadence, nor availability requirements.

The solution

Several applications, one shared record

The platform is not a single application, and it is not a microservice architecture either. It is a set of autonomous applications — each with its own Node.js/Express backend, its own Angular interface, its own deployment and its own authentication — built around a shared database that serves as the integration point.

  • Federation back office — licences, transfers, clubs, people, documents.
  • Competitions — entries, calendars, matches, results.
  • Public CMS — the federation's own website, administered by the federation itself.
  • News — a reduced variant of the CMS for federations that only need to publish.

The trade-off is deliberate: no backend ever makes an HTTP call to another backend. Each interface talks only to its own backend, and consistency comes from the data model rather than from a service mesh. That removes cascading latency, distributed transactions and chain failures — at the cost of coupling at the schema, which three rules offset: one single migration chain for the whole suite, identical query conventions in every project, and no foreign keys at all (referential integrity is held in application code, which keeps each application in charge of its own writes).

Tenant isolation is the starting point, not a feature

Each federation reaches the platform on its own subdomain. The current federation is then derived from the authentication token only — never from a URL parameter, request body or form field, all of which can be forged. Every read and every write is filtered on it, no query joins two federations, and an identifier belonging to another federation returns 404 rather than "access denied": the second answer would confirm the record exists.

Two identifiers per record

Every business object carries two keys: an internal key used only for joins and never exposed, and a federation-scoped sequential identifier assigned automatically by a database trigger from a dedicated counter. That second identifier is what users, URLs and the API see — so licence holder no. 1,042 exists independently in each federation, with short gap-free numbers, while the database stays single. The rule holds everywhere: the public identifier appears in output only, never in a filter or a join.

Permissions computed, not hard-coded

Five federal roles ship predefined — super administration, federal administration, federal read-only, club management, club read-only — but the permissions attached to each role are configurable per federation, and any user can be granted or denied individual permissions on top of their role. The whole set is computed at sign-in, carried in the token, then checked server-side on every route and in the interface so that only genuinely permitted actions are rendered.

The one shared service: files

Signed licences, supporting evidence, photographs, logos — every document is centralised in a single file service, and it is the only dependency any application has on another. It works at two levels of access:

  • backends call it with HMAC-signed requests; the service holds no session and no user accounts, and trusts the signature and nothing else;
  • browsers reach private documents through time-limited signed URLs, with no authentication token and without ever seeing a real storage path.

Three details that matter in practice: the MIME type is validated from the file's content rather than from the declared header; the storage path must contain the federation segment, so a coding mistake cannot write into another federation's folder; and uploads happen in two stages — temporary deposit, then confirmation — with a cleanup job for files never confirmed.

Six modules, switched on at the federation's pace

Federation management, licences and transfers, competitions and matches, training/camps and diplomas, marketing and website, finance and treasury. All six share one record: a licence holder entered once is the same person on a match sheet, in a training session and in an accounting entry. A federation can enable two and add the rest later, with no data migration.

The results

What the architecture makes possible

  • A new federation is added without a new instance — no duplicated code, database or server, so no drift between clients.
  • One business area can move without blocking the others: competitions ship without redeploying the licence back office.
  • One shared record: the same person is no longer entered in three files, and licences, entries and payments reconcile without an intermediate export.
  • Short sequential licence numbers usable on a paper document, without exposing the database structure.
  • A permission model that follows the real organisation, adjustable by the federation itself rather than by a developer.
  • A single documented access point for files, signed and time-limited, which is what makes an audit answerable.

The platform is in production and operated under the sportiq.ma brand, where the six modules are described publicly. Development continues — further modules are in progress, and the architecture was chosen precisely so they can be added without disturbing what already runs.

Why this project matters beyond sport

Strict isolation between organisations, configurable roles, public identifiers separated from technical keys, signed calls between applications, documents served through temporary URLs: these are the same constraints a health fund, a multi-site clinic group or a property manager faces. It is the same foundation we build on for our business platforms.

Technologies used

Angular Node.js Express.js MySQL JWT HMAC
Explore the service : Business platforms →

Have a similar project?

Contact us to discuss it.

Chat on WhatsApp