VetPulse: AI-CRM for vet clinics
A multi-tenant SaaS for vet clinics: an AI dispatcher answers clients and books patients, the system sends appointment reminders and wins back the «dormant» base. Designed and built end-to-end as a team: both the backend and a premium site with an interactive demo office.
// in this demo the replies are scripted on three examples; in production this is done by an LLM + RAG over the clinic's services and prices
From the owner's message to a booking in the clinic
A private vet clinic loses money at three points, and all three land on a single receptionist: evening and weekend enquiries go to the clinic next door; a patient forgets an appointment and the vet's hour sits empty; hundreds of pets with overdue vaccinations that no one systematically brings back. The routine eats the receptionist alive, and there are no hands left to win back the «dormant» base.
We built a multi-tenant AI-SaaS (clinic_id everywhere): the AI dispatcher handles enquiries and books patients, and two background engines send appointment reminders and win back the «dormant» base on their own, as in the diagram above. On top of that: self-serve clinic sign-up, an onboarding wizard, connecting your own practice system (Vetmanager) with encrypted keys, and a dashboard with «₽ recovered». Stack: Python, FastAPI, SQLAlchemy, a scheduler, an LLM behind a single provider interface.
The public docs didn't unambiguously give the filter serialization, the field keys, or, most importantly, where to get vaccination dates: a dedicated field, or compute them from the appointment history. We implemented both strategies behind a flag, isolated every ambiguous spot into separate helpers marked «verify on the first real response», and covered the client itself with tests via simulated HTTP responses: no network, no key.
A hard limit of 20 requests per minute forced a batching design and a local cache of the base for reactivation. The point: build against a spec you can't fully verify, but in a way where the touch-up after the first live response is one or two lines in one place.
A false negative: on a position:fixed modal, overflow:hidden clips the overflow instead of scrolling it: «no scroll», but the text is cut off. The root cause is min-width:auto on a flex/grid child that won't shrink below its own content; the fix is min-width:0. The lesson we reused afterwards: measure scrollWidth against clientWidth, don't rely on the document's scroll.
The main principle of this case isn't an engineering one: check whether an existing tool already covers the job, and whether there's demand, before you build, not after. Validation showed that reminders and win-back are largely covered by the built-in features of the vet CRMs themselves. That's a lesson we now build in from the very start.
- A multi-tenant SaaS end-to-end: self-serve clinic sign-up, onboarding, connecting your own practice system, an AI dialogue with booking, reminders and base reactivation, a dashboard with stats.
- A data layer with per-clinic isolation, covered by automated tests; a production Vetmanager client behind an adapter interface with a mock fallback.
- Multi-tenant security baked in from the start: passwords via bcrypt, integration keys encrypted in the database and never handed to the frontend.
- Separately designed and built a premium landing and an interactive product demo (a clinic «office»): pure static with zero dependencies, a custom design system, animated interactive components, full responsiveness and accessibility.
- Built in roughly 2 days of AI-assisted development (an estimate, not a stopwatch figure).
- External services are mocked and the integration code is written for real: that's how the whole end-to-end flow is assembled, from clinic sign-up to reminders.