Интеграция расписания и календаря

Автор: Николай СапуновОбновлено: август 202617 мин чтения
Содержание статьи +

Это инженерные рекомендации, а не юридическая консультация. Конкретику уточняйте у квалифицированного юриста.

Кратко

Расписание в телемедицине решает четыре задачи: показать реальное свободное время врача; дать пациенту занять слот так, чтобы двое не заняли его одновременно; напомнить о приёме, чтобы пациент пришёл; синхронизировать всё это с медицинской информационной системой клиники (МИС), ЕГИСЗ и календарём врача. В России записаться можно сразу несколькими путями: через собственное приложение, через Госуслуги (эта запись идёт через федеральную электронную регистратуру – ФЭР ЕГИСЗ), через агрегаторы вроде ПроДокторов, СберЗдоровья и НаПоправку, через колл-центр. Поэтому ведущей системой по слотам должна быть одна, обычно МИС, а сведения о расписании и записях передаются в ФЭР в течение одного рабочего дня. Для модели данных удобен FHIR (Schedule, Slot, Appointment, AppointmentResponse и схема «найти – придержать – подтвердить»), даже если конкретная МИС отдаёт собственный API. Чаще всего расписание ломают две незаметные проблемы: 11 часовых поясов, границы которых меняет закон, и имя пациента в личном календаре врача, то есть разглашение врачебной тайны. Отдельно разберём напоминания, снижающие неявки примерно на треть, и проверку допустимости, которая должна сработать до показа слотов.

Зачем это читать

Расписание кажется простой частью телемед-проекта: виджет календаря, что тут сложного? Из-за этой иллюзии оно так часто выходит за бюджет и подводит в самый неудобный момент. Статья написана для основателя, продакт-менеджера или руководителя ИТ в клинике, которому нужно честно оценить запись: где на самом деле хранится расписание, какие обязанности перед ЕГИСЗ у клиники, что можно писать в напоминаниях и какие две ошибки проектирования (часовые пояса и календарь, через который утекают данные) обязательно всплывут после запуска. Если всё сделано правильно, расписание работает незаметно: пациент и врач встречаются в понятное обоим время, а неявок становится меньше. Если нет – пациента запишут не на тот час, слот окажется занят дважды или имя пациента попадёт в личный календарь врача, и каждая такая ошибка подрывает доверие. Это подробный разбор одного узла карты интеграций телемед-платформы – расписания.

Четыре задачи расписания

Прежде чем говорить о стандартах и API, разберёмся с самой задачей. Расписание телемедицины делает четыре разные вещи, и как минимум две из них команды недооценивают.

Первая – публикация свободного времени: превратить рабочие часы врача, типы приёмов и уже занятое время в свободные слоты для записи. Вторая – запись: дать пациенту занять один из этих слотов так, чтобы второй пациент – из приложения, с Госуслуг или с агрегатора – не занял тот же слот полсекундой позже. Третья – напоминание: напомнить пациенту о приёме, чтобы слот не пропал. Четвёртая – синхронизация: передать каждую запись, перенос и отмену во все системы, которым нужно о них знать: МИС клиники, ФЭР ЕГИСЗ, агрегаторы, календарь врача и учёт оплат.

У каждой задачи свои типичные сбои, и дальше мы разберём их по порядку.

Рисунок 1. Карта интеграций расписания. Движок записи – в центре; у каждой связи свой протокол и свои сроки, а проверка допустимости отсекает неподходящие слоты ещё до того, как их увидит пациент.

Модель данных: четыре ресурса расписания в FHIR

Начнём с хорошей новости: для расписания есть зрелая модель данных. Международный стандарт HL7 FHIR (Fast Healthcare Interoperability Resources) – веб-API, где каждое клиническое понятие – «ресурс» с заданной структурой. Расписание использует четыре ресурса, и они вкладываются друг в друга как матрёшки [1].

Schedule – контейнер, который описывает: «этот врач принимает по такому типу приёма в таком интервале времени». Внутри Schedule лежат ресурсы Slot, каждый – конкретный блок времени со статусом: free, busy, busy-unavailable, busy-tentative или entered-in-error [2]. Свободный Slot – окно, которое пациент может занять. Когда пациент его занимает, вы создаёте Appointment – саму запись, которая проходит свой жизненный цикл статусов: proposed, pending, booked, arrived, fulfilled, cancelled и тот, которого боится любая клиника, – noshow [1]. Наконец, когда запись требует подтверждения от каждого участника – пациента, врача, переводчика, – AppointmentResponse фиксирует согласие или отказ каждой стороны [1].

