Ветклиника: карточки животных и напоминания о прививках без абонплаты за врача
Открыли второго врача — и облачная ветеринарная система молча пересчитала счёт в большую сторону. Ещё через полгода взяли третьего на полставки, потом ассистента с отдельным логином — и абонплата выросла уже вдвое против той, что была при открытии клиники. Проблема не в конкретном сервисе, а в самой модели "подписка за рабочее место": чем успешнее клиника, тем больше она платит за то же самое ПО. Ниже — как перенести карточки животных-пациентов и напоминания о прививках на свой сервер, чтобы плата зависела от объёма данных, а не от количества людей в белых халатах.
Содержание
- Абонплата "за врача": как устроено ценообразование облачных ветеринарных систем
- Что должно быть в карточке пациента-животного и истории приёмов
- Своя база вместо чужого SaaS: архитектура на PostgreSQL и веб-морда
- Напоминания о прививках и приёмах: cron, бот, рассылка — без платы за уведомление
- Резервные копии, доступ по ролям и то, что нельзя терять
- Экономика: свой сервер против растущей подписки на штат врачей
Абонплата "за врача": как устроено ценообразование облачных ветеринарных систем
Почти все облачные системы для ветклиник построены на модели "цена за пользователя" или "цена за рабочее место в месяц". Логика понятна с точки зрения вендора: чем больше клиника, тем больше она может заплатить, и биллинг растёт сам, без дополнительных продаж. Для клиники это означает обратное — рост штата напрямую бьёт по марже.
Возьмём типичный сценарий. Клиника открывается с одним-двумя врачами и платит за минимальный тариф. Через год-два в штате уже четыре-пять врачей, плюс ассистенты, плюс администратор на ресепшене, которому тоже нужен доступ к карточкам хотя бы для записи. Каждое такое рабочее место — это либо отдельная лицензия, либо переход на более дорогой тарифный план с более высоким порогом по числу пользователей. В деньгах это часто выглядит так, что рост штата на треть даёт рост счёта за софт вдвое: клиника перескакивает в следующий ценовой сегмент целиком, а не платит "за одного дополнительного человека".
Второй нюанс — от этой платы нельзя отказаться частично. Если вы держите пять врачей, но троих из них в конкретный день нет на смене, льготы за это не будет — тариф считается по факту заведённых аккаунтов, а не по факту использования. То же самое с сезонностью: у многих ветклиник летом и в праздники поток выше, чем зимой, но подписка на CRM не умеет "дышать" вместе с загрузкой.
Третий момент — данные. Карточки животных, история прививок, результаты анализов и снимки годами накапливаются внутри чужой системы. Формально это ваши данные, но физически они лежат на серверах вендора, и выгрузка при смене поставщика — отдельная головная боль: не все системы отдают полный экспорт в удобном формате, а снимки могут выгружаться отдельно от текстовых карточек.
Если попробовать сравнить логику этого рынка с другими нишами, она похожа на то, что происходит в автосервисах: там тоже облачная CRM тарифицируется за число мастеров, и мы разбирали похожий расчёт в статье про облачную CRM на четырёх мастеров и свой сервер — суть та же, меняется только предметная область.
Что должно быть в карточке пациента-животного и истории приёмов
Прежде чем проектировать замену, стоит честно списать, что вообще нужно от системы учёта пациентов в ветклинике — без привязки к конкретному продукту.
Минимальный набор данных на карточку животного:
- вид, порода, пол, дата рождения (или примерный возраст), окрас, особые приметы;
- владелец и контакты — телефон, желательно мессенджер для напоминаний;
- вес в динамике — критично для дозировки препаратов;
- прививки: какая, когда, каким препаратом, дата следующей ревакцинации;
- обработки от паразитов — отдельная лента с датами следующей обработки;
- история приёмов: дата, врач, жалобы, диагноз, назначения;
- хронические состояния и аллергии — видно врачу с первого экрана, а не искать по истории;
- прикреплённые файлы: снимки, результаты анализов, заключения.
Ключевая мысль в том, что 90% этого — обычные реляционные данные: животное, владелец, приём, назначение, прививка. Никакой экзотики, которая требовала бы специализированной СУБД или облачной инфраструктуры конкретного вендора. Это задача, для которой десятилетиями существует связка "таблицы + внешние ключи", и она прекрасно живёт на обычном сервере.
Отдельно стоит продумать роли доступа: врач видит полную карточку и историю, администратор на ресепшене — контакты, расписание и статус прививок для записи, но не обязательно медицинские детали, а владелец клиники — сводную аналитику по потоку и загрузке врачей. Это стандартная задача ролевой модели доступа (RBAC), решаемая на уровне приложения или ролей в самой СУБД.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверСвоя база вместо чужого SaaS: архитектура на PostgreSQL и веб-морда
Технически для замены облачной ветеринарной CRM не нужен монстр — нужна аккуратная база данных и тонкий веб-интерфейс поверх неё. Рабочая схема, которая закрывает 90% практических случаев:
[Врачи, ресепшн] --HTTPS--> [Nginx + веб-приложение] --> [PostgreSQL]
|
+--> [Файловое хранилище: снимки, документы]
|
+--> [Планировщик напоминаний]
Ядро — PostgreSQL. База хорошо ложится на нормализованную схему:
CREATE TABLE owners (
id SERIAL PRIMARY KEY,
full_name TEXT NOT NULL,
phone TEXT NOT NULL,
telegram_chat_id BIGINT,
email TEXT
);
CREATE TABLE animals (
id SERIAL PRIMARY KEY,
owner_id INT REFERENCES owners(id),
species TEXT NOT NULL,
breed TEXT,
sex TEXT,
birth_date DATE,
weight_kg NUMERIC(5,2),
notes TEXT
);
CREATE TABLE visits (
id SERIAL PRIMARY KEY,
animal_id INT REFERENCES animals(id),
vet_name TEXT NOT NULL,
visit_date TIMESTAMP DEFAULT now(),
complaint TEXT,
diagnosis TEXT,
treatment TEXT
);
CREATE TABLE vaccinations (
id SERIAL PRIMARY KEY,
animal_id INT REFERENCES animals(id),
vaccine_name TEXT NOT NULL,
given_date DATE NOT NULL,
next_due_date DATE,
vet_name TEXT
);
Поверх такой базы веб-интерфейс — это набор форм и списков: карточка животного, лента приёмов, форма записи вакцинации с автоматическим расчётом следующей даты. Писать это с нуля необязательно — многие команды берут готовый low-code конструктор форм или лёгкий self-hosted CRM-фреймворк и настраивают поля под ветеринарную специфику. Если в клинике есть разработчик или подрядчик на аутсорсе, простое CRUD-приложение на связке "PostgreSQL + веб-фреймворк" — задача на несколько недель, а не на полгода.
Важный практический момент — регион размещения сервера. Если у клиники сеть точек в разных городах или врачи консультируют удалённо, имеет смысл держать сервер там, откуда быстрее и стабильнее идёт основной трафик, и учитывать требования к хранению данных клиентов — контактов и телефонов владельцев животных, которые формально являются персональными данными, даже если сами животные под такое регулирование не подпадают.
Установка PostgreSQL на чистый сервер — стандартная и хорошо задокументированная процедура, мы разбирали её пошагово в статье про установку и настройку PostgreSQL на VPS — оттуда можно взять базовые команды и применить их к серверу под ветклинику.
Напоминания о прививках и приёмах: cron, бот, рассылка — без платы за уведомление
Второй кусок боли — это не хранение данных, а автоматические напоминания: клиника должна сама, без ручной работы администратора, напомнить владельцу, что через неделю ревакцинация, а через месяц — плановый осмотр. В облачных системах это обычно завязано на тот же тариф "за место" или продаётся отдельным модулем с лимитом на число сообщений в месяц.
На своём сервере это решается связкой из трёх частей: запрос к базе, который каждый день ищет "горящие" даты, канал доставки (Telegram-бот, SMS-шлюз или e-mail) и планировщик, который всё это запускает по расписанию.
Запрос, который находит животных с прививкой через 3 дня:
SELECT a.id, a.species, o.full_name, o.telegram_chat_id, v.vaccine_name, v.next_due_date
FROM vaccinations v
JOIN animals a ON a.id = v.animal_id
JOIN owners o ON o.id = a.owner_id
WHERE v.next_due_date = CURRENT_DATE + INTERVAL '3 days';
Скрипт-обвязка (Python, псевдокод — берите актуальные версии пакетов на момент установки):
import psycopg2, requests
conn = psycopg2.connect("dbname=vetclinic user=vetapp")
cur = conn.cursor()
cur.execute("""
SELECT o.telegram_chat_id, v.vaccine_name
FROM vaccinations v
JOIN animals a ON a.id = v.animal_id
JOIN owners o ON o.id = a.owner_id
WHERE v.next_due_date = CURRENT_DATE + INTERVAL '3 days'
AND o.telegram_chat_id IS NOT NULL
""")
for chat_id, vaccine in cur.fetchall():
text = f"Напоминаем: через 3 дня плановая прививка ({vaccine}) для вашего питомца."
requests.post("https://api.telegram.org/bot<TOKEN>/sendMessage",
json={"chat_id": chat_id, "text": text})
И задача в cron, которая запускает это каждое утро:
0 9 * * * /usr/bin/python3 /opt/vetclinic/reminders.py >> /var/log/vet-reminders.log 2>&1
Дальше это можно усложнять: отдельная лента для напоминаний об обработке от паразитов, повторное напоминание, если владелец не записался в течение суток, SMS как резервный канал для тех, у кого нет Telegram. Принципиально важно другое — цена этой части не растёт с числом врачей и не упирается в лимит сообщений вендора. Она зависит только от канала доставки: Telegram Bot API практически без ограничений для такого объёма, а SMS-шлюз тарифицируется линейно от числа сообщений, а не от числа врачей.
Похожую задачу — запись и напоминания без привязки к числу рабочих мест — мы разбирали для другой сферы услуг в статье про онлайн-запись и напоминания в мессенджер для автосервиса: архитектура там почти дословно переносится на ветклинику, меняются только поля в карточке.
Резервные копии, доступ по ролям и то, что нельзя терять
Перенос данных на свой сервер снимает вопрос абонплаты, но добавляет ответственность, которую раньше молча нёс вендор SaaS: резервное копирование и контроль доступа теперь на стороне клиники.
С резервными копиями всё стандартно для PostgreSQL — ежедневный pg_dump (или pg_basebackup для крупной базы) с копированием архива на отдельное хранилище, не на тот же диск, где стоит боевая база. Минимальный рабочий вариант:
#!/bin/bash
DATE=$(date +%Y-%m-%d)
pg_dump -U vetapp vetclinic | gzip > /backups/vetclinic-$DATE.sql.gz
find /backups -name "vetclinic-*.sql.gz" -mtime +30 -delete
Этот же скрипт по cron, плюс копия архива на внешнее хранилище (второй сервер, объектное хранилище, минимум — другой диск) закрывает базовый сценарий "сгорел диск — не потеряли карточки животных за пять лет". Разбор более серьёзных инструментов резервного копирования баз данных — в статье про автоматизацию резервного копирования баз данных, если объём данных клиники вырастет настолько, что простого dump'а станет мало.
По доступу — минимум с первого дня:
- отдельный логин на каждого врача и администратора, без общих паролей "на всю ресепшен";
- ограничение прав на уровне ролей PostgreSQL или приложения — администратор не должен иметь возможность стереть историю приёмов;
- журнал изменений (кто и когда правил диагноз или дату вакцинации) — защита клиники в спорной ситуации с владельцем животного;
- HTTPS с самого начала, а не "добавим сертификат потом" — карточки с контактами владельцев не должны утекать в перехваченном трафике.
Здесь же стоит трезво оценить обратную сторону перехода: с собственным сервером клиника берёт на себя обновления системы, мониторинг места на диске и реакцию на сбои. Если своего айтишника в штате нет, разумный компромисс — простая конфигурация (одна СУБД, один сервер приложения, без микросервисов) и подрядчик на несколько часов в месяц для планового обслуживания, а не полноценный ИТ-отдел ради базы карточек животных.
Экономика: свой сервер против растущей подписки на штат врачей
Смысл всей затеи — сделать так, чтобы стоимость инфраструктуры не зависела от того, сколько врачей вы наняли в этом квартале. Ниже — не измеренные цифры конкретного вендора (их мы намеренно не приводим, у каждой облачной системы своя сетка), а логика сравнения, по которой стоит считать применительно к вашей клинике.
| Параметр | Облачная система "за место" | Своя база на сервере |
|---|---|---|
| От чего зависит цена | Число врачей/аккаунтов | Мощность сервера (CPU, RAM, диск) |
| Рост при найме нового врача | Прямой рост счёта, часто скачком через тарифный план | Не меняется, пока хватает ресурсов сервера |
| Лимит на напоминания | Часто есть отдельный лимит сообщений в месяц | Ограничен только каналом доставки (Telegram/SMS) |
| Экспорт данных при уходе | Зависит от вендора, не всегда полный | Полный — это ваша база |
| Кто отвечает за бэкапы и аптайм | Вендор | Клиника (сама или через подрядчика) |
| Разовые затраты | Минимальные, входит в подписку | Разработка/настройка интерфейса и миграция данных |
Практический ориентир: если в клинике один-два врача, чужая облачная CRM почти всегда выгоднее — тариф минимальный, а разработка своей системы стоит дороже, чем несколько лет подписки. Порог, где расчёт переворачивается, обычно наступает тогда, когда число оплачиваемых мест в облачной системе (врачи плюс ассистенты плюс ресепшен) переваливает за пять-семь и продолжает расти — именно тогда фиксированная стоимость сервера начинает обгонять растущую подписку.
Стоит закладывать и разовые затраты на переход: перенос исторических карточек из старой системы, обучение персонала новому интерфейсу и период, когда обе системы работают параллельно, пока не убедитесь, что новая считает прививки и напоминания корректно. Это разовые расходы — в отличие от абонплаты, которая продолжает расти вместе со штатом каждый следующий год.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Нужно ли отдельное "медицинское" ПО, или обычная база данных подойдёт?
Для карточек пациентов-животных, истории приёмов и напоминаний обычной реляционной базы вроде PostgreSQL достаточно — это стандартная транзакционная нагрузка без экзотических требований. Специализированное ветеринарное ПО добавляет готовый интерфейс и типовые справочники (породы, препараты), но технически задача решается и без него.
Что делать с уже накопленными карточками в старой облачной системе при переходе?
Экспортировать данные, пока действует подписка — большинство систем дают выгрузку в CSV или похожем формате хотя бы для основных таблиц. Снимки часто нужно выгружать отдельно от текстовых карточек — это стоит проверить заранее, а не в последний день перед отключением старого сервиса.
Можно ли давать доступ к карточкам самим владельцам животных, а не только персоналу?
Да, это отдельный слой поверх той же базы — личный кабинет с урезанными правами только на карточки своих питомцев. Архитектуру это не меняет, но добавляет требования к безопасности внешнего доступа, и стоит проектировать это сразу, если такая функция планируется.
Что произойдёт с напоминаниями, если сервер уйдёт в перезагрузку или упадёт на несколько часов?
Cron-задача выполнится с опозданием при следующем запуске сервера — рассылка не потеряется, а сдвинется по времени. Для критичных сценариев стоит держать мониторинг доступности сервера, чтобы простой не растягивался на сутки и не срывал напоминание о прививке.
Сколько ресурсов сервера реально нужно для базы клиники на несколько врачей?
Зависит от числа животных в базе, объёма приложенных файлов и интенсивности одновременных подключений — для клиники среднего размера обычно достаточно скромного VPS, но точную конфигурацию стоит подбирать под фактический объём данных, а не по общему шаблону.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →