Vetzy — projet Laravel SaaS

Plateforme SaaS vétérinaire de prise de rendez-vous pour cliniques et propriétaires d’animaux.

Vetzy — projet Laravel SaaS
Rôle
Fondateur, développeur full stack
Stack
Laravel 13 · Livewire 4
Architecture
7 applications, 17 packages
Statut
En ligne

Contexte

Prendre rendez-vous chez un vétérinaire se fait encore souvent par téléphone, aux heures d’ouverture, sans rappel ni historique. Les cliniques gèrent leurs agendas, leurs absences et leurs dossiers dans des outils séparés, et trouver un vétérinaire de garde la nuit ou le week-end relève de la chance.

Défi métier

Digitaliser la prise de rendez-vous vétérinaire tout en gardant une expérience simple pour les propriétaires d'animaux.

Solution

Vetzy est un monorepo de sept applications Laravel, chacune dans son sous-module Git avec sa base MySQL : l’application de rendez-vous pour les propriétaires et les cliniques, l’administration commune, une API REST centrale, le blog, un site d’emploi vétérinaire, la carte des gardes et l’espace des assistants vétérinaires. Le code commun vit dans 17 packages internes ; aucune transaction ne traverse deux bases, les écritures entre applications passent par HTTP ou par une table d’attente.

Résultat

En ligne sur vetzy.eu, en français, anglais et néerlandais. La carte des gardes couvre la Belgique, la France, la Suisse et le Luxembourg. Un déploiement n’a lieu que si quatre workflows ont réussi sur le même commit, puis chaque application est vérifiée en production.

Mon rôle

Fondateur et développeur lead

Architecture

Utilisateurs

  • Propriétaires d’animaux
  • Vétérinaires et cliniques
  • Assistants vétérinaires
  • Recruteurs et candidats
  • Équipe d’administration

Application

  • app · admin · api
  • blog · jobs · garde · asv
  • 17 packages vetzy/*
  • MySQL 8.4, une base par application
  • Redis 7 · workers · scheduler
  • SSO signé entre applications

Services externes

  • Stripe · Cashier
  • Twilio (SMS, WhatsApp)
  • Mailjet · SendGrid · Brevo
  • Meilisearch (Scout)
  • Leaflet · PlaceKit
  • Sentry · PostHog

Le parcours, étape par étape

  1. Recherche

    Le propriétaire cherche un vétérinaire ou une clinique par spécialité, lieu, urgence ou langue ; Scout interroge Meilisearch, avec une requête SQL en repli.

  2. Réservation

    Dans la fenêtre de réservation Livewire, il choisit l’animal, le motif et le créneau ; les conflits et les absences du vétérinaire sont vérifiés.

  3. Confirmation

    Le rendez-vous est enregistré et apparaît dans l’espace du propriétaire comme dans l’agenda de la clinique.

  4. Rappels

    Des jobs Redis envoient les rappels par e-mail ou SMS selon les préférences ; chaque envoi est journalisé.

  5. Accueil

    L’assistant vétérinaire se connecte par SSO à son espace et enregistre l’arrivée du patient et les notes d’accueil.

  6. Annulation tardive

    Une annulation hors délai peut déclencher un paiement Stripe Checkout, suivi jusqu’à son expiration.

Modèle de données

Les entités principales, leurs champs clés et leurs relations.

User

  • email · phone · locale
  • colonnes Stripe (Cashier)
  • onboarding_completed_at
  • 1—n Pet
  • 1—n Appointment
  • 1—1 Veterinary

Pet

  • species · breed
  • birthdate
  • chip_number
  • 1—n Appointment
  • 1—n MedicalRecord
  • 1—n Vaccination

Center

  • name · vat_number
  • latitude · longitude
  • opening_hours
  • 1—n Veterinary

Veterinary

  • slug · license_number
  • is_emergency · is_24h
  • is_telemedicine
  • n—n Speciality
  • n—n Service
  • 1—n Unavailability

Appointment

  • date · start_at · end_at
  • status · is_emergency
  • sms_reminder · price
  • n—1 Pet · Veterinary · Center
  • 1—n MedicalRecord

MedicalRecord

  • consultation_date
  • diagnosis
  • prescriptions
  • n—1 Appointment

GuardShift (garde)

  • vétérinaire de garde
  • période
  • pays
  • clé logique vers app.veterinaries

Job (jobs)

  • company
  • offre
  • indexée par Scout
  • Company 1—n Job
  • Job 1—n JobApplication

Fiche technique complète

Langages
PHP 8.4, JavaScript, TypeScript (tests Playwright)
Framework
Laravel 13 dans les sept applications
Front
Livewire 4, Alpine 3, Tailwind 4, Vite 8, Chart.js (admin)
Base de données
MySQL 8.4, une base par application, pas de transaction distribuée
Cache et files
Redis 7 pour les files, conteneurs dédiés aux workers et au scheduler
Recherche
Laravel Scout et Meilisearch, repli SQL
Authentification
Fortify, Sanctum, Jetstream, Socialite (Google, Apple, Facebook), SSO signé, double authentification selon le rôle
Paiement
Stripe : Cashier pour les vétérinaires, stripe-php pour le site d’emploi, webhooks dédoublonnés
Notifications
Twilio (SMS, WhatsApp), Mailjet ou SendGrid, Brevo pour la newsletter, Web Push
Cartographie
Leaflet pour la carte des gardes, PlaceKit pour l’autocomplétion d’adresse
IA
OpenAI en option pour rapprocher candidats et offres d’emploi
Hébergement
Serveur Linux dédié, Apache et PHP-FPM 8.4, Docker Compose en local
CI/CD
25 workflows GitHub Actions sur runner auto-hébergé ; version, CI, E2E et smoke tests requis avant tout déploiement
Tests
Pest 4 (457 fichiers, environ 1 400 cas), Playwright (90 specs sur six applications)
Qualité
Pint, Larastan et PHPStan (niveau 10 sur l’application principale), commitlint, lefthook, Lighthouse CI
Observabilité
Sentry dans les sept applications, PostHog après consentement, Telescope, sonde /health
Langues
Français, anglais, néerlandais ; quatre audits i18n bloquants en CI
Sécurité et RGPD
Package de sécurité maison (liste de blocage, détection d’injections, e-mails jetables), honeypot, journal d’activité, consentement des cookies

Fonctionnalités clés

  • Recherche géolocalisée

    Par spécialité, urgence, langue et services, avec élargissement aux alentours.

  • Agendas

    Pour les vétérinaires et les cliniques, avec absences, remplaçants et taux d’occupation.

  • Dossier de l’animal

    Consultations, vaccins, traitements et documents.

  • Rappels automatiques

    Vaccins, médicaments, anniversaires et enquêtes de satisfaction.

  • Carte des gardes

    Quatre pays, URL par pays et par langue.

  • Site d’emploi

    Offres, alertes, abonnements Stripe et rapprochement par IA.

Problèmes résolus

  1. Serveur saturé trois fois en 24 h

    ProblèmeApache tombait cinq minutes à chaque fois : des processus restaient bloqués sur des connexions TLS laissées ouvertes après un bannissement fail2ban.

    SolutionScript de durcissement Apache et PHP-FPM, et un runbook d’incident.

  2. Clés de traduction dans les e-mails

    ProblèmeDes rappels partaient avec la clé brute en objet au lieu du texte traduit.

    SolutionUn quatrième audit i18n vérifie en CI que chaque clé appelée existe.

  3. CI bloquée par la facturation GitHub

    ProblèmeLes workflows ne démarraient plus.

    SolutionBascule sur des runners auto-hébergés, choisis par une variable.

  4. Carte cassée par la CSP

    ProblèmeEn production, la politique de sécurité bloquait la bibliothèque de carte.

    SolutionBibliothèque servie depuis un CDN autorisé, et la CSP testée.

  5. Tests qui vidaient la base locale

    ProblèmeLa suite s’exécutait sur la base de développement.

    SolutionBase de test imposée dans la configuration PHPUnit.

Choix techniques

Choix Pourquoi
Une base par application Chaque application se déploie et se migre seule ; les écritures croisées passent par HTTP ou une table d’attente, avec compensation documentée.
Livewire plutôt qu’une SPA Un seul langage côté serveur pour sept applications, et un rendu indexable.
Meilisearch optionnel En local, le pilote « collection » suffit : un service de moins à faire tourner.
Migrations non destructives Pas de suppression de colonne sans plan, des gardes idempotentes et un renommage en trois étapes.

Chronologie

  1. Août 2024 Premier commit de l’application
  2. Avril 2025 Abonnements Stripe pour les vétérinaires
  3. Printemps 2025 API, gardes, emploi et blog
  4. Février 2026 Monorepo et sous-modules
  5. Juin 2026 Espace des assistants vétérinaires
  6. Juillet 2026 Sept applications sous Laravel 13

En chiffres

4 778
commits dans les sous-modules
1 798
routes nommées
259
migrations
90
scénarios Playwright

Relevé dans le code source et l’historique Git du projet le 8 octobre 2026. Aucun chiffre d’usage ou de revenu n’est publié.

Projets similaires

SaaS
sept. 2025 — présent
Lodate — projet Web App
Système de gestion de rendez-vous avec rappels et interface épurée.
Laravel, Livewire, Alpine.js, TailwindCSS
Voir le projet
SaaS
janv. 2023 — présent
Laroo — projet Laravel ERP
Solution ERP Laravel pour opérations, inventaire et productivité.
Laravel, Livewire, PHP, TailwindCSS
Voir le projet
SaaS
janv. 2024 — présent
StreamCrea — tableau de bord des créateurs
Synchro Twitch, YouTube et Kick, publication multi-réseaux et blog pour abonnés.
PHP, Laravel, Livewire, Stripe
Voir le projet
SaaS
janv. 2022 — déc. 2022
MissionsCMS — projet Web App
Système de gestion de missions avec suivi et tableaux de bord.
Laravel, Livewire, Alpine.js, TailwindCSS
Voir le projet

Disponible pour missions PHP / Laravel / WordPress / Silverstripe en Belgique et remote EU.