02 / 04 Fonctionnel · migration HDS requise avant mise en service
NutriFollow
SaaS de suivi pour diététiciens indépendants, sur nutrifollow.fr, conçu et construit seul. Il est fonctionnel ; trois conditions, dont la migration vers un hébergement certifié HDS, restent à remplir avant d'accueillir des patients réels. Personne ne l'utilise aujourd'hui.
Le problème
Le suivi diététique se joue surtout entre les consultations : ce que le patient mange, son poids, ses questions, ses rendez-vous. NutriFollow met le praticien et ses patients sur le même outil. Le praticien construit des plans alimentaires à partir de la table de composition CIQUAL, suit le journal et la courbe de poids de chaque patient, gère ses créneaux. Le patient tient son journal depuis son téléphone (repas en photo, faim, humeur, sommeil), réserve un rendez-vous et écrit à son praticien.
Ce sont des données de santé, dont chaque praticien est responsable. Le produit doit donc isoler strictement les cabinets les uns des autres, et ne rien laisser passer d'un compte à l'autre.
Ce qui rendait la solution évidente inutilisable
Le comportement le plus naturel à écrire était aussi le plus dangereux. Quand un praticien ajoute un patient dont l'adresse e-mail a déjà un compte, le plus simple est de rattacher ce compte existant. C'est ce que faisait le code, sans regarder à qui appartenait ce compte, même à un autre praticien. Comme l'e-mail d'un patient pouvait ensuite être modifié sans contrainte d'unicité, la chaîne était complète : rattacher la victime, remplacer son e-mail par une adresse qu'on contrôle, demander une réinitialisation du mot de passe ou se connecter avec Google. Le compte changeait de propriétaire.
La faille a été trouvée lors d'un audit de sécurité interne, le 29 septembre 2026, et corrigée le jour même. Une adresse déjà connue est désormais refusée à la création. L'e-mail d'un patient n'est plus modifiable par le praticien dès que le patient a activé son compte ; avant, il le reste, pour corriger une faute de frappe. La connexion Google exige une adresse vérifiée par Google et ne se lie plus à un compte local non vérifié, ce qui ferme une variante par pré-création de compte. Des tests de non-régression couvrent chacun de ces cas.
Deuxième évidence inutilisable : mettre en service, tel quel, un produit qui fonctionne. Trois contraintes identifiées conditionnent l'accueil de patients réels. L'hébergement : en France, des données de santé hébergées pour le compte de tiers doivent l'être chez un hébergeur certifié HDS, et le produit doit migrer vers l'un d'eux. La pseudonymisation : les données d'un patient doivent être pseudonymisées avant tout appel au service d'inférence, qui est un tiers. Le chiffrement : déjà appliqué aux traitements et aux notes médicales, il doit s'étendre au reste du dossier médical. Le produit fonctionne ; ces trois points décident du moment où il pourra servir.
Ce qui a été choisi, et ce que ça a coûté
Une seule application Laravel, servie par Inertia et Vue, porte les deux interfaces : celle du praticien, pensée pour l'ordinateur, et celle du patient, installable sur téléphone comme PWA. Il n'y a pas d'API REST séparée, pas d'application native, pas de multi-cabinet (un praticien, un compte), et la visio passe par un lien Google Meet externe. Le temps réel passe par Reverb : messagerie, saisies du journal qui arrivent chez le praticien pendant qu'il le consulte, notifications. Les rappels de rendez-vous partent la veille par mail, SMS et notification push.
Le coût de la PWA est apparu pendant l'audit : le service worker gardait en cache, pendant 24 heures, des pages et des réponses contenant des données médicales, encore lisibles après déconnexion. Il ne met plus en cache que les fichiers statiques. Il n'y a donc pas de mode hors ligne pour les données, et c'est voulu.
L'IA (proposition de plan, suggestions de repas, analyse du journal, résumé avant rendez-vous) passe par Groq, choisi pour son coût. Chaque demande est un job asynchrone dans une file Redis. Le JSON renvoyé est validé avant affichage, et le résultat est présenté comme une proposition à valider par le praticien, jamais comme une prescription.
L'isolation entre cabinets repose sur une portée globale appliquée aux modèles. L'audit a
montré sa limite : deux fuites entre cabinets, classées hautes, passaient à côté. L'export
RGPD incluait des conversations d'autres cabinets, et la duplication d'un plan acceptait
l'identifiant du patient d'un autre praticien. Une portée globale filtre les requêtes
qu'on écrit, elle ne valide pas l'identifiant qu'un formulaire envoie. Les deux
corrections sont une règle de validation dédiée et un filtre explicite sur l'export. Le
même audit a déplacé les photos de santé d'un disque public vers un disque privé, servi
derrière des autorisations. Il a aussi mis à zéro les alertes de
composer audit et npm audit.
Ce qui manque pour lancer le produit n'est pas que technique : le démarchage n'a pas été fait. J'ai donné la priorité à l'activité freelance.
Vérifiable
- Site
- nutrifollow.fr
Chiffres déclarés, dépôt privé :
- Tests
- 184 Pest · 44 Vitest · 70 Dusk au 2 octobre 2026