Aller au contenu
Web · Santé animale — 2026

MrVeto

Plateforme de prise de rendez-vous vétérinaire : recherche géolocalisée, réservation en ligne, planning des cabinets et carnet de santé des animaux.

Rôle
Lead Développeur
Période
2026
Équipe
5 développeurs
Stack
Symfony · Stimulus · MySQL
Sur cette page

Le contexte

MrVeto met en relation des propriétaires d'animaux et des vétérinaires. Le propriétaire cherche un cabinet autour de lui, réserve un créneau en ligne et retrouve le suivi de ses animaux. Le cabinet gère ses horaires, ses rendez-vous et ses dossiers patients.

Le problème visé est concret : la prise de rendez-vous passe encore par le téléphone, et en cas d'urgence on perd du temps à chercher qui est ouvert. L'objectif était de couvrir tout le parcours, de la recherche jusqu'au compte rendu de consultation.

Dans l'équipe, j'ai surtout porté la recherche de vétérinaires, la carte, le bouton d'urgence, le planning du cabinet, les pages animaux et le déploiement.

Fig. 1 - Recherche autour d'une ville : filtres, statut ouvert ou fermé, carte avec regroupement des marqueurs

Fig. 1 - Recherche autour d'une ville : filtres, statut ouvert ou fermé, carte avec regroupement des marqueurs

Contraintes techniques

  • Sept développeurs sur le même dépôt : une branche par personne, fusion par pull request vers dev, puis staging.
  • Quatre profils aux droits distincts : propriétaire, vétérinaire, secrétaire, administrateur.
  • Un compte vétérinaire n'est actif qu'après contrôle de son SIRET et validation par un administrateur.
  • Aucune API payante ni clé à gérer : adresses via l'API Adresse de l'État, fonds de carte OpenStreetMap.
  • Un serveur de staging joignable en SSH, sans conteneur, avec une base MySQL.

Architecture

L'application est rendue côté serveur avec Symfony et Twig. L'interactivité arrive par petites touches, avec un contrôleur Stimulus par besoin : carte, autocomplétion d'adresse, édition du profil en ligne, bouton d'urgence. Résultat : une seule base de code, pas d'API à maintenir en parallèle d'un second front, et des pages utilisables dès le premier rendu.

Back
  • Symfony 7.4
  • PHP 8.2+
  • Doctrine ORM
  • KnpPaginator
  • Dompdf
Front
  • Twig
  • Stimulus
  • Turbo
  • Bootstrap 5
  • Leaflet
  • FullCalendar
Données
  • MySQL
  • API Adresse
  • API Recherche d'entreprises
Outils
  • Webpack Encore
  • GitHub Actions
  • PHPUnit

Recherche géolocalisée

La recherche part d'une ville ou de la position du navigateur. L'autocomplétion interroge l'API Adresse après 250 ms de pause et trois caractères saisis, pour limiter les appels. Le serveur reçoit une latitude, une longitude et un rayon, puis filtre avec un rectangle englobant.

src/Repository/UserRepository.php
$latPerKm = 1 / 111.0;
$lonPerKm = 1 / (111.0 * cos(deg2rad($lat)));
 
$latMin = $lat - ($distance * $latPerKm);
$latMax = $lat + ($distance * $latPerKm);
$lonMin = $lon - ($distance * $lonPerKm);
$lonMax = $lon + ($distance * $lonPerKm);

Un degré de longitude rétrécit quand on monte en latitude, d'où le cosinus de la ligne 2. Les résultats sont paginés, et le statut ouvert ou fermé des cabinets de la page est calculé avec une seule requête sur leurs horaires.

Urgences et planning

Le bouton d'urgence est présent sur toutes les pages. Il demande la position du navigateur, appelle /urgence/nearest et affiche le vétérinaire urgentiste le plus proche avec son téléphone. Ici la distance est exacte (formule de Haversine), calculée en PHP sur la liste des urgentistes, ce qui suffit tant qu'elle reste courte.

Fig. 2 - Bouton d'urgence : l'urgentiste le plus proche en un clic

Fig. 2 - Bouton d'urgence : l'urgentiste le plus proche en un clic

Le planning du vétérinaire repose sur FullCalendar. Il a son propre point d'entrée Webpack, donc la bibliothèque n'est chargée que sur cette page. Les rendez-vous arrivent par un endpoint JSON borné à la période affichée, et les horaires du cabinet délimitent les plages actives.

Fig. 3 - Planning du cabinet : une couleur par statut, détail du rendez-vous au clic

Fig. 3 - Planning du cabinet : une couleur par statut, détail du rendez-vous au clic
Pourquoi pas de requête spatiale ?
DQL n'a ni fonctions spatiales ni trigonométrie sans bibliothèque supplémentaire. Calculer les bornes en PHP ramène le filtre à quatre comparaisons.
Pourquoi rsync plutôt que Docker ?
Le staging est une machine classique joignable en SSH. GitHub Actions construit les assets, pousse les fichiers par rsync, puis lance Composer, le cache et les migrations.
Pourquoi l'API Adresse ?
Elle est publique, sans clé, et renvoie directement les coordonnées. Le même contrôleur sert à la recherche et aux formulaires d'inscription des cabinets.

Résultats

Le parcours complet fonctionne : recherche, réservation, gestion des rendez-vous par le cabinet, compte rendu en PDF et carnet de santé côté propriétaire.

de développement, de janvier à juin 2026
5 mois
contributeurs sur le dépôt
7
pull requests fusionnées
61
profils utilisateurs
4

Fig. 4 - Carnet de santé : prochains rendez-vous, traitements et historique par animal

Fig. 4 - Carnet de santé : prochains rendez-vous, traitements et historique par animal

Ce que j'ai appris

Le déploiement m'a demandé plusieurs séries de correctifs entre mars et juin : droits sur le dossier var/, cache Symfony à reconstruire en production, lockfile npm désynchronisé. Un coéquipier a ensuite durci le script. J'en retiens qu'un pipeline se teste comme du code, et tôt dans le projet.

Travailler à sept sur les mêmes gabarits Twig m'a appris à livrer petit et à fusionner souvent : le layout commun est le fichier que j'ai le plus modifié après la page de recherche. Côté regrets, la couverture de tests est restée mince, avec 13 tests fonctionnels. La recherche et la réservation mériteraient des tests de bout en bout.

  1. Janvier - février

    Initialisation du projet Symfony, puis recherche de vétérinaires, fiche cabinet et autocomplétion d'adresse.
  2. Mars

    Disponibilités, gestion des rendez-vous, carnet de santé et déploiement automatique sur le staging.
  3. Avril - mai

    Notifications, archivage des comptes, planning du cabinet, carte interactive et suivi des soins.
  4. Juin

    Profil vétérinaire éditable, urgences, filtres, passe d'accessibilité et corrections finales.
enzodaloia/MrVetoPHP · Twig

Un projet en tête ?

Disponible pour des missions freelance et des postes en CDI.

Me contacter