#Глоссарий и правила идентификаторов
Справочник по всем терминам и полям контракта. Если в другой статье встретилось незнакомое слово — оно объяснено здесь.
#Участники
| Термин | Что означает |
|---|---|
| МИС | Медицинская информационная система — ваша система, где ведётся карта пациента |
| Бэкенд МИС | Ваш сервер. Здесь хранятся секреты, отсюда идут запросы к Smartica. Браузер врача в эту роль не годится |
| Браузер врача | Открывает только готовую ссылку, которую выдал ваш бэкенд. Никаких ключей знать не должен |
| Smartica | Наш сервис: записывает разговор, расшифровывает, заполняет поля протокола |
#Ключевые понятия
#Сценарий: Launch и Import
Отвечает на вопрос «с чего начался приём».
- Launch — врач нажал кнопку «Smartica» в карточке приёма МИС. Подробнее.
- Import — врач записал приём в Smartica отдельно, а потом привязал запись к приёму в МИС. Подробнее.
#Доставка: push и pull
Отвечает на другой вопрос — «как готовый протокол попадёт в МИС». От сценария не зависит.
- push — Smartica сама вызывает ваш
PUT, когда протокол готов. Нужен доступный извне endpoint. - pull — ваша МИС сама спрашивает у Smartica, готов ли протокол, забирает его и подтверждает получение. Входящие соединения не нужны.
Режим выбирается один раз при подключении.
#SSO
Single Sign-On — «сквозной вход». Врач нажимает кнопку в МИС и попадает в Smartica уже авторизованным, без ввода логина и пароля. Работает так: ваш бэкенд заранее просит у Smartica одноразовую ссылку и открывает её врачу.
#Идемпотентность
Свойство операции, при котором повторный одинаковый запрос не создаёт ничего нового, а просто приводит систему в то же состояние.
Пример: Smartica дважды прислала один и тот же PUT с протоколом. Идемпотентная МИС во второй раз обновит уже существующий приём и вернёт успех. Неидемпотентная создаст вторую карточку — и в карте пациента появится дубль.
Это обязательное требование к вашему PUT. Повторы реально случаются: врач нажал «отправить заново», приём дописали, протокол перегенерировали. Ключом операции служит encounter_id — отдельного заголовка вроде Idempotency-Key в контракте нет.
#Ревизия (revision)
Номер версии заполненного протокола. Начинается с 0 и растёт каждый раз, когда Smartica перезаполняет протокол — например, после того, как врач дописал приём.
Нужна только при доставке pull, чтобы вы не подтвердили устаревшую версию. Механика называется «оптимистичная блокировка» и работает так:
- Вы забрали протокол — в ответе пришло
revision: 3. - Сохранили его у себя.
- Отправляете подтверждение с
revision: 3. - Если за это время Smartica успела перезаполнить протокол, у нас уже
revision: 4, и подтверждение отклоняется с ошибкой409 revision_mismatch. - Вы забираете протокол заново, получаете актуальную версию и подтверждаете её.
Так исключается ситуация, когда МИС «закрыла» приём той версией, которая уже устарела.
#Подтверждение (ack)
От английского acknowledge — «подтверждаю получение». Запрос, которым ваша МИС при доставке pull сообщает Smartica: «протокол сохранён у меня, можно считать приём доставленным». Пока подтверждения нет, приём остаётся в статусе «готов, но не доставлен».
#Курсор (cursor)
Способ листать длинные списки. Вместо номера страницы Smartica возвращает в ответе строку next_cursor — передайте её в следующем запросе, чтобы получить продолжение списка. Содержимое строки разбирать не нужно, для вас это просто непрозрачный маркер. Если next_cursor пришёл как null — список закончился.
#Inline-поля
Название бланка и список его полей, переданные прямо в теле запроса, а не запрошенные отдельным GET. В Import они передаются всегда, в Launch — по желанию: так можно вообще не делать GET у себя.
#Поля контракта
| Поле | Что это |
|---|---|
encounter_id |
ID приёма в вашей МИС. Его придумываете вы, Smartica просто возвращает его обратно |
smartica_encounter_id |
ID записи в Smartica (UUID). Появляется только в сценарии Import |
platform |
Идентификатор вашей клиники в Smartica. Выдаём мы при подключении |
user_email |
Email врача. По нему Smartica понимает, чей это приём |
user_full_name |
ФИО врача. Нужно, чтобы завести аккаунт при самом первом входе |
template |
Название бланка или специальности — «Кардиолог», «Первичный приём педиатра» |
fields[].id |
Технический ключ поля. По нему вы поймёте, куда положить текст |
fields[].label |
Человекочитаемое название поля. По нему Smartica понимает смысл поля |
fields[].value |
Заполненный текст поля. Приходит в результате |
transcript |
Полная стенограмма разговора одним текстом |
launch_url |
Готовая одноразовая ссылка для входа врача |
revision |
Версия заполненного протокола, см. выше |
delivery |
push или pull, см. выше |
#encounter_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 вашей МИС не подходят под эти форматы, обсудите это при онбординге до начала разработки.
#Правила использования
- ID должен однозначно определять один приём внутри вашей клиники.
- В Launch один и тот же ID используется везде: в SSO-запросе, в URL
GETиPUT, и в теле JSON. - В Import тот же ID передаётся в теле запроса на привязку (в адресе при этом стоит
smartica_encounter_id— не перепутайте). - Повторный запуск с тем же ID — это продолжение того же приёма, а не новый приём.
- Не переиспользуйте ID для другого пациента, другого врача или новой карточки.
- Один ID нельзя привязать к двум разным записям Smartica — вернём ошибку
encounter_taken.
#smartica_encounter_id — ID записи в Smartica
UUID без префиксов, генерируем мы. Вы впервые видите его в списке записей, ожидающих привязки, и дальше подставляете в адрес:
POST /api/v1/integrations/{platform}/encounters/{smartica_encounter_id}/import
Легко перепутать с encounter_id. Запомните так: smartica_… — наш ID и живёт в адресе, encounter_id — ваш ID и живёт в теле запроса.
#platform — идентификатор клиники
Формат — строчные латинские буквы, цифры и одиночные дефисы:
^[a-z0-9]+(?:-[a-z0-9]+)*$
Например: gorodskaya-klinika-1.
Значение выдаёт Smartica после регистрации подключения. Подобрать его самостоятельно нельзя: строка правильного формата, но незарегистрированная, вернёт 404.
#template — название бланка
Передавайте название, которое однозначно описывает бланк или специальность:
"Кардиолог""ЛОР""Первичный приём педиатра""УЗИ органов брюшной полости"
Для одного и того же бланка всегда используйте одно и то же написание. Не чередуйте "ЛОР", "lor" и "Отоларинголог" — от названия зависит, какой клинический контекст Smartica применит при заполнении, и разнобой ухудшает результат.
#fields[].id и fields[].label
id — для вас, label — для нас. Это принципиально разные вещи.
id может быть техническим, но обязан быть непустым, уникальным внутри одного бланка и неизменным после запуска. По нему вы разложите пришедшие значения по своим полям, поэтому менять его нельзя — сломается сопоставление.
label Smartica читает как инструкцию: именно по названию мы определяем, какой фрагмент разговора попадёт в это поле. От качества label напрямую зависит качество заполнения.
{ "id": "objective_status", "label": "Объективный статус (status praesens)" }
| Хорошо | Плохо | Почему |
|---|---|---|
"Жалобы" |
"field_3" |
Название ничего не сообщает о содержании |
"Диагноз (основной)" |
"Диагноз" |
Если диагнозов несколько видов, непонятно, какой имеется в виду |
"Объективный статус (status praesens)" |
"Статус" |
Слишком общее слово |
"Рекомендации по лечению" |
"Данные" |
Невозможно понять, что туда класть |
Если в бланке есть похожие поля, уточняйте названия: не "Диагноз" и "Диагноз 2", а "Диагноз (основной)" и "Диагноз (сопутствующий)".
#Дубликаты id в бланке
Два поля с одинаковым id — неоднозначность: по одному ключу вы не сможете разложить два значения, даже если label у них разные. Поэтому такой бланк мы не считаем корректным.
Приём врача при этом не срывается. Мы берём первое вхождение каждого id вместе с его label, остальные поля с тем же id в заполнении не участвуют и в результате не появятся. В ответе на привязку записи и на запрос ссылки для входа приходит предупреждение:
{
"warnings": [
{
"code": "duplicate_field_id",
"field_ids": ["objective_status"],
"message": "Несколько полей с одинаковым id: objective_status. Заполнили первое, остальные пропустили. Сделайте id уникальными внутри бланка."
}
]
}
Ключ warnings появляется только когда есть о чём предупредить, и не влияет на код ответа. Логируйте его: это единственный сигнал о том, что часть полей бланка молча не заполняется.
Обычно дубликат означает, что id собран из названия раздела без учёта вложенности — например, у всех подполей объективного статуса ключ получился одинаковым. Тогда добавьте к ключу уникальную часть: objective_status.temperature, objective_status.weight. Точки, слэши и другие разделители внутри id допустимы — для нас это просто непрозрачная строка.
#Как назвать endpoint на своей стороне
Адрес выбираете вы, но есть рекомендации:
- используйте HTTPS;
- назовите ресурс существительным во множественном числе;
- поместите
encounter_idв адрес; - используйте один и тот же адрес для чтения контекста и записи результата, различая их методом.
Рекомендуемый вариант:
GET /api/for-smartica/encounters/{encounter_id}
PUT /api/for-smartica/encounters/{encounter_id}