GoalKick
Étude de cas

GoalKick : gérer un centre de football, de la réservation à la caisse

GoalKick est une plateforme de gestion pour les centres de football et de five que j'ai conçue et développée pour le marché casablancais : un tableau de bord pour le gérant, une application de réservation pour les joueurs et un catalogue public des terrains — prix en dirhams, et paiement sur place traité comme un vrai moyen de paiement.

Le problème

La plupart des centres prennent encore les réservations par téléphone et WhatsApp, et les notent dans un cahier : doubles réservations, absences impossibles à suivre, et aucune vision claire des créneaux vraiment rentables.

Ce que j'ai construit

  • Tableau de bord du gérant — terrains, horaires et règles de prix ; réservations et fermetures ; clients et fidélité ; tournois et cours d'académie ; abonnements, caisse, dépenses et paie ; rapports d'occupation et de chiffre d'affaires.
  • Application joueur — iOS, Android et web à partir d'une seule base Expo : trouver un terrain, voir les vraies disponibilités, réserver, partager le coût, rejoindre des matchs.
  • Site public — pages de présentation et catalogue des centres rendus côté serveur avec Angular SSR, lisibles par les moteurs de recherche.

Les choix techniques

La double réservation est bloquée par la base de données. Une contrainte d'exclusion PostgreSQL couvre chaque terrain et chaque plage horaire. Le service tente l'insertion et passe au terrain suivant si la contrainte la refuse ; un test lance 12 réservations simultanées sur un créneau de 3 terrains et vérifie qu'exactement 3 aboutissent.

Les disponibilités sont calculées, jamais stockées. Les créneaux sont calculés à partir des horaires, de la durée des créneaux et des règles de prix, moins les réservations en cours — le calendrier ne peut donc jamais contredire les réservations.

L'argent en nombres entiers. Les montants sont stockés en centimes, sans aucun nombre à virgule près des dirhams, et un paiement partagé retombe toujours exactement sur le total.

Multi-centres dès le départ. Aucun point d'accès du gérant n'accepte d'identifiant de centre : il vient du jeton signé, il n'y a donc aucun paramètre à falsifier.

Les paiements derrière une seule interface. Le paiement sur place est un fournisseur à part entière, et un acquéreur carte marocain (CMI ou Payzone) se branche sans toucher à la logique de réservation.

La stack

  • Java 25
  • Spring Boot 4.1
  • PostgreSQL 17
  • Liquibase
  • Angular 22 SSR
  • Expo · React Native
  • Testcontainers
  • Docker
  • GitHub Actions

Les tests d'intégration tournent sur un vrai PostgreSQL via Testcontainers, et chaque fusion se déploie d'elle-même derrière Caddy.

Voir le projet

Votre activité tourne sur des tableurs et WhatsApp ? Racontez-moi comment elle fonctionne aujourd'hui.