Кейс агентства AiR о разработке мобильного приложения для клиники.

Заказчик

Клиника Претор – это многопрофильная клиника с сетью отделений в Новосибирске, Иркутске и Ахтубинске.

Цели и задачи проекта

Клиника обратила внимание на очевидный современные тренд – люди ценят время и оперативность. Разумеется со стороны клиентов так же появился спрос в этом направлении. Многим лень рыться в почте и искать заветное письмо с результатами исследований и прочими назначениями. Ну или придётся складировать на полочку листочки, в которых также можно запутаться.

А если предстоит многократно посетить врача, то всё это превращается в рутину, которую хочется избежать.

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

  • Личный кабинет для отслеживания прошедших и новых записей к врачу,
  • Хранение итогов посещения врачей в личном кабинете, таких как: назначения, результаты анализов, обследования и тд.,
  • Получение оперативной информации о скидках и спецпредложениях.

В результате у клиента клиники должна появиться своя “цифровая медицинская карта”, где можно оперативно посмотреть всю информацию о планировании и итогах посещения врачей.

Вызовы проекта

  1. Организация передачи данных: Сайт <-> Мобильное приложение <-> МИС (медицинская информационная система);
  2. Организация записи онлайн из Мобильного приложения;
  3. Разработка концепции и механизма для организации быстрой и слаженной работы приложения.

Решения

1. Организация передачи данных Сайт <-> Мобильной приложение <-> МИС

В организации процесса участвуют несколько элементов данных:

  1. Официальный сайт компании;
  2. Мобильное приложение;
  3. МИС (Медицинская информационная система);
  4. Промежуточное API. Специальная программный блок для конвертации разных типов данных между Сайтом/МП и МИС.

В чём сложности?

Если бы данные просто передавались напрямую между Приложением и МИС, то всё было бы относительно просто. Но такая система будет некорректной по причине маршрутизации данных.

В нашем случае информация в приложение должна поступать частично из МИС, частично с сайта, а некоторые данные проходят последовательно обе точки и только затем попадают в МП.

Кроме того, сайт и мобильное приложение воспринимают данные в разных форматах, поэтому на пути от МИС к сайту нам необходимо иметь какой-то конвертер данных под оба формата.

Какое решение?

Сперва проанализировали в каких направлениях и какие данные необходимо передавать между элементами системы (Сайт, приложение, МИС). После это смогли определить маршруты данных между ними. В результате сформулировали организационную схему их передачи:

  • Расписание врачей также хранится в МИС и экспортируется на Сайт и в БД мобильного приложения, преобразовываясь в процессе передачи в удобный формат. Это необходимо, так как БД МИС и API МП/Сайт используют разные форматы данных. Эти данные хранятся и используются независимо друг от друга в обоих элементах.
  • Врачи. Сущности врачей создаются в МИС, но там не хранится ничего кроме их ID, ФИО, должностей и расписания (которое создается и модерируется отдельно на сайте). Эти данные передаются на сайт, где уже контент менеджеры заполняют вручную такие данные как фото врачей, образование, специализации и прочие регалии. Комплекс этих данных уже и передаётся в Мобильное приложение.
  • Данные о записях к врачам и на исследования (будущие и прошедшие), назначения, результаты анализов, обследований и исследований хранятся в МИС и передаются в приложение.
  • Новости и Акции. Создаются на сайте и не хранятся в МИС. Потому здесь организована связка только с сайтом, из которого информация поступает только в МП.

Таким образом контентщики в любой момент просто заполняют данные сущности на сайт и они динамически передаются в мобильное приложение.

Изображение предоставлено агентством AiR с сайта airws.ru

2. Сложности в оптимизации запросов к таблицам. Репликация и механизмы обмена информацией

Для обычного пользователя передача данных выглядит как просто бегающие туда-сюда биты/байты. Но на практике “гладкую” передачу информации нужно ещё и организовать с учётом исходных данных.

Здесь нам потребовалось продумать и организовать пакетную загрузку данных.

В чём сложности загрузки данных?

Допустим в базе 700 000 пациентов. У каждого пациента по 50 анализов. Т.е. одних только анализов получается 35 000 000 штук – и это только в одной таблице базы данных, а таких таблиц – нам нужно несколько, такие как: посещения врачей, назначения, результаты обследования (которое может быть впоследствии ещё связано с назначением) и исследований.

Все эти данные нельзя просто разом и мгновенно переносить между всеми Сайтом, Мобильным приложением и МИС. Если просто напрямую передать все нужные данные, запрос и его ожидание может быть катастрофически долгим. И в итоге получим просто очень медленное приложение, которое клиенты не захотят использовать.

Изображение предоставлено агентством AiR с сайта airws.ru

Какое для этого есть решение?

Чтобы решить данную проблему организовали механизм репликации или – простыми словами – регулярную загрузку.

Это значит, что забираем данные не целиком, а небольшими пакетами данных. И, конечно, организовываем из них (пакетов данных) быстро обрабатываемую очередь. Таким образом данные поступают быстро, а приложение не “зависает”.

Изображение предоставлено агентством AiR с сайта airws.ru

Как это работает?

Рассмотрим это вкратце на примере таблицы с анализами:

Берём только тех пользователей, которые установили приложение и авторизовались в нем. Далее начинаем пакетную загрузку по 10 записей каждые 5 секунд, запоминая ID-репликатор последней загруженной записи.

