← Tous les projets
● PublicProjet personnel2026

CoachPro — SaaS de coaching avec IA

Architecture & développement (API + mobile)

Plateforme API-First de coaching sportif et nutritionnel, avec sécurité multi-tenant en défense en profondeur et coach IA Mistral.

SymfonyAPI PlatformPostgreSQLJWTReact NativeMistral AIMessenger

Le contexte

CoachPro est une plateforme de suivi sportif et nutritionnel, pensée API-First et SaaS dès le premier jour. Phase 1 : un usage personnel (tracking poids, performances, diète). Phase 2 : une plateforme pour coachs, où chaque coach gère ses clients, leur assigne des programmes et suit leur progression.

L'application est volontairement découpée en un backend API unique (Symfony / API Platform) consommé par un client mobile React Native / Expo. Aucune logique métier ne vit côté client — le même backend servira demain le web et d'autres coachs.

La sécurité multi-tenant : le vrai défi

Dès qu'on parle de plusieurs coachs et de leurs clients, une question devient critique : comment garantir qu'un coach ne voie jamais les données d'un autre ? J'ai répondu par une défense en profondeur à deux couches complémentaires :

  1. Lectures — une extension Doctrine (CurrentUserExtension) injecte automatiquement le WHERE de scoping sur toute collection ou item exposé par API Platform. Ajouter une nouvelle entité « possédée » = l'inscrire dans une map, et elle est protégée. Aucun filtre oublié possible.
  2. Écritures & accès direct — un Voter unique (OwnedResourceVoter) gère les autorisations (VIEW / EDIT / CREATE) pour toutes les entités possédées : soi-même → ok ; client de mon périmètre coach → ok ; sinon refus.

En complément : JWT pour l'authentification stateless, UUID v7 non énumérables (pas de /users/1, /users/2), et un contrôle securityPostDenormalize sur les POST pour empêcher la création de ressources au nom d'un autre utilisateur.

L'IA, mais cadrée

Le coach IA s'appuie sur Mistral AI pour donner des conseils personnalisés et expliquer les recalibrages d'objectifs. Le principe que j'ai posé : l'IA explique, elle ne décide pas. Les calculs (régression sur les pesées, projection d'objectif) sont déterministes ; le LLM ne fait que reformuler la décision en langage clair. Un garde-fou de périmètre limite le chatbot au sport et à la nutrition, et refuse les sujets hors cadre.

Les traitements lourds (recalibrage d'objectif après une pesée) tournent en asynchrone via Symfony Messenger, hors du cycle requête.

La stack

Backend : PHP 8.4, Symfony, API Platform 4.3, Doctrine ORM, PostgreSQL, LexikJWT, Symfony Messenger, Symfony UID (UUID v7), Mistral AI. Mobile : React Native 0.81 + Expo (build cloud EAS). Front web : Tailwind 4 + DaisyUI via AssetMapper.

Ce que ce projet démontre

La capacité à concevoir une architecture SaaS multi-tenant sécurisée by design, à appliquer le principe de défense en profondeur, et à intégrer l'IA de façon responsable — avec une séparation nette entre calcul déterministe et reformulation par le LLM.