#Глоссарий

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

#Участники

Термин Что означает
МИС Медицинская информационная система, в которой вы ведёте карту пациента
Бэкенд МИС Ваш сервер. На сервере хранятся секреты. С сервера идут запросы к smartica.ai. Браузер врача в эту роль не годится
Браузер врача Открывает только готовую ссылку, которую выдал ваш бэкенд. Браузер врача не получает ключи
smartica.ai Наш сервис записывает и расшифровывает разговор. Затем сервис заполняет поля протокола

#Ключевые понятия

#Сценарий Launch и Import

Сценарий показывает, с чего начался приём.

#Доставка push и pull

Доставка показывает, как готовый протокол попадает в МИС. Доставка от сценария не зависит.

  • push. При push smartica.ai сама вызывает ваш PUT, когда протокол готов. Для push нужен endpoint, доступный извне.
  • pull. При pull ваша МИС спрашивает у smartica.ai, готов ли протокол. МИС забирает протокол. МИС подтверждает получение. Входящие соединения не нужны.

Режим задаётся один раз при подключении.

#SSO

Single Sign-On означает «сквозной вход». Врач нажимает кнопку в МИС. Врач попадает в smartica.ai уже авторизованным, без ввода логина и пароля. Ваш бэкенд просит у smartica.ai одноразовую ссылку. Бэкенд открывает ссылку врачу.

#Идемпотентность

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

Пример: smartica.ai дважды присылает один и тот же PUT с протоколом. Идемпотентная МИС во второй раз обновляет уже существующий приём и возвращает успех. Неидемпотентная МИС создаёт вторую карточку. В карте пациента появляется дубль.

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

  • Врач нажимает «отправить заново».
  • Врач дописывает приём.
  • smartica.ai генерирует протокол заново.

Ключом операции служит encounter_id. Заголовка Idempotency-Key в контракте нет.

#Ревизия (revision)

Ревизия нумерует заполненный протокол. Номер начинается с 0. Номер растёт каждый раз, когда smartica.ai перезаполняет протокол, например когда врач дописывает приём.

При pull номер лежит в ответе GET. При push тот же номер приходит в заголовке X-Smartica-Revision входящего PUT. Тело запроса при этом не меняется. Номер нужен, чтобы подтвердить забор. Тот же номер указывается в запросе из статьи Протокол после правки врача.

При pull подтверждение работает как оптимистичная блокировка:

  1. Вы забираете протокол. В ответе приходит revision: 3.
  2. Вы сохраняете протокол у себя.
  3. Вы отправляете подтверждение с revision: 3.
  4. Если до подтверждения smartica.ai перезаполнила протокол, у нас уже revision: 4. Подтверждение отклоняется с ошибкой 409 revision_mismatch.
  5. Вы забираете протокол заново, получаете актуальную версию и подтверждаете её.
Врачдописывает приём
Бэкенд МИСзабирает и подтверждает
smartica.aiхранит версии протокола
1
Бэкенд МИС → smartica.ai
Забрать протокол
GET …/encounters/{smartica_encounter_id}
smartica.ai → бэкенд МИС
протокол · revision: 3
2
Сохраняет протокол у себя
В это время
Врач → smartica.ai
Дописывает приём
Протокол заполнен зановоrevision 3 → revision 4
Подтверждение
3
Бэкенд МИС → smartica.ai
Подтвердить
POST …/ack · revision: 3
smartica.ai → бэкенд МИС
409 revision_mismatch
актуальная revision: 4
У вас сохранена версия без дописанного. Её нельзя считать доставленной.
4
Бэкенд МИС → smartica.ai
Забрать протокол заново
GET …/encounters/{smartica_encounter_id}
smartica.ai → бэкенд МИС
протокол · revision: 4
5
Обновляет сохранённые данные
6
Бэкенд МИС → smartica.ai
Подтвердить
POST …/ack · revision: 4
smartica.ai → бэкенд МИС
200 · accepted

Так МИС не отмечает приём доставленным по устаревшему протоколу.

#Подтверждение (ack)

Английское acknowledge означает «подтверждаю получение». Этим запросом ваша МИС при доставке pull сообщает smartica.ai, что протокол сохранён. Пока подтверждения нет, приём остаётся в статусе «готов, но не доставлен».

