Sportify
Une plateforme où chaque club amateur gère ses membres, publie ses actualités et programme ses matchs, pendant que les supporters suivent, commentent et likent. Construite à trois sur une période courte, comme exercice de conception et de travail en équipe.
LE POINT DE DÉPART
Sportify est né d'un besoin simple à énoncer et large à couvrir : donner à un club sportif amateur un seul endroit pour tout gérer. Le club a ses membres et ses responsables, publie ses actualités, programme ses matchs à domicile et à l'extérieur. Les supporters suivent leurs clubs, commentent, likent, reçoivent des notifications. Rien d'exotique pris isolément, mais mis bout à bout, un périmètre qui oblige à réfléchir avant d'écrire.
C'est là qu'est le vrai contenu du projet. Nous avons passé la première phase à trois sur du papier plutôt que sur du code : les user stories d'abord, puis le modèle conceptuel, le modèle logique, le modèle physique. Douze tables, les relations entre elles, les rôles au sein d'un club, ce qui se supprime en cascade et ce qui ne doit jamais disparaître. Le découpage en tâches est venu après, suivi sur YouTrack, sans répartition par spécialité : chacun de nous a fait du back, du front, du câblage entre les deux et des tests d'API sous Postman. C'est ce que je retiens le plus : dans une équipe où tout le monde touche à tout, ce qui tient le projet debout n'est pas la répartition, c'est ce qui a été décidé ensemble avant de commencer.
Le projet s'est arrêté avec la fin de la période. Deux domaines sont allés le plus loin : l'authentification et la gestion des matchs, du modèle de données jusqu'à l'écran. Les autres ont leur modèle et leur squelette d'API, mais ne sont jamais remontés jusqu'à l'interface. C'était un exercice d'apprentissage, pas un produit à livrer, et il a rempli son rôle.
CE QUE J'AI CONSTRUIT
- Une conception menée avant le code : user stories, MCD, MLD puis MPD posés à trois, aboutissant à 12 tables sous MySQL et 7 migrations Prisma versionnées.
- Une authentification à deux clés : un jeton d'accès court et un jeton de renouvellement long, stocké en base et révoqué à chaque renouvellement. Un même jeton ne peut donc pas servir deux fois. Mots de passe hashés avec bcrypt.
- La gestion des matchs : création, modification, suppression, avec les règles métier isolées dans leur propre service (un club ne peut pas jouer contre lui-même, la fin doit suivre le début, les deux clubs doivent exister) et la garantie que seul l'auteur d'un match peut y toucher.
- Un front React branché sur l'API : routes protégées, cache serveur avec invalidation automatique après chaque écriture, session persistée entre les rechargements, formulaires validés.
- Le profil utilisateur : modification des informations, changement de mot de passe, suppression de compte avec confirmation.
- Chaque route vérifiée sous Postman avant d'être câblée au front : la seule façon, à trois sur la même base, de savoir si un bug venait de l'API ou de l'interface.
- Un environnement conteneurisé : front, API et base MySQL sous Docker, le front servi par nginx à partir d'un build multi-stage.
- Une interface responsive Tailwind + DaisyUI, avec une navigation mobile dédiée.
Ce que j'en retiens
- Écrire le modèle de données avant le code n'a jamais coûté du temps ; c'est l'inverse qui en coûte.
- Quand personne n'est propriétaire d'une partie, c'est la conception commune qui fait office de contrat. Sans elle, trois personnes sur la même base écrivent trois versions de la même chose.
- Sortir les règles métier du contrôleur pour les mettre dans leur propre service est le seul endroit du projet qui serait testable sans monter toute l'application.
- Un périmètre large finit rarement complet. Mieux vaut deux domaines terminés que huit à moitié.