NutriPetit
01Le besoin
En rayon, un parent n'a aucun outil fait pour son bébé. Yuka, le Nutri-Score et NOVA appliquent des barèmes pensés pour des adultes : une compote très sucrée peut y paraître correcte, un lait infantile y est mal classé.
NutriPetit répond à une question simple : « ce produit est-il adapté à mon enfant de 0 à 3 ans ? ». On scanne le code-barres, on obtient une note sur 100, expliquée règle par règle et adaptée à l'âge.
02Mes choix techniques
- API Symfony 7.4 / PHP 8.4, PostgreSQL et Redis : toute la logique métier vit côté serveur, testable.
- Données produits issues d'Open Food Facts, scoring basé sur les recommandations OMS, ANSES, EFSA et le règlement UE 2016/127.
- Un moteur de règles déterministe : une vingtaine d'« évaluateurs » indépendants (risque d'étouffement, miel et botulisme, poissons contaminés, sucres et sel ajoutés, édulcorants, allergènes, fer, oméga-3…). Une règle = une classe = des tests.
- L'IA est volontairement exclue du calcul : une note de santé doit être reproductible et vérifiable.
- Front Angular en PWA installable (scan caméra, historique, profil bébé), qui consomme l'API en JSON. La vitrine et l'administration restent en Twig pour le référencement.
- Caddy en point d'entrée unique : / pour la vitrine, /app pour l'Angular, /api pour l'API.
03La difficulté
Les laits infantiles ressortaient tous « au-dessus des seuils ». En comparant avec la table Ciqual de l'Anses, j'ai trouvé la cause : Open Food Facts stocke les valeurs de la poudre dans les champs censés contenir le lait reconstitué, soit environ 8 fois trop.
Plutôt que de bricoler un coefficient, j'ai sorti les laits du calcul nutriment par nutriment et écrit un calculateur dédié, basé sur ce qui distingue réellement deux laits : huile de palme, sucres ajoutés, prébiotiques, bio, protéines de soja. Chaque bonus et malus est rattaché à sa source réglementaire.
Deuxième difficulté, côté déploiement : le front et l'API sur deux domaines Railway différents bloquaient le cookie de session. J'ai réglé ça avec un reverse proxy : tout passe par un seul domaine, le cookie redevient first-party.
04Le résultat
- En ligne sur un seul domaine : vitrine, application Angular et API.
- 184 tests PHPUnit, PHPStan niveau 6 sans erreur, CI GitHub Actions à chaque push.