#Курсор (cursor)

Курсор листает длинные списки. Вместо номера страницы smartica.ai возвращает в ответе строку next_cursor. Передайте next_cursor в следующем запросе, чтобы получить продолжение списка. Содержимое строки разбирать не нужно. Строка для вас остаётся непрозрачным маркером. Если в ответе next_cursor равен null, список закончился.

#Inline-поля

Inline-поля передают название бланка и список полей бланка прямо в теле запроса. В Import inline-поля передаются всегда. В Launch вы передаёте inline-поля по желанию. С inline-полями свой GET за бланком не нужен.

#Поля контракта

Поле Что означает
encounter_id ID приёма в вашей МИС. Вы задаёте этот ID. smartica.ai возвращает этот ID обратно
smartica_encounter_id ID записи в smartica.ai в формате UUID. ID нужен в сценарии Import и при доставке pull
platform Идентификатор вашей клиники в smartica.ai. Мы выдаём идентификатор при подключении
user_email Email врача. По этому email smartica.ai определяет врача для приёма
user_full_name ФИО врача. smartica.ai использует ФИО, чтобы завести аккаунт при первом входе
template Название бланка или специальности, например «Кардиолог» или «Первичный приём педиатра»
fields[].id Технический ключ поля. По этому ключу вы определяете, куда положить текст
fields[].label Заголовок для заполнения smartica.ai. Обычно совпадает с подписью поля на бланке. Если подпись понятна только вместе с разделом выше, опишите поле целиком
fields[].value Заполненное значение поля. Тип значения задаёт бланк. Правила описаны в статье Типы полей бланка
fields[].type Тип поля: текст, число, дата, список, таблица. Если не передан, поле считается текстом
skipped Поля, которые не попали в протокол, и причина
transcript Передаёт полную стенограмму разговора одним текстом
launch_url Содержит готовую одноразовую ссылку для входа врача
revision Показывает ревизию заполненного протокола, см. выше
delivery Принимает значение push или pull, см. выше

#encounter_id — ID приёма в вашей МИС

encounter_id служит главным идентификатором интеграции. Этот ID связывает вход врача, запрос полей и возврат результата.

#Передавайте строкой

Даже если в вашей базе ID хранится целым числом:

{ "encounter_id": "12345" }

Не 12345 без кавычек. Строка.

#Допустимые форматы

Поддерживаются ровно два варианта:

Формат Пример Годится
Только цифры "12345" Да
UUID в форме 8-4-4-4-12 "a1b2c3d4-e5f6-7890-abcd-ef1234567890" Да
С префиксом "enc-123", "TEST-1" Нет, вернём 422
С пробелами "12345 " Нет
Произвольная строка "приём-Иванова" Нет

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

#Правила использования

  1. ID должен однозначно определять один приём внутри вашей клиники.
  2. В Launch вы передаёте один и тот же ID в SSO-запросе, в URL GET и PUT и в теле JSON.
  3. В Import вы передаёте тот же ID в теле запроса на привязку. В адресе этого запроса стоит smartica_encounter_id.
  4. Завершение записи из МИС использует один и тот же запрос для Launch Push и Launch Pull: POST /api/v1/integrations/{platform}/encounters/{encounter_id}/stop. В адресе стоит ваш encounter_id. Доставка push или pull на этот запрос не влияет. Пошаговое описание для pull есть в статье Запуск из МИС, протокол забираете вы (Launch Pull).
  5. Повторный запуск с тем же ID продолжает тот же приём. Новый приём при этом не создаётся.
  6. Не переиспользуйте ID для другого пациента, другого врача или новой карточки.
  7. Один ID нельзя привязать к двум разным записям smartica.ai. Мы вернём ошибку encounter_taken.

#smartica_encounter_id — ID записи в smartica.ai

Мы генерируем UUID без префиксов. Впервые вы видите этот UUID в списке записей:

Дальше вы подставляете этот UUID в адрес привязки, забора протокола и подтверждения:

POST /api/v1/integrations/{platform}/encounters/{smartica_encounter_id}/import
GET  /api/v1/integrations/{platform}/encounters/{smartica_encounter_id}
POST /api/v1/integrations/{platform}/encounters/{smartica_encounter_id}/ack

В адресах Import и pull стоит smartica_encounter_id. В запросе «завершить запись» в адресе стоит encounter_id.

#platform — идентификатор клиники

Формат состоит из строчных латинских букв, цифр и одиночных дефисов:

^[a-z0-9]+(?:-[a-z0-9]+)*$

Например: gorodskaya-klinika-1.

Значение выдаёт smartica.ai после регистрации подключения. Подобрать значение самостоятельно нельзя. Строка правильного формата без регистрации вернёт 404.

#template — название бланка

Передавайте название, которое однозначно описывает бланк или специальность:

  • "Кардиолог"
  • "ЛОР"
  • "Первичный приём педиатра"
  • "УЗИ органов брюшной полости"

Для одного и того же бланка используйте одно написание. Не чередуйте "ЛОР", "lor" и "Отоларинголог". От названия зависит клинический контекст, который smartica.ai применит при заполнении.

#fields[].id и fields[].label

id читаете вы. label читает smartica.ai.

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

label — заголовок для заполнения smartica.ai. По этому заголовку smartica.ai определяет, какой фрагмент разговора попадёт в поле. Обычно заголовок совпадает с подписью на бланке врача. Если подпись понятна только вместе с разделом или группой выше, короткой подписи мало. «Норма» не объясняет поле. «Объективный статус. Норма» объясняет.

{ "id": "objective_status", "label": "Объективный статус (status praesens)" }
Хорошо Плохо Почему
"Жалобы" "field_3" Название ничего не сообщает о содержании
"Диагноз (основной)" "Диагноз" Если диагнозов несколько видов, неясно, какой диагноз имеется в виду
"Объективный статус (status praesens)" "Статус" Слишком общее слово
"Рекомендации по лечению" "Данные" Невозможно понять, что туда класть
"Объективный статус. Норма" "Норма" Короткая подпись понятна только вместе с разделом

Если в бланке есть похожие поля, уточняйте названия: не "Диагноз" и "Диагноз 2", а "Диагноз (основной)" и "Диагноз (сопутствующий)".

#Что попадает в поле

Каждое поле заполняется отдельно, по своему label. В поле попадает только то, что относится к его названию. Поле "Перенесённые заболевания" не получит аллергии и вредные привычки.

Один факт может прийти в нескольких полях. Температура из жалоб придёт и в "Жалобы", и в "Температура". Так и задумано: каждое поле заполнено целиком, и врачу не нужно переносить значения вручную.

Факт, для которого в бланке нет подходящего поля, в протокол не попадает. Мы не дописываем его в соседнее поле, близкое по смыслу. Если нужно передавать, например, назначенное лечение, добавьте в бланк поле "Лечение" или "Рекомендации по лечению". Стенограмма с полным разговором приходит всегда.

#Дубликаты id в бланке

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

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

{
  "warnings": [
    {
      "code": "duplicate_field_id",
      "field_ids": ["objective_status"],
      "message": "Несколько полей с одинаковым id: objective_status. Заполнили первое, остальные пропустили. Сделайте id уникальными внутри бланка."
    }
  ]
}

Ключ warnings появляется только когда есть о чём предупредить. Ключ не влияет на код ответа. Логируйте warnings. warnings остаётся единственным сигналом, что часть полей бланка не заполняется.

Обычно дубликат означает, что id собран из названия раздела без учёта вложенности. Например, у всех подполей объективного статуса ключ получается одинаковым. Добавьте к ключу уникальную часть: objective_status.temperature, objective_status.weight. Точки, слэши и другие разделители внутри id допустимы. Для нас id остаётся непрозрачной строкой.

#Как назвать endpoint на своей стороне

Адрес выбираете вы. Рекомендации такие:

  • Используйте HTTPS.
  • Назовите ресурс существительным во множественном числе.
  • Поместите encounter_id в адрес.
  • Используйте один и тот же адрес для чтения контекста и для записи результата. Чтение и запись различайте методом HTTP.

Рекомендуемый вариант:

GET /api/for-smartica/encounters/{encounter_id}
PUT /api/for-smartica/encounters/{encounter_id}

#Связанные статьи

← Все статьи: Интеграция с МИС Поиск по базе знаний