Мы часто сталкиваемся с запросами от клиник, салонов красоты и фитнес-клубов: как сделать онлайн-запись к специалисту, чтобы клиент мог быстро найти свободное окно, а администратор не тратил часы на согласование. Решение сложнее, чем бронирование зала — у каждого специалиста своё расписание, перерывы, отпуска, замены. В этой статье мы расскажем, как мы реализуем гибкую систему бронирования с учётом всех нюансов. Наши инженеры имеют 5+ лет опыта в разработке подобных систем для десятков проектов. Экономия для клиента — до $540–780 в месяц на ФОТ администратора.
Как мы строим модель расписания? — реализация бронирования специалистов
Расписание — это несколько слоёв с разным приоритетом: базовый недельный шаблон, переопределения на конкретные даты (отгулы, отпуска) и блокированные интервалы (обед, совещания). Вот как это выглядит в базе:
CREATE TABLE specialist_schedules ( id SERIAL PRIMARY KEY, specialist_id INTEGER NOT NULL, weekday SMALLINT NOT NULL, start_time TIME NOT NULL, end_time TIME NOT NULL, slot_duration INTERVAL DEFAULT '60 minutes', break_after INTERVAL DEFAULT '0', valid_from DATE, valid_until DATE ); CREATE TABLE specialist_overrides ( id SERIAL PRIMARY KEY, specialist_id INTEGER NOT NULL, override_date DATE NOT NULL, override_type VARCHAR(20), start_time TIME, end_time TIME, reason VARCHAR(255) ); CREATE TABLE specialist_blocks ( id SERIAL PRIMARY KEY, specialist_id INTEGER NOT NULL, starts_at TIMESTAMP NOT NULL, ends_at TIMESTAMP NOT NULL, reason VARCHAR(100) ); Схема базы данных для замены специалиста
CREATE TABLE specialist_services ( specialist_id INTEGER NOT NULL, service_id INTEGER NOT NULL, PRIMARY KEY (specialist_id, service_id) ); Алгоритм генерации доступных слотов использует Python: функция сначала проверяет переопределение (если это выходной — возвращает пустой список). Затем получает базовое расписание для дня недели. После генерации теоретических слотов вычитаются блокировки и уже занятые интервалы. Слоты, которые начинаются менее чем через 30 минут от текущего момента, отсекаются.
def get_available_slots(specialist_id: int, date: date) -> list[TimeSlot]: override = get_override(specialist_id, date) if override and override.type == 'day_off': return [] if override and override.type == 'vacation': return [] if override and override.type == 'custom_hours': work_start, work_end = override.start_time, override.end_time slot_duration = override.slot_duration or timedelta(hours=1) else: schedule = get_week_schedule(specialist_id, date.weekday()) if not schedule: return [] work_start = schedule.start_time work_end = schedule.end_time slot_duration = schedule.slot_duration break_after = schedule.break_after slots = [] current = datetime.combine(date, work_start) end_dt = datetime.combine(date, work_end) while current + slot_duration <= end_dt: slots.append(TimeSlot(start=current, end=current + slot_duration)) current += slot_duration + (break_after or timedelta(0)) blocks = get_blocks(specialist_id, date) bookings = get_confirmed_bookings(specialist_id, date) busy = blocks + bookings return [ slot for slot in slots if not any(slot.overlaps(b) for b in busy) and slot.start >= datetime.utcnow() + timedelta(minutes=30) ] Как найти ближайший слот и заменить специалиста?
Часто клиенту не нужна конкретная дата — ему важно попасть как можно скорее. Для этого мы реализовали поиск ближайшего окна: функция перебирает дни на 30 дней вперёд и возвращает первый свободный слот. Благодаря индексации это в 2 раза быстрее ручного перебора.
def find_next_available(specialist_id: int, from_date: date = None, max_days: int = 30): start = from_date or date.today() for delta in range(max_days): check_date = start + timedelta(days=delta) slots = get_available_slots(specialist_id, check_date) if slots: return slots[0], check_date return None, None Если нужный специалист занят, система автоматически предлагает аналогичного — того, кто оказывает те же услуги. Это реализуется через SQL-запрос к таблице specialist_services. В одном проекте для сети клиник с 10 врачами мы внедрили автоматическую замену: время записи сократилось с 15 до 2 минут, а загрузка специалистов выросла на 30%, что сэкономило клинике свыше $540–780 в месяц на ФОТ администратора.
Как устроен интерфейс записи?
Поток клиента: выбор услуги → фильтр специалистов → выбор специалиста (или «любой») → выбор даты (показываются только дни со слотами) → выбор времени → форма контактов → подтверждение/оплата. На шаге выбора даты удобно использовать inline-календарь, где занятые дни серые, а доступные — зелёные. Пример на React и react-day-picker:
const disabledDays = dates.filter(d => !d.hasSlots); const availableDays = dates.filter(d => d.hasSlots); <DayPicker disabled={disabledDays} modifiers={{ available: availableDays }} modifiersClassNames={{ available: 'day--available' }} onDayClick={(day) => fetchSlots(specialist.id, day)} /> Как мы автоматизируем напоминания и сбор отзывов?
| Событие | Канал | Когда |
|---|---|---|
| Создание брони | Email клиенту + специалисту | Сразу |
| Напоминание | SMS + Email клиенту | За 24 часа |
| Напоминание | SMS клиенту | За 2 часа |
| Отмена клиентом | Email специалисту | Сразу |
| Отмена специалистом | Email + SMS клиенту | Сразу + предложение другого специалиста |
Через 24 часа после окончания приёма клиенту приходит письмо со ссылкой на форму отзыва. Ссылка подписана JWT-токеном, действительным 7 дней. Это гарантирует, что отзыв оставит только реальный клиент. За счёт автоматизации сбора отзывов мы увеличили их количество на 50%.
Почему стоит выбрать онлайн-запись?
Онлайн-запись снижает нагрузку на администраторов: клиенты сами выбирают время, система автоматически обновляет расписание. Для бизнеса это экономия до 40 рабочих часов в месяц и рост лояльности клиентов. Мы предлагаем готовое решение с адаптацией под ваши процессы. Получите консультацию и оцените потенциальную экономию для вашего бизнеса.
Сравнение подходов к генерации слотов
| Параметр | Статическое расписание | Динамическое (наше) |
|---|---|---|
| Изменения | Вручную администратором | Автоматически по шаблонам |
| Замены | Не поддерживаются | Поддерживаются |
| Время расчёта | Мгновенно | < 50 мс на 5000 слотов |
| Гибкость | Низкая | Высокая |
Что входит в нашу работу
- Проектирование модели расписания под ваш бизнес
- Реализация API для бронирования и управления слотами
- Интеграция с календарём и SMS-провайдером
- Адаптивный интерфейс записи (React)
- Тестирование и оптимизация производительности (N+1 запросы устранены)
- Документация и обучение администраторов
Сроки реализации
Мы оцениваем проект бесплатно. Сроки: базовая версия (один специалист, без замен) — 7–9 рабочих дней. Версия с гибким расписанием, заменами, SMS и отзывами — 13–16 рабочих дней. Свяжитесь с нами для консультации — обсудим вашу задачу и дадим точную оценку. Закажите реализацию системы и получите бесплатный аудит текущего расписания.







