Vetzy — Laravel SaaS project

SaaS veterinary booking platform for clinics and pet owners with scheduling, notifications and client portal.

Vetzy — Laravel SaaS project
Role
Founder, full stack developer
Stack
Laravel 13 · Livewire 4
Architecture
7 applications, 17 packages
Status
Live

Context

Booking a vet is still often a phone call during opening hours, with no reminder and no history. Clinics run their schedules, absences and records in separate tools, and finding an on-call vet at night or at the weekend is down to luck.

Business challenge

Digitize appointment booking for veterinary clinics while keeping a simple experience for pet owners.

Solution

Vetzy is a monorepo of seven Laravel applications, each in its own Git submodule with its own MySQL database: the booking app for pet owners and clinics, a shared admin, a central REST API, the blog, a veterinary job board, the on-call map and the vet assistants’ workspace. Shared code lives in 17 internal packages; no transaction spans two databases, and cross-application writes go through HTTP or an outbox table.

Outcome

Live at vetzy.eu, in French, English and Dutch. The on-call map covers Belgium, France, Switzerland and Luxembourg. A deployment only runs once four workflows have passed on the same commit, and every application is then checked in production.

My role

Founder & lead developer

Architecture

Users

  • Pet owners
  • Vets and clinics
  • Vet assistants
  • Recruiters and candidates
  • Admin team

Application

  • app · admin · api
  • blog · jobs · on-call · assistants
  • 17 vetzy/* packages
  • MySQL 8.4, one database per app
  • Redis 7 · workers · scheduler
  • Signed SSO between apps

External services

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

The flow, step by step

  1. Search

    The owner searches for a vet or clinic by speciality, location, emergency or language; Scout queries Meilisearch, with an SQL fallback.

  2. Booking

    In the Livewire booking window, they pick the pet, the reason and the slot; conflicts and the vet’s absences are checked.

  3. Confirmation

    The appointment is stored and shows up both in the owner’s space and in the clinic’s calendar.

  4. Reminders

    Redis jobs send reminders by e-mail or SMS according to preferences; every send is logged.

  5. Check-in

    The vet assistant signs in to their workspace through SSO and records the patient’s arrival and intake notes.

  6. Late cancellation

    A late cancellation can trigger a Stripe Checkout payment, tracked until it expires.

Data model

The main entities, their key fields and their relations.

User

  • email · phone · locale
  • Stripe columns (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 (on-call)

  • on-call vet
  • period
  • country
  • logical key to app.veterinaries

Job (jobs)

  • company
  • listing
  • indexed by Scout
  • Company 1—n Job
  • Job 1—n JobApplication

Full technical sheet

Languages
PHP 8.4, JavaScript, TypeScript (Playwright tests)
Framework
Laravel 13 in all seven applications
Front end
Livewire 4, Alpine 3, Tailwind 4, Vite 8, Chart.js (admin)
Database
MySQL 8.4, one database per application, no distributed transaction
Cache and queues
Redis 7 for queues, dedicated worker and scheduler containers
Search
Laravel Scout and Meilisearch, SQL fallback
Authentication
Fortify, Sanctum, Jetstream, Socialite (Google, Apple, Facebook), signed SSO, role-based two-factor authentication
Payments
Stripe: Cashier for vets, stripe-php for the job board, deduplicated webhooks
Notifications
Twilio (SMS, WhatsApp), Mailjet or SendGrid, Brevo for the newsletter, Web Push
Maps
Leaflet for the on-call map, PlaceKit for address autocomplete
AI
Optional OpenAI matching between candidates and job listings
Hosting
Dedicated Linux server, Apache and PHP-FPM 8.4, Docker Compose locally
CI/CD
25 GitHub Actions workflows on a self-hosted runner; version, CI, E2E and smoke tests required before any deployment
Tests
Pest 4 (457 files, about 1,400 cases), Playwright (90 specs across six applications)
Quality
Pint, Larastan and PHPStan (level 10 on the main app), commitlint, lefthook, Lighthouse CI
Observability
Sentry in all seven apps, PostHog after consent, Telescope, /health probe
Languages (UI)
French, English, Dutch; four blocking i18n audits in CI
Security and GDPR
In-house security package (blocklist, injection detection, disposable e-mails), honeypot, activity log, cookie consent

Key features

  • Location-based search

    By speciality, emergency, language and services, with a widen-the-area option.

  • Calendars

    For vets and clinics, with absences, stand-ins and occupancy rate.

  • Pet record

    Consultations, vaccines, treatments and documents.

  • Automatic reminders

    Vaccines, medication, birthdays and satisfaction surveys.

  • On-call map

    Four countries, URLs per country and language.

  • Job board

    Listings, alerts, Stripe subscriptions and AI matching.

Problems solved

  1. Server saturated three times in 24 h

    ProblemApache went down for five minutes each time: processes hung on TLS connections left open after a fail2ban ban.

    FixAn Apache and PHP-FPM hardening script, and an incident runbook.

  2. Translation keys in e-mails

    ProblemSome reminders went out with the raw key as their subject instead of the translated text.

    FixA fourth i18n audit checks in CI that every key used exists.

  3. CI blocked by GitHub billing

    ProblemWorkflows stopped starting.

    FixMoved to self-hosted runners, selected by a variable.

  4. Map broken by the CSP

    ProblemIn production, the security policy blocked the map library.

    FixLibrary served from an allowed CDN, and the CSP tested.

  5. Tests wiping the local database

    ProblemThe suite ran against the development database.

    FixTest database enforced in the PHPUnit configuration.

Technical choices

Choice Why
One database per application Each app deploys and migrates on its own; cross-app writes go through HTTP or an outbox, with documented compensation.
Livewire rather than an SPA One server-side language for seven applications, and indexable pages.
Optional Meilisearch Locally, the “collection” driver is enough: one less service to run.
Non-destructive migrations No column drop without a plan, idempotent guards and three-step renames.

Timeline

  1. August 2024 First commit of the booking app
  2. April 2025 Stripe subscriptions for vets
  3. Spring 2025 API, on-call, jobs and blog
  4. February 2026 Monorepo and submodules
  5. June 2026 Vet assistants’ workspace
  6. July 2026 All seven apps on Laravel 13

In numbers

4,778
commits across submodules
1,798
named routes
259
migrations
90
Playwright specs

Taken from the project’s source code and Git history on 8 October 2026. No usage or revenue figures are published.

Related projects

SaaS
Sep 2025 — present
Lodate — Web App project
Appointment scheduling system with reminders and clean interface navigation.
Laravel, Livewire, Alpine.js, TailwindCSS
View project
SaaS
Jan 2023 — present
Laroo — Laravel ERP project
Laravel ERP covering inventory, billing and CRM for growing teams.
Laravel, Livewire, PHP, TailwindCSS
View project
SaaS
Jan 2024 — present
StreamCrea — Creator dashboard
Twitch, YouTube and Kick sync, multi-network publishing and a subscriber blog.
PHP, Laravel, Livewire, Stripe
View project
SaaS
Jan 2022 — Dec 2022
MissionsCMS — Web App project
Mission management system with tracking dashboards and workflow tools.
Laravel, Livewire, Alpine.js, TailwindCSS
View project

Available for PHP / Laravel / WordPress / Silverstripe missions in Belgium and remote EU.