То есть алгоритм можно записать как:

  1. запрашиваем 10 анализов с (0 по 10)
  2. Получаем и записываем их.
  3. После удачной записи, запоминаем репликатор (ID последнего элемента – в нашем случае это 11)
  4. В следующий раз запросим с (11 по 20)
  5. и так до самого конца, пока шина не ответит нам, что элементов для загрузки более нет.
Изображение предоставлено агентством AiR с сайта airws.ru

Обратим внимание, что процессы обмена по одной и той же сущности (Анализы, Исследования и тд) и не могут происходит параллельно во избежание “перекоса” в импортируемой информации и чрезмерного увеличения нагрузки на сервер МИС. Поэтому процесс импорта реализован так, что запущен может быть только один процесс за раз.

Механизм подгрузки новых анализов, которых еще нет в МП БД/ Процесс проверки обновления данных запускается с определенными промежутками, которые могут увеличиться, если база простаивает (например, ночью).

Очередность импорта в БД мобильного приложения организовывается при помощи сервера очередей RabbitMQ, позволяющего нам последовательно импортировать поступающую информацию.

Результат

Таким образом в фоновом режиме всегда подгружаются данные из МИС в базу данных мобильного приложения и отображаясь в личных кабинетов пользователей. Так обеспечивается оперативное обновление данных на стороне мобильного приложения.

Конечно пользователи этого не знают, но всё это ради того, чтобы они могли наслаждаться быстрым доступом к своим данным ))

3.Регистрация и разовая оперативная подгрузка данных в мобильное приложение из МИС

В чём сложности регистрации?

После регистрации и авторизации нового пользователя необходимо , чтобы его данные быстро оказались в Личном кабинете приложения. Для сохранения оптимальной механики обмена, мы не должны загружать все данные пользователя сразу, т.к. рискуем напороться на уже обозначенные выше проблемы – Мобильное приложение будет “подвисать”.

Какое для этого есть решение?

Чтобы все прошло “как по маслу”, мы запускаем для нового пользователя отдельный обмен внутри отдельной очереди запросов, при этом исключая пользователя из основного обмена до момента полной загрузки информации по нему.

Отдельная история – это механизм идентификации пользователя в МИС. Когда пользователь устанавливает мобильное приложение и переходит к регистрации, то происходит следующий процесс:

  • Пациент вводит свое ФИО, дату рождения и контактные данные.
  • Если мы однозначно можем определить по ним пользователя и более дублей нет – то все ок.
  • Но если какая-то часть данных не совпадает – запускается процесс дополнительной валидации пользователя (о котором подробно мы не можем рассказать по очевидным причинам безопасности), в рамках которого предусмотрено несколько исходов из ситуации.
  • После завершения регистрации – можно переходить к импорту данных пользователя 🙂

Результат

В итоге с помощью дополнительного обмена получаем быструю работу в данной части функций приложения. В противном случае повышали бы нагрузку на сервер и, следовательно, долго бы получали данные после регистрации.

4.Онлайн запись и расписание.

Реализация онлайн записи и поддержание актуальности расписания врачей также потребовали найти путь решения для эффективной работы.

В чём сложности хранения данных?

В МИС расписание не хранится в равномерных ячейках времени, например, с 9 до 18:00 и интервалом 30 минут. Вместо этого есть только данные о том, что врач работает 2 через 2 дня, 1 через 1 день и тд, а также – сколько длится его прием. Однако, задачу облегчает тот факт, что вся совокупность врачей в МИС имеет ограниченный набор правил, который можно зафиксировать и описать на стороне генерации расписания.

Изображение предоставлено агентством AiR с сайта airws.ru

Какое решение?

При загрузке расписания нам нет необходимости выгружать всех врачей разом. Поэтому исключим:

  • Уволенных;
  • В декрете;
  • Особые причины.

Кроме того, у врачей есть различные события: конференции, отпуска и прочие, которые нужно учесть при построении расписания.

Потому выгружаем только врачей, что ведут приемы в данный момент, т.е. врачей с активным расписанием. Таким образом оптимизируется объем расписания и скорость его загрузки.

Итак, формирование расписания конкретных врачей происходит на основании:

  • Типа его расписания (правила);
  • Начала и конца его рабочего времени в каждую из рассчитанных дат в его расписании;
  • Длительности приёма;
  • Уже занятых слотов времени (будущих приемов);
  • Событий, занимающих полезное рабочее время.

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

Сложности формирования временных слотов в расписании

Для примера, если приём длится 25 минут, рабочий день врача начинается в 10:00, а конференция запланирована с 11:00 до 12:15, то мы должны сразу “отсечь” свободный слот в 10:50 и 12:05. Очевидно, он явно накладываются на конференцию, а остальные слоты – 10:00-10:25, 10:25-10:50, 12:30-12:55 и т.д. – показать как доступные, если они не заняты записями или другими событиями.

Изображение предоставлено агентством AiR с сайта airws.ru

Дополнительный момент, усложняющий работу – расписание заполняется не только через онлайн запись: это и несколько администраторских стоек, и колл-центр, также записывающие людей на приемы. А так как расписание актуализируется с некоторыми промежутками, то свободный слот времени может быть быстро занят.

Какое решение?

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

Изображение предоставлено агентством AiR с сайта airws.ru

Результат

Таким образом мы избавляемся от любых конфликтов в расписании Врачей. Делаем запись через приложение к ним лёгким и удобным.