semd_validator
SEMD validator - сервис проверки СЭМД для 1С:Медицина и выдачи копий справочников ФНСИ
Сервис предназначен для выполнения проверок структурированных электронных медицинских документов (СЭМД) на соответствие xsd схеме, схематрону и справочникам ФНСИ. Схемы и схематроны публикуются на портале ЕГИСЗ Минздрава РФ. Сервис реализован как сервлет для веб сервера Jetty версии 9.4+.
Сервис получает справочники ФНСИ и сохраняет в собственной базе данных. Справочники загружаются из json файлов и сохраняются в собственном бинарном формате.
Описание базы данных ФНСИ
Встроенная база данных - база данных «ключ-значение». Ключ и значение справочника определяются по паспорту справочника и в настройках могут быть изменены. Помимо ключа и значения в справочнике могут быть другие реквизиты справочника как дополнительные. Тогда сервис будет возвращать эти реквизиты вместе с основными данными (ключ + значение).
Папка passport
Содержит json файлы паспортов справочников.
Папа avl
Содержит содержимое справочников в файлах со следующими расширениями:
- avl - файл с данными в формате «ключ-значение». Данные хранятся в виде двух avl деревьев - словарь и записи справочника (ключ и значение). Значение состоит из ссылок на словарь. Файл загружается в ОЗУ целиком при обращении к справочнику.
- ext - файл с дополнительными реквизитами (отличными от ключа и значения). Файл может отсутствовать. Дополнительные значения в ОЗУ загружаются только в момент их использования.
- idx - файл с индексом на значение. На значение справочника всегда строится индекс, по которому выполняется запросы LIKE и LIKE2. Индекс целиком загружается в ОЗУ в момент первого использования индекса.
Описание веб-ссылок
/get_sch_list.html - просмотр загруженных схем и схематронов, а также списка OID справочников ФНСИ, с командами проверки
Для доступа к ссылкам требуются права администратора или доступ с localhost. В случае установки ограничений на список проверяемых типов РЭМД в параметре LIST_TYPES_FOR_VARIFICATION проверяемые типы в списке будет выделяться оформлением.
/send_semd.html - форма отправки СЭМД для выполнения валидации
Схема и схематрон должны быть предварительно загружены на сервер. Для доступа к ссылкам требуются права администратора или доступ с localhost.
/verify - валидация СЭМД
В случае проверки только на xsd-схемы и\или на соответствие справочникам ФНСИ при успешной проверке будет возвращено значение "valid". Иначе будет возращен текст сообщения об ошибке. Проверка на соответствие ФНСИ выполняется в соответствии с файлом настроек FNSIlist.json.
Типы проверок:
- 0 - проверка только на xsd.
- 1 - проверка только на sch.
- 2 - проверка на xsd и sch.
- 3 - проверка на xsd, sch и ФНСИ. Точный порядок проверок - xsd, ФНСИ, sch.
После выполнения проверки схематроном возвращается результат проверки. Результат записывается в элементе /result/sch. В атрибуте @file элемента sch записывается имя xsl преобразования, по которому выполнялась проверка. Пример успешной проверки:
<result>
<sch file="118.xsl">
<svrl:schematron-output xmlns:svrl="http://purl.oclc.org/dsdl/svrl"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:saxon="http://saxon.sf.net/"
xmlns:schold="http://www.ascc.net/xml/schematron"
xmlns:iso="http://purl.oclc.org/dsdl/schematron"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:identity="urn:hl7-ru:identity"
xmlns:address="urn:hl7-ru:address"
xmlns:medService="urn:hl7-ru:medService"
xmlns:fias="urn:hl7-ru:fias"
title=""
schemaVersion=""><!--
-->
<svrl:ns-prefix-in-attribute-values uri="http://www.w3.org/2001/XMLSchema-instance" prefix="xsi"/>
<svrl:ns-prefix-in-attribute-values uri="urn:hl7-ru:identity" prefix="identity"/>
<svrl:ns-prefix-in-attribute-values uri="urn:hl7-ru:address" prefix="address"/>
<svrl:ns-prefix-in-attribute-values uri="urn:hl7-ru:medService" prefix="medService"/>
<svrl:ns-prefix-in-attribute-values uri="urn:hl7-ru:fias" prefix="fias"/>
</svrl:schematron-output>
</sch>
</result>
Примеры неуспешных проверок:
:ERROR: Line: 292 Column: 186 Message: cvc-elt.4.3: Type 'CD' is not validly derived from the type definition, '#AnonType_IdentityDocTypePOCD_MT000040.DocInfo', of element 'identity:IdentityDocType'.
:ERROR: Line: 294 Column: 242 Message: cvc-elt.4.3: Type 'CD' is not validly derived from the type definition, '#AnonType_InsurancePolicyTypePOCD_MT000040.DocInfo', of element 'identity:InsurancePolicyType'.
:ERROR: INVALID_ELEMENT_VALUE_NAME Справочник OID [1.2.643.5.1.13.13.99.2.166], версия [2.7]. Наименование элемента [Наименование рекомендованного протеза, протезно-ортопедического изделия] не соответствует наименованию элемента в НСИ [Сведения о протезе, протезно-ортопедическом изделии]
<result>
<sch file="118.xsl">
<svrl:schematron-output xmlns:svrl="http://purl.oclc.org/dsdl/svrl"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:saxon="http://saxon.sf.net/"
xmlns:schold="http://www.ascc.net/xml/schematron"
xmlns:iso="http://purl.oclc.org/dsdl/schematron"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
title=""
schemaVersion="iso">
<svrl:ns-prefix-in-attribute-values uri="http://www.w3.org/2001/XMLSchema-instance" prefix="xsi"/>
<svrl:failed-assert test="count(realmCode)=1">
<svrl:text>У1-8. Элемент ClinicalDocument должен иметь один элемент realmCode.</svrl:text>
</svrl:failed-assert>
</svrl:schematron-output>
</sch>
</result>
/passport - получение паспорта справочников ФНСИ
Выдает паспорт справочника в JSON формате ФНСИ.
Параметры:
- identifier - Обязательный. oid справочника ФНСИ.
- remdtype (*) - Необязательный. Тип РЭМД по справочнику 1.2.643.5.1.13.13.11.1520. Если указан, то справочник будет использован той версии, которая указана в справочнике 1.2.643.5.1.13.13.99.2.805 для требуемого типа РЭМД.
- version - Необязательный. Номер версии справочника ФНСИ. Если номер версии не указан, то используется последняя версия справочника. Если указан remdtype, то параметр не используется.
/data - получение содержимого справочника ФНСИ
Выдает содержимое справочника в JSON формате ФНСИ. Возможно наложение отбора на поле, которое в файле FNSIlists.json или FNSIExtraList.json определено как KEY и на поле, которое определено как VALUE. Если в настройках справочника перечислены поля в поле REKV, то будут выданы и значения только этих полей. См. описание REKV в файле FNSIlists.json и FNSIExtraList.json. Формат запросов сделан по аналогии с аналогичными запросами к ФНСИ.
Параметры:
- userKey - Обязательный. Идентификатор запроса. Формат не контролируется. Идентификатор должен быть уникальным для пагинированных запросов в рамках получения страниц. То есть запрос на получение N-ой страницы должен иметь тот же идентификатор, что и на N-1. Для пагинированных запросов в параметре page значение номера страницы не важно, тут используется логика работы курсоров в СУБД. Вызов интерпретируется как next у курсора.
- identifier - Обязательный. oid справочника ФНСИ.
- remdtype (*) - Необязательный. тип РЭМД по справочнику 1.2.643.5.1.13.13.11.1520. Если указан, то справочник будет использован той версии, которая указана в справочнике 1.2.643.5.1.13.13.99.2.805 для требуемого типа РЭМД. Необязательный.
- version - Необязательный. Номер версии справочника ФНСИ. Если номер версии не указан, то используется последняя версия справочника. Если указан remdtype, то параметр не используется.
- size - Необязательный. Размер страницы в записях. Если параметр size не указан, то берется значение по умолчанию - 20.
- page (*) - Игнорируется. См. описание userKey.
- filters - Необязательный. Критерии отбора записей справочника. Если в качестве имени поля указано поле KEY, то осуществляется поиск значения этого поля. Применение модификатора LIKE не предусмотрено.
Если в качестве имени поля указано поле VALUE, то необходимо использовать один из 2-х модификаторов:
- LIKE - запись соответствует критерию поиска, если в Value входит искомая подстрока (без учета регистра)
- LIKE2 (*) - запись соответствует критерию поиска, если в Value входят искомые подслова (без учета регистра). Поиск морфологический - без учета окончаний существительных и прилагательных
(*) - отличия от API ФНСИ.
Примеры:
data?userKey=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx&identifier=1.2.643.5.1.13.13.11.1522&version=1.2&filters=code|1
data?userKey=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx&identifier=1.2.643.5.1.13.13.11.1522&remdtype=114&filters=code|1
data?userKey=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx&identifier=1.2.643.5.1.13.13.11.1522&size=20
data?userKey=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx&identifier=1.2.643.5.1.13.13.11.1522&filters=Name|Протокол|LIKE&size=20
data?userKey=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx&identifier=1.2.643.5.1.13.13.11.1522&filters=name|наименование|LIKE2&size=20
Примеры использования LIKE:
Шаблон 'медицинская сес'
Данные:
'медицинская сестра' - соответствует
'сестра медицинская' - не соответствует
Шаблон 'едицинск'
Данные:
'медицинская сестра' - соответствует
Примеры использования LIKE2:
Шаблон 'медицинская сес'
Данные:
'медицинская сестра' - соответствует
'сестра медицинская' - соответствует
Шаблон 'едицинск'
Данные:
'медицинская сестра' - не соответствует
Данные ответа:
- result - статус ответа. Допустимые значения - OK и ERROR.
- total - общее число записей, которые соответствуют критериям отбора.
- hasNext - есть ли следующая страница (для пагинированных ответов).
- before - число выданных ранее записей
- codeSystem (*) - OID справочника
- codeSystemName (*) - наименование справочника
- codeSystemVersion (*) - версия справочника
- list - данные ответа. В качестве идентификаторов колонок используются имена колонок справочника ФНСИ. См. раздел FNSIlist.json и FNSIExtraList.json.
(*) - отличия от API ФНСИ.
Пример ответа:
{"result":"OK",
"total":1,
"codeSystem":"1.2.643.5.1.13.13.11.1035","codeSystemName":"Виды полиса обязательного медицинского страхования","codeSystemVersion":"1.3",
"hasNext":false,
"list":[
[
{"column":"ID","value":"4"},
{"column":"NAME","value":"Временное свидетельство"}
]
]
}
/send_sch.html - форма отправки файлов настроек в сервис
Список тегов, подлежащих проверке на соответствие справочникам ФНСИ
Список тегов передается в сервис текстовым файлом в кодировке UTF-8. Теги записывается построчно. Тег должен содержать следующие атрибуты, значение которых подлежит контролю - code, codeSystemVersion, codeSystemName, displayName. Если есть namespace, то тег указывается с namespace. Пример содержимого:
code
administrativeGenderCode
value
functionCode
translation
/updatedb - генерации xsl для схематронов
Sch файлы уже должны находится в папке DATA_PATH. Требования к файлам такие же как как к отправляемым в zip архиве через форму send_sch.html Для доступа к ссылкам требуются права администратора или доступ с localhost. В URL передается список типов РЭМД, которым необходимо сгенерировать XSL для валидации. Список передается через разделитель - "_".
Примеры:
http://localhost:8891/a/semd/updatedb/223
http://localhost:8891/a/semd/updatedb/223_224
Возвращаемые значение - текст 'OK' и далее через пробел список типов РЭМД, которые успешно обработались. В случае возникновения ошибки команда вернет текст ошибки.
/reload - очистка кеша справочников ФНСИ
При завершении работы fnsi-downloader вызывает reload для того, чтобы перезагрузить все справочники сервлета, т.к. они могли обновиться.
/login.html - форма авторизации
Папка data
xsd схемы и схематроны для СЭМД, содержимое справочников ФНСИ. Содержимое папки можно использовать для наполнения папки, указанной в параметре сервлета DATA_PATH.
Для предоставления прав записи в эту папку в некоторых дистрибутивах необходимо в настройка sandbox сервиса Jetty дать права записи. Например, в Ubuntu 20.04 необходимо в файле /etc/systemd/system/multi-user.target.wants/jetty9.service добавить строку (новую):
ReadWritePaths=/var/www/upload/tron2/
Для применения настроек надо выполнить:
systemctl daemon-reload
service jetty9 restart
В папке data должны быть созданы папки avl и passport с такими же правами доступа как к папке data. В папке avl хранятся скачанные справочники ФНСИ в объеме, заданном для в файле FNSIlist.json и FNSIExtraList.json. В папке passport хранятся паспорта справочников в формате JSON.
Параметры сервлета
В файле semd.war:\WEB-INF\web.xml задаются следующие параметры:
- DATA_PATH - Обязательный. Полный путь к папке, где будут хранится загруженный файлы (xsd, sch и сгенерированные xsl файлы). Значение по умолчанию - /var/www/upload/tron2.
- ADMIN_NAME - Необязательный. Имя пользователя, являющего администратором. Значение по умолчанию - admin.
- ADMIN_PASS - Необязательный. Пароль пользователя, являющего администратором. Значение по умолчанию - pass.
- LIST_TYPES_FOR_VARIFICATION - Необязательный. Список типов РЭМД (OID), по которым выполняется проверка. Типы РЭМД указывают через запятую, без пробелов. Если список пустой, то ограничений нет и проверка выполняется по всем типам, по которым загружены xsd и sch.
Установка сервлета
Для работы сервлета semd.war нужен Jetty версии 9.4 или выше. Необходимо опубликовать сервлет semd.war в Jetty 9. Необходимо руководствоваться инструкций по публикации Jetty.
Для Jetty9 из состава Ubuntu 20.04 файл semd.war необходимо поместить в папку /var/lib/jetty9/webapps. Отвечать сервлет будет по адресу "http:/localhost:9000/semd/login.html".
FNSIlist.json и FNSIExtraList.json - настройки использования справочников ФНСИ
В файле FNSIlist.json задаются настройки сохранения справочников, которые загружаются на основании их присутствия в справочнике 1.2.643.5.1.13.13.99.2.805. Если в FNSIlist.json справочник не присутствует, но присутствует в справочнике 1.2.643.5.1.13.13.99.2.805, то он загружается с настройками из паспорта справочника.
В файле FNSIExtraList.json задается список справочников, которых нет в справочнике 1.2.643.5.1.13.13.99.2.805, но требуется загрузить в сервис с целью их промежуточного хранения в сервисе. Формат обоих файлов идентичный.
Справочники 1.2.643.5.1.13.13.99.2.805 и 1.2.643.5.1.13.13.11.1520 необходимо включить в файл FNSIExtraList.json, так как их содержимое требуется для загрузки справочников в соответствии с содержимым FNSIlist.json.
Массив объектов в формате JSON, где для справочников указываются следующие настройки:
- CODESYSTEM - Обязательный. oid справочника ФНСИ.
- LOAD - Необязательный. Если указано значение 0 (false), то справочник не загружается в сервис валидации СЭМД.
- KEY - Необязательный. Имя поля справочника ФНСИ, которое будет использоваться как ключ справочника. При проверке СЭМД это поле соответствует атрибуту code. Если значение не указано, то берется поле, помеченное как PRIMARY в паспорте справочника.
- VALUE - Необязательный. Имя поля справочника ФНСИ, которое будет использоваться как значение справочника. При проверке СЭМД это поле соответствует атрибуту displayName. Если значение не указано, то берется поле, помеченное как VALUE в паспорте справочника.
- REKV - Необязательный. Список полей справочника, которые будут сохранены при загрузке справочника и будут выдаваться запросами data к сервису валидации.
- VALIDATE_REFNAME - Если указано значение 0 (false), то при проверке СЭМД не выполнять проверку атрибута codeSystemName.
- VALIDATE_VALUE - Необязательный. Если указано значение 0 (false), то при проверке СЭМД не выполняется проверка displayName. Если REKV отсутствует, то справочник загружается полностью (все поля). Если REKV пустой, то загружаются только два поля - ключ и значение.
- COMMENT - Необязательный. Комментарий к справочнику.
Если по данным паспорта не удалось определить поле, которые будет записано в VALUE, то утилита fnsi-downloader выдаст сообщение ''' EMPTY REF. CHECK SETTINGS 'codeSystem' + Problem with version 'ver' ''' и справочник не будет загружен.
fnsi-downloader
Загрузка справочников ФНСИ выполняет консольной утилитой fnsi-downloader.
Параметры командной строки
- USERKEY - Обязательный. Ключ доступа к сайту nsi.rosmindrav.ru.
- DATA_PATH - Обязательный. Папка, где располагается файл FNSIlist.json и FNSIExtraList.json (настройки использования справочников ФНСИ), в этой же папке должны быть созданы папки avl и passport, куда будут сохраняться бинарные версии справочников и данные паспортов. Значение параметра должно совпадать с аналогичным параметром сервлета.
- URL - Необязательный. Адрес публикации сервлета. ВАЖНО, чтобы доступ к сервлету был через localhost, т.к. сервлет без авторизации принимает команды только с localhost.
- SIZE - Необязательный. Передается в параметр size в запросах к ФНСИ. Число записей, которые вернет ФНСИ. Значение по умолчанию - 2000.
Пример запуска
java -jar fnsi-downloader-1.1-jar-with-dependencies.jar DATA_PATH=/home/user/ URL=http://infomed.med.1c.ru/a/semd USERKEY=xxx-xxx-xxx-xxx
Для запуска fnsi-downloader может потребоваться установка сертификата сайта ФНСИ в хранилище сертификатов Java. Для этого необходимо в браузере сохранить сертификат сайта nsi.rosminzdrav.ru в бинарном виде (DER), после чего необходимо экспортировать его в lib\security\cacerts:
keytool -import -alias rosminzdrav -keystore D:\openjdk-17.0.2\lib\security\cacerts -file _.rosminzdrav.ru.der
Сборка
Для сборки проекта необходимо выполнить команду в корневой папке проекта
mvn package
в папке, где расположен файл pom.xml, который определяет проект, состоящий из 3-х модулей - servlet, console, avltree.
В составе репозитория можно найти уже собранные semd-X-X.war и fnsi-downloader-X.X-jar-with-dependencies.jar актуальных версий.
Подробнее о Maven можно найти на странице https://maven.apache.org/guides/getting-started/maven-in-five-minutes.html.
В проекте demo демонстрируется работа со справочниками:
- загрузка справочника с ФНСИ с сохранением в файлы
- запрос к справочнику Примеры являются независимыми между собой.
Описание
Сервис проверки СЭМД для 1С:Медицина
Языки
XSLT
- Java