Реализация управления расписанием специалистов на сайте
Управление расписанием — это инструмент для самих специалистов и администраторов: задать рабочие часы, добавить выходной, поставить блокировку на время встречи, посмотреть кто записался на следующую неделю. Расписание должно быть гибким и не требовать участия разработчика при каждом изменении.
Уровни расписания
Расписание строится из трёх слоёв, каждый следующий перекрывает предыдущий:
1. Базовый шаблон — стандартные рабочие часы по дням недели:
Пн–Пт: 09:00–18:00, слот 60 мин, перерыв 0 мин
Сб: 10:00–14:00, слот 30 мин
Вс: выходной
2. Переопределения дат — конкретная дата работает иначе:
2025-05-09: выходной (праздник)
2025-06-01: 10:00–16:00 (сокращённый день)
2025-07-01–2025-07-14: отпуск
3. Блокировки — закрытые интервалы внутри рабочего дня:
2025-04-15 12:00–13:00: обед
2025-04-16 14:00–15:00: совещание
Интерфейс управления для специалиста
Специалист управляет расписанием через личный кабинет. Ключевые операции:
| Действие | Как реализуется |
|---|---|
| Задать базовые часы | Форма по дням недели с полями start/end/slot |
| Закрыть дату | Клик на дату в календаре → модальное окно → тип: выходной/отпуск |
| Открыть нерабочую дату | Тот же модал, тип: custom hours |
| Добавить блокировку | Drag на временной шкале или форма с датой и временем |
| Посмотреть записи | Недельный calendar view с бронями |
API эндпоинты
GET /api/specialists/{id}/schedule?date=2025-04-15
→ { slots: [...], overrides: [...], blocks: [...] }
GET /api/specialists/{id}/available-slots?from=2025-04-15&to=2025-04-21
→ { "2025-04-15": [{ start, end }], ... }
POST /api/specialists/{id}/overrides
{ override_date: "2025-05-01", type: "day_off" }
POST /api/specialists/{id}/blocks
{ starts_at: "2025-04-16T14:00", ends_at: "2025-04-16T15:00", reason: "Совещание" }
DELETE /api/specialists/{id}/overrides/{override_id}
DELETE /api/specialists/{id}/blocks/{block_id}
PATCH /api/specialists/{id}/schedule/{weekday}
{ start_time: "10:00", end_time: "18:00", slot_duration: 45 }
Массовые изменения (отпуск, праздники)
Отпуск на 2 недели — не 14 отдельных записей, а одна запись с диапазоном:
CREATE TABLE specialist_overrides (
id SERIAL PRIMARY KEY,
specialist_id INTEGER NOT NULL,
date_from DATE NOT NULL,
date_until DATE NOT NULL, -- включительно
override_type VARCHAR(20) NOT NULL, -- 'day_off' | 'vacation' | 'custom_hours'
start_time TIME, -- только для custom_hours
end_time TIME,
created_by INTEGER, -- кто создал: специалист или администратор
reason VARCHAR(255)
);
При генерации слотов диапазоны разворачиваются в отдельные дни в коде, не в БД.
Автоматические праздники
Настройка: при создании расписания можно включить опцию «закрывать государственные праздники автоматически». Список праздников загружается через API (например, calendarific.com) или хранится в таблице настроек с ежегодным обновлением:
def populate_holidays(country: str, year: int):
resp = requests.get(
'https://calendarific.com/api/v2/holidays',
params={'api_key': API_KEY, 'country': country, 'year': year, 'type': 'national'}
)
holidays = resp.json()['response']['holidays']
for h in holidays:
db.execute("""
INSERT INTO public_holidays (country, date, name)
VALUES (%s, %s, %s)
ON CONFLICT DO NOTHING
""", [country, h['date']['iso'], h['name']])
Уведомления об изменениях
Когда специалист закрывает дату, на которую уже есть бронирования — система автоматически:
- Находит все активные брони на закрываемый период
- Отправляет клиентам письмо с извинениями и предложением выбрать другое время
- Переводит брони в статус
needs_reschedule - Уведомляет администратора
def close_date(specialist_id: int, date: date, reason: str):
affected_bookings = get_bookings_for_date(specialist_id, date)
with db.transaction():
create_override(specialist_id, date, 'day_off', reason=reason)
for booking in affected_bookings:
update_booking_status(booking.id, 'needs_reschedule')
send_reschedule_request_email(booking, specialist_id, reason)
notify_admin(specialist_id, booking, 'date_closed')
Экспорт в внешние календари
Специалист может синхронизировать расписание с Google Calendar или Outlook через iCal feed:
GET /api/specialists/{id}/calendar.ics?token={private_token}
Этот URL добавляется в Google Calendar как подписка — обновляется каждые 15 минут автоматически.
Сроки реализации
Базовое управление шаблоном расписания и блокировками, без внешних интеграций — 5–7 рабочих дней. Диапазонные переопределения, автопраздники, уведомления клиентов при закрытии, iCal-экспорт, ролевой доступ (специалист vs администратор) — 9–12 рабочих дней.