Итого: Schedule содержит слоты (Slot), свободный Slot превращается в Appointment, участники подтверждают запись через AppointmentResponse. Если вы читали разбор HL7 FHIR, СЭМД и интеграции с МИС на практике, это та же логика ресурсов, только применённая ко времени, а не к клиническим данным.

Рисунок 2. Модель данных расписания в FHIR. Четыре ресурса вложены друг в друга; операции `$find` → `$hold` → `$book` бронируют слот без конфликтов. Это удобная внутренняя модель, даже если МИС отдаёт собственный API.

Процесс записи поверх этих ресурсов тоже описан: руководство Argonaut Scheduling, FHIR-спецификация, не привязанная к конкретному вендору, определяет три операции, которые решают проблему гонки за слот [3]. $find возвращает свободные слоты под запрос пациента; $hold временно резервирует слот, чтобы его не заняли, пока пациент заполняет запись; $book подтверждает бронь. В российской практике FHIR-интерфейс расписания у МИС встречается не так часто, но модель полезна сама по себе: на FHIR работает интеграционная платформа N3.Health, а сообщество HL7 FHIR Россия ведёт профиль RuCore (FHIR R5), в примерах которого есть и Appointment [4][9]. Если построить движок записи на этой модели, каждая новая МИС потребует только адаптера, а не переписывания ядра.

Где хранится расписание: МИС, ФЭР и Госуслуги

Расписание врача почти всегда уже ведётся в МИС клиники – Медиалог, 1С:Медицина, ЕЦП.МИС, ЕМИАС, MEDODS, Renovatio, Инфоклиника, qMS. Платформа, которая заводит параллельное расписание, через месяц получает два расходящихся графика. Поэтому ведущая система по слотам должна быть одна – обычно МИС, а телемед-платформа читает свободное время и создаёт записи через её API. Подробно интеграции с конкретными МИС разобраны в статье «Интеграция с МИС: Медиалог, 1С:Медицина, ЕЦП.МИС, ЕМИАС и другие».

Интерфейсы при этом разные: собственный REST или SOAP API МИС, интеграционные шины, FHIR. Интеграционная шина МедФлекс (МедРокет) соединяет МИС со страховщиками, ЕГИСЗ и агрегаторами – по данным компании, это более 24 тыс. клиник и 152 МИС [10]; у Медиалога заявлены интеграции с ПроДокторов и НаПоправку [8]. Если МИС отдаёт изменения потоком HL7 v2 – сообщениями SIU (SIU^S12 – новая запись, S13 – перенос, S15 – отмена, S26 – неявка, каждое подтверждается ACK), – принимайте их как однонаправленные уведомления: МИС записывает, ваша платформа слушает [5].

Второй слой – ЕГИСЗ. Положение о ЕГИСЗ (ПП № 140) относит к поставщикам сведений медорганизации государственной, муниципальной и частной систем (п. 44 «к»), а сведения о расписании, записях на приём и фактах приёма передаются в федеральную электронную регистратуру (ФЭР) в течение одного рабочего дня [6]. Через ФЭР работает и запись на Госуслугах: граждане в реальном времени записываются на приём и вызывают врача на дом через ЕПГУ (п. 21), а также подают запрос на телемедицинскую консультацию (п. 20); запрос на консультацию и её протокол тоже уходят в ФЭР в течение одного рабочего дня [7]. На практике клиника выполняет эту обязанность через МИС, региональную систему (РЕГИЗ) или интеграционную платформу – N3.Health, например, принимает запись и с портала Госуслуг [9]. Значит, приём, созданный в обход МИС, до ФЭР не дойдёт, и клиника по вашей вине не выполнит свою обязанность.

Третий слой – агрегаторы: ПроДокторов и его МедРокет с API, СберЗдоровье, НаПоправку [11]. Пациент с агрегатора занимает тот же слот, что и пациент из вашего приложения, поэтому агрегатор тоже должен бронировать через ведущую систему, а не по выгрузке расписания раз в час.

Время и часовые пояса: где расписание ломается чаще всего

Следующая проблема ставит в тупик даже опытные команды, и к медицинским стандартам она отношения не имеет. Телемедицина – единственный вид приёма, где пациент и врач регулярно находятся в разных часовых поясах, а в России их одиннадцать: от UTC+2 в Калининграде до UTC+12 на Камчатке и Чукотке [12]. Врач в Москве (UTC+3) и пациент во Владивостоке (UTC+10) расходятся на семь часов, и «приём в 15:00» без указания пояса – это две разные встречи.

Правило скучное, но без исключений: храните всё время в UTC (всемирное координированное время) и переводите его в локальное время каждого участника только при отображении, используя базу часовых поясов IANA – эталонный список зон вроде Europe/Moscow, Asia/Yekaterinburg или Asia/Vladivostok с полной историей их правил [12]. Никогда не храните «15:00» без пояса и никогда не храните фиксированное смещение вроде «UTC+4» или привычное «МСК+1».

Почему не смещение, если на летнее время Россия не переходит с 2011 года? Потому что смещения у нас меняет закон. В октябре 2014 года большинство регионов перевели стрелки на час назад; в 2016 году пояс сменили сразу несколько регионов – среди них Астраханская, Саратовская, Новосибирская, Томская и Сахалинская области; Волгоградская область перешла на UTC+4 в октябре 2018 года и вернулась на UTC+3 в декабре 2020-го [12]. Приём, сохранённый как «UTC+4» до такой смены, после неё незаметно съезжает на час: телефон пациента показывает 15:00, система врача – 14:00, и кто-то из них ждёт в пустой виртуальной приёмной. Храните идентификатор зоны (Europe/Volgograd) и обновляйте tzdata на серверах и в приложениях, а пересчёт сделает база IANA.

Для обмена записями с календарями используется формат iCalendar (IETF RFC 5545) – стандарт файлов .ics, который понимают практически все календарные программы [13]. Часовой пояс в нём задаётся свойством TZID, повторяющиеся приёмы – правилом RRULE, так что серия «каждый второй вторник» описывается одним правилом, а не пятьюдесятью записями [13]. Для двусторонней синхронизации с календарным сервером есть CalDAV (RFC 4791) – протокол доступа к календарям поверх WebDAV [14]. Если обрабатывать пояса по RFC 5545, вы получаете совместимость, отлаженную за десятилетия, вместо самодельного решения.

Гонка за слот: временная бронь и двойная запись

Вторая ловушка проектирования – одновременный доступ. Двое пациентов открывают свободные слоты одного врача – один в вашем приложении, другой на агрегаторе, – оба видят слот «вторник, 15:00», оба нажимают «записаться». Без защиты вы либо запишете двоих в один слот, либо покажете одному из них непонятную ошибку.

Для этого и нужна операция $hold: как только пациент выбрал слот, вы ставите на него временную бронь (Slot получает статус busy-tentative), даёте пару минут на подтверждение, затем бронируете ($book) или возвращаете слот в free [2][3]. В собственном движке ту же идею реализуют блокировкой в БД или атомарной операцией «занять, если ещё свободно»: бронирование должно быть одной транзакцией, которая для второго пациента корректно завершается отказом. Если ведущая система – МИС, временную бронь нужно ставить в МИС, а не в вашей копии расписания, иначе Госуслуги и агрегаторы о ней не узнают. Если МИС не поддерживает временную бронь, договоритесь о квотах: часть слотов отдаётся только телемед-каналу, часть – только внешним каналам. Тогда пользователь видит честное «Это время только что заняли – вот ближайшие свободные окна», а врач не обнаруживает двух пациентов на одно время в момент приёма.

Напоминания, которые снижают неявки: расчёт

Забронированный слот, о котором пациент забыл, хуже пустого: врач держал время и ничего не заработал. Напоминания – функция расписания с самой высокой отдачей, и эффект от неё измерим. Систематический обзор в Journal of Telemedicine and Telecare показал, что SMS-напоминания снижают неявку в среднем примерно на 38% – больше, чем любое другое одиночное вмешательство [15]. Рандомизированное исследование в The Permanente Journal показало, что адресные SMS-напоминания значимо сокращают пропуски приёмов по сравнению с их отсутствием [16].

Посчитаем: именно расчёт обосновывает затраты на разработку. Пусть врач проводит 40 телемед-приёмов в неделю при средней стоимости приёма 10 000 ₽ и типичной неявке 23%:

40 приёмов × 23% неявки = ~9 пропусков/нед.
9 пропусков × 10 000 ₽ = 90 000 ₽/нед. удержанного, но не оплаченного времени

Добавим напоминания, которые снижают неявки на ~38%:

9 пропусков × 38% возврата = ~3,4 приёма возвращено/нед.
3,4 × 10 000 ₽ = 34 000 ₽/нед., или ~1,8 млн ₽/год на врача

Напоминания многократно окупаются даже на одном враче. Цифры условные – подставьте свою стоимость приёма и долю неявок, – но вывод не меняется: напоминания стоят дёшево, а возвращённая выручка велика.

Рисунок 3. Расчёт неявок. Напоминания возвращают около трети пропусков: время, которое врач держал впустую, снова превращается в оказанную помощь. Это самый наглядный пример окупаемости в расписании.

Что разрешают 152-ФЗ, врачебная тайна и закон о рекламе

Здесь три правила, и все касаются содержания напоминаний, а не самого факта отправки. Первое – основание обработки. Сведения о здоровье – специальная категория персональных данных (ст. 10 152-ФЗ), но медорганизация вправе обрабатывать их в медицинских целях без согласия, если это делают лица, обязанные хранить врачебную тайну [17]. Подрядчик, рассылающий напоминания по поручению клиники, собственного согласия пациента не получает (ст. 6 ч. 4), но работает строго в рамках поручения [18]. Если пациент пользуется вашей платформой напрямую, без клиники-оператора, – нужна своя правовая основа, вплоть до письменного согласия.

Второе – врачебную тайну составляет уже сам факт обращения (ст. 13 323-ФЗ) [19]. «У вас приём во вторник в 15:00» – нормально. «Ваша консультация онколога во вторник» – уже раскрытие тайны любому, кто увидит экран блокировки, да и SMS-шлюзу тоже. Ограничьтесь временем, ссылкой и нейтральным словом «консультация»: SMS не шифруются, а SMS-провайдер – ещё один подрядчик, который должен работать по договору-поручению.

Третье – закон о рекламе. Реклама по сетям электросвязи допускается только с предварительного согласия абонента; если рекламораспространитель не докажет, что согласие получено, реклама считается распространённой без него, а по требованию абонента рассылку нужно немедленно прекратить (ч. 1 ст. 18 38-ФЗ) [20]. Информационное напоминание о записи рекламой не является – но ровно до тех пор, пока в него не дописали «а ещё скидка 20% на чекап». Держите напоминания и маркетинг в разных потоках, с разными согласиями и раздельным учётом отписок.

Календарь врача и врачебная тайна

Эта ошибка удивляет команды сильнее всего, потому что выглядит как удобная функция. Вы даёте врачам синхронизировать телемед-приёмы с личным облачным календарём через iCalendar-подписку или CalDAV. Технически это просто, но с точки зрения закона проблема серьёзная.

Запись с именем пациента и причиной приёма во внешнем календаре – это персональные данные о здоровье и врачебная тайна у третьего лица. С сервисом, где у врача личный аккаунт, у клиники нет ни договора, ни поручения на обработку: данные пациента переданы без законного основания. Если серверы календарного сервиса стоят за рубежом, добавляется нарушение локализации: с 1 июля 2025 года запись и хранение персональных данных граждан РФ в зарубежных базах прямо запрещены (ч. 5 ст. 18 152-ФЗ), штраф для юрлица – до 6 млн ₽, за повторное нарушение – до 18 млн ₽ [17][21]. Шифрование соединения этого не исправляет.

Корректных решений два. Либо синхронизация идёт в корпоративный календарь внутри контура: календарный сервер клиники или сервис, данные которого хранятся в России, а с поставщиком заключён договор с поручением на обработку ПДн (ст. 6 ч. 3 152-ФЗ) [18]. Либо – лучше и проще – вы обезличиваете запись в календаре: отправляете только блок «Телемед-приём» с непрозрачным ID, а личность пациента держите внутри платформы, куда врач переходит по ссылке после авторизации. Врач видит занятое время в своём календаре, а имена пациентов не покидают контур. Отдельно проверьте ICS-подписки: «секретная» ссылка на ленту календаря открывается любым, у кого она оказалась, – ещё один довод в пользу обезличенных блоков. Договорная сторона разобрана в статье о поручении обработки ПДн и договорах с подрядчиками, основы – в материале «152-ФЗ и врачебная тайна простым языком».

Рисунок 4. Граница календаря. Личность пациента остаётся внутри контура платформы; внешний календарь получает только обезличенный блок «Телемед-приём» – или сам находится внутри контура по договору-поручению с хранением в России.

Проверка допустимости до показа слотов

Это правило важнее всех остальных, и его легко упустить: юридическое ограничение здесь маскируется под настройку расписания. Лицензия на медицинскую деятельность в России действует на всей территории страны, отдельной «телемедицинской» лицензии нет. Но телемедицинскую помощь можно оказывать только по работам и услугам, включённым в лицензию клиники (п. 4 приказа 193н), а врач должен быть внесён в ФРМР, организация – в ФРМО (п. 9) [22]. Главный фильтр, однако, – режим консультации. «Врач – пациент» по ч. 2 ст. 36.2 323-ФЗ допускается только для профилактики, сбора жалоб и анамнеза, оценки эффективности лечения и наблюдения, а также для решения о необходимости очного приёма; скорректировать лечение лечащий врач может, только если диагноз поставлен и лечение назначено на очном приёме (ч. 3) [23]. Поставить диагноз дистанционно без очного приёма нельзя (п. 40 193н) [22].

Для расписания это значит, что тип приёма – не формальность. «Первичный онлайн-приём с постановкой диагноза» предлагать нельзя; «нужен ли очный приём», «повторная консультация после очного приёма» и «дистанционное наблюдение» – можно, с разными правилами. Проверять это нужно до показа слотов: был ли очный приём по этому обращению (это знает МИС), есть ли услуга в лицензии, внесён ли врач в ФРМР. Идентификация участников телемедконсультации – через ЕСИА (ч. 6 ст. 36.2, п. 7 193н), поэтому «Войти через Госуслуги» разумно просить уже при записи, а не за минуту до приёма [22][23]. И ещё одна обязанность ложится прямо на экран записи: до консультации пациенту на сайте или в приложении раскрывают лицензию, сведения о консультанте, оператора информационной системы и место хранения материалов, порядок идентификации и стоимость (п. 37 193н) [22]. Подробнее о лицензиях, регистрах и особых направлениях – в статье «Лицензия, аккредитация врачей, рецепты и особые направления», о входе через ЕСИА – в материале об идентификации через ЕСИА, SSO и регистрах ФРМР/ФРМО.

Перенос и отмена: что важнее самой записи

Записаться пациент может и на демо, а качество продукта видно по переносам и отменам. Пациенты меняют планы, врачей срочно вызывают к экстренным больным, и расписание, которое плохо справляется с изменениями, порождает поток обращений в поддержку. Помогают три правила. Первое: перенос – атомарная операция, а не «отменить и записать заново»: при таком подходе старый слот на мгновение освобождается, и его может занять кто-то другой. Придержите новый слот, прежде чем отпустить старый. Второе: каждое изменение должно дойти до всех синхронизируемых систем – МИС, ФЭР (через МИС, в пределах того же рабочего дня), агрегатора, если запись пришла оттуда, календаря, напоминаний и учёта оплат, – иначе данные разойдутся. Статусы FHIR Appointment (cancelled, noshow) и сообщение об отмене SIU^S15 для того и существуют, чтобы зависимые системы узнали об изменении [1][5]. Если приём был оплачен заранее, отмена запускает возврат – со всеми последствиями для кассы, которые разобраны в статье о платежах, ДМС, ОМС и фискализации. Третье: отмена должна снимать запланированные напоминания, иначе пациент получит напоминание о приёме, которого больше нет. Ошибка мелкая, но для пациента выглядит как небрежность.

Где здесь Фора Софт

Фора Софт с 2005 года разрабатывает системы видеосвязи в реальном времени и ПО для клиник. В телемедицине расписание – место, где сходятся два незаметных риска: часовые пояса и календарь, через который имя пациента уходит за пределы контура. Запись мы проектируем так, чтобы требования закона выполнялись в первую очередь: проверка режима консультации, лицензии и регистров срабатывает до того, как предложен слот; время приёмов хранится в UTC с зонами IANA; внешние календари получают обезличенный блок, а не имя пациента. В интеграциях ведущей системой делаем МИС, бронируем через её API или шину вроде МедФлекс, а записи с Госуслуг и агрегаторов сводим в те же слоты. В итоге запись пациента видит каждая подключённая система, включая ФЭР.

Главное

  • Расписание – это четыре задачи: публикация свободного времени, запись, напоминание и синхронизация.
  • Ведущая система по слотам – одна, обычно МИС; Госуслуги, агрегаторы и ваше приложение бронируют через неё.
  • Сведения о расписании и записях передаются в ФЭР ЕГИСЗ в течение одного рабочего дня, и частные клиники тоже относятся к поставщикам сведений.
  • FHIR Schedule → Slot → Appointment → AppointmentResponse и операции find/hold/book – хорошая внутренняя модель.
  • В России 11 часовых поясов, и закон их меняет: храните UTC и ID зоны IANA, а не «МСК+N».
  • Напоминания снижают неявки примерно на 38%; в тексте – время и ссылка, без специальности и диагноза.
  • Имя пациента в личном календаре врача – разглашение врачебной тайны: обезличьте запись или держите календарь в контуре.

Что читать дальше

Строите такую систему?

Подберём параметры кодирования под ваш контент и посчитаем стоимость доставки до старта разработки.