Contract
Contract by Embedika — сервис для анализа и проверки договоров. Он подсветит условия, на которые нужно обратить внимание перед заключением договора, и поможет минимизировать правовые риски.
Архитектурные решения
Записи об архитектурных решениях, реализованных в продукте Contract.
Продуктивизация
- Status: accepted
- Story: CON-752 Продуктивизация Contract
Context
Цель: поставлять продукт любому заказчику без дополнительных затрат времени на разработку.
Considered Options
- Вынести алгоритмы обработки рисков под каждого заказчика в отдельный jar-файл и подключать в зависимости от проекта.
- В итоги пришли к универсальному алгоритму под все риски, из-за чего необходимость вынесения алгоритмов отдельно отпала.
- Вынести общий код сервиса в библиотеку, создавать на её основе реализацию сервиса под каждого заказчика.
- Сложно поддерживать большое количество сервисов.
- Нельзя просто развернуть один из сервисов у нового заказчика, т. к. он содержит кастом.
- Один универсальный сервис, который содержит в себе реализации под всех заказчиков, выбирать нужную настройками
окружения.
- Размер сервиса будет неограниченно возрастать и занимать лишнее место, т. к. использоваться будет только одна реализация.
- Сложно поддерживать код, т. к. реализации начинают пересекаться внутри сервиса, отделить их будет большой проблемой.
- Один универсальный сервис, но весь кастом под заказчика выносится из исходного кода сервиса наружу.
- Используется универсальный формат конфигов, которые понятны и могут поддерживаться не только программистами.
- Конфиги + модели под конкретного заказчика нужно собирать в отдельный образ для облегчения развертывания.
Decision
Выполняем один универсальный сервис: risk-checker. Выносим кастомизацию под нужды заказчика в Json-файлы конфигурации.
Реализован перенос данных из Json во внешние сервисы и собственную БД путем выполнения Liquibase-миграции. Чтение Json выполняется из файлового хранилища S3.
Перед запуском сервиса должна выполняться джоба config-pusher (копирует файлы из образа в S3). Для контроля актуальности данных используется файл version с номером релиза - и в коде сервиса, и в S3 номера релиза должны совпадать (миграция упадет при несовпадении).
Positive Consequences
- Конфигурацию под заказчика может настроить даже не разработчик через Json без изменения исходного кода.
Negative Consequences
- Файлы конфигурации должны быть размещены в GitLab рядом с проектом, чтобы обрабатывались тестами и собирались в образ config-pusher.
Импорт конфигурации системы
- Status: accepted
- Init issue: CON-64 Импорт сущностей в Contract
Context
Для работы анализатора нужно загрузить первоначальные данные в систему (требования чек-листа, риски, сущности, модели, каталоги, группы пользователей, политики, подписки, техконстанты). Набор первоначальных данных определяется требованиями заказчика и берется из Json-файлов ( см. Продуктивизация).
Considered Options
- Загрузка данных командой.
- На каждую разновидность объекта нужна отдельная команда на импорт и интерфейс для её выполнения.
- Не обеспечивается автоматическое развертывание, необходимое для некоторых объектов (группы и политики).
- Нужна инструкция для админа с порядком импорта.
- Некоторые миграции зависят друг от друга и не могут выполняться раздельно, а делать одновременный импорт из разных файлов сложно.
- Миграция Verdi (ExternalMigration) - механизм, встроенный в шаблон сервиса Verdi.
- Выполняется при каждом перезапуске сервиса, хотя достаточно один раз при развертывании релиза (лишняя нагрузка, замедление запуска, вопросы от техподдержки).
- Для каждой миграции нужно придумывать свой механизм вычисления needExecution из-за разной архитектуры API сервисов.
- Не понятно, выполнилась миграция или нет, т. к. нет чейнджлога.
- Сервис запускается и работает, даже если упала миграция.
- Миграция Liquibase:
- Сервис не будет запущен, если упала миграция, что гарантирует обновление всех данных.
- В таблице databasechangelog отображаются выполенные миграции.
- Удалением из databasechangelog можно инициировать перезапуск миграции при необходимости.
Decision
Миграции импорта кастомизации под заказчика используют Liquibase. Для удобства они имеют схожую структуру и наследуются от трейта SystemImport. Перезапуск миграции из кода инициируется изменением номера задачи в названии Changeset / имени автора.
Positive Consequences
- Полный контроль за выполнением миграций.
- Гарантия доставки всех данных.
Negative Consequences
- Не получится перезапустить миграцию перезапуском сервиса, т. к. успешно выполненные миграции, записанные в databasechangelog, пропускаются.
- Для контроля нужен доступ к БД PostgreSQL (ограничивается заказчиком).
risk-checker: сервис Анализатора
Сервис принимает запросы для работы с рисками. Состояние хранится в PostgreSQL.
Команды могут приходить как по HTTP, так и через Kafka в топик risk_checker_commands.
Сервис разбит на несколько модулей, в виде sbt проектов:
domain, в котором содержатся все доменные модели и их различные представления.commands, в котором содержатся все? что связано с командами, их описанием и обработчиками.infrastructure, в котором содержится описание взаимодействия с другими сервисами.storage, содержит сервисы для сохранения и чтения их разных хранилищ доменных моделей.service, содержит сервисы бизнес логики, которые определяют правила взаимодействия компонентов между собой.boot, содержит зависимости и описание для сборки и запуска сервиса.
Информация по добавлению команд можно прочитать в описании шаблона
Локальный запуск сервиса risk-checker
При запуске сервиса ожидается, что уже развернута необходимая инфраструктура:
- PostgreSQL база по адресу
localhost:5432/riskchecker_db - Kafka по адресу
localhost:9092 - Consul по адресу
localhost:8500 - Адрес Kafka будет указан в
application.conf - Добавлены необходимые переменные окружения:
- RISK_CHECKER_DB_HOST
- RISK_CHECKER_DB_PORT
- RISK_CHECKER_DB_NAME
- RISK_CHECKER_DB_USER
- RISK_CHECKER_DB_PASSWORD
Запуск из консоли с помощью SBT
RISK_CHECKER_DB_HOST=localhost RISK_CHECKER_DB_PORT=5432 RISK_CHECKER_DB_NAME=riskchecker_db RISK_CHECKER_DB_USER=postgres RISK_CHECKER_DB_PASSWORD=12345 sbt boot/run
Список переменных окружения сервиса risk-checker
Все доступные переменные окружения для настройки сервиса.
| Переменная | Тип | Обязательная | Значение по умолчанию | Описание |
|---|---|---|---|---|
| RISK_CHECKER_HTTP_HOST | string | нет | "0.0.0.0" | Хост, на котором слушает HTTP-сервер |
| RISK_CHECKER_HTTP_PORT | int | нет | 8192 | Порт, на котором слушает HTTP-сервер |
| RISK_CHECKER_HTTP_CLIENT_CONNECT_TIMEOUT | duration string | нет | 10 seconds | Максимальное время ожидания ответов на http запросы |
| RISK_CHECKER_KAFKA_SERVERS | string | да | "localhost:9092" | Адрес Kafka |
| RISK_CHECKER_KAFKA_TOPIC | string | нет | "risk_checker_commands" | Название кафка-топика для получения команд. Сервис получает кафка-команды по нему, но и также сам публикует это название в CommandDiscovery. |
| RISK_CHECKER_KAFKA_DATAMODEL_EVENTS_TOPIC | string | нет | "risk_checker_datamodel_events" | Название кафка-топика для получения событий из datamodel по сущностям |
| RISK_CHECKER_KAFKA_DATAMODEL_RELATION_EVENTS_TOPIC | string | нет | "risk_checker_datamodel_relation_events" | Название кафка-топика для получения событий из datamodel по отношениям |
| RISK_CHECKER_KAFKA_MARKER_EVENTS_TOPIC | string | нет | "risk_checker_marker_events" | Название кафка-топика для получения событий из marker-service |
| RISK_CHECKER_KAFKA_CONSUMER_GROUP | string | нет | "risk_checker_consumer_group" | Имя consumer-группы для чтения из кафка-топика команд. Не должна меняться и не должна быть пустой, иначе сервис перечитает свои команды при перезапуске. |
| RISK_CHECKER_KAFKA_PARTITIONS | int | нет | 10 | Число читаемых партиций из кафка-топика команд. |
| RISK_CHECKER_KAFKA_CONSUMER_RESTART_MIN_BACKOFF | duration string | нет | 1 second | Изначальная задержка до рестарта консьюмера после падения (увеличивается в 2 раза после каждого рестарта) |
| RISK_CHECKER_KAFKA_CONSUMER_RESTART_MAX_BACKOFF | duration string | нет | 30 seconds | Максимальное задержка до рестарта консьюмера после падения |
| RISK_CHECKER_KAFKA_CONSUMER_RESTART_RANDOM_FACTOR | double | нет | 0.2 | Рандомный фактор для вычисления задержки перед следующим рестратом консьюмера (При значении 0.2 задержка может быть до 20% больше, чем при 0) |
| RISK_CHECKER_KAFKA_CONSUMER_RESTART_MAX_RESTARTS | int | нет | 5 | Максимальное число рестартов консьюмера после падения (в пределах RISK_CHECKER_KAFKA_CONSUMER_RESTART_MAX_RESTARTS_WITHIN) |
| RISK_CHECKER_KAFKA_CONSUMER_RESTART_MAX_RESTARTS_WITHIN | duration string | нет | 5 minutes | Временной отрезок, в который RISK_CHECKER_KAFKA_CONSUMER_RESTART_MAX_RESTARTS ограничивает число рестартов |
| RISK_CHECKER_KAFKA_COMMANDEVENT_TOPIC | string | да | "commandevents" | Название кафка-топика для отправки сообщений со статусами выполняемых команд. ОБЯЗАТЕЛЬНО должно соответствовать названию этого топика в сервисе статуса команд. |
| RISK_CHECKER_KAFKA_AUTH_USER | string | нет | "" | Название учетной записи Kafka. Если название не указано, то настройки авторизации не будут применены. |
| RISK_CHECKER_KAFKA_AUTH_PASSWORD | string | нет | "" | Пароль учетной записи Kafka. |
| RISK_CHECKER_KAFKA_AUTH_PRINCIPAL | string | нет | "" | Principal учетной записи Kafka в Kerberos(в случае соединения с kafka через Kerberos). |
| RISK_CHECKER_KAFKA_AUTH_KEYTAB_PATH | string | нет | "" | Путь до keytab-файла(в случае соединения с kafka через Kerberos). |
| RISK_CHECKER_KAFKA_AUTH_TRUSTSTORE_LOCATION | string | нет | "" | Путь до хранилища сертификатов (Java key store). Если путь не указан, то сертификат применятся не будет. |
| RISK_CHECKER_KAFKA_AUTH_TRUSTSTORE_PASSWORD | string | нет | "" | Пароль к хранилищу сертификатов. |
| RISK_CHECKER_KAFKA_AUTH_MODE | string | нет | "" | Режим аутентификации: static - одна учетная запись на все запросы, mapping - учетная запись зависит от запроса |
| RISK_CHECKER_KAFKA_AUTH_CONFIG | string | нет | "" | Настройки для аутентификации: если AuthMode = mapping, то необходим JSON с List[KafkaAuthConfig] |
| RISK_CHECKER_KAFKA_AUTH_CACHE_SIZE | int | нет | Максимальный размер кеша для Kafka producer (количество активных соединений). | |
| RISK_CHECKER_KAFKA_AUTH_CACHE_TTL | duration string | нет | Время жизни Kafka producer в кеше. | |
| RISK_CHECKER_SYNC_PAGE_SIZE | int | нет | 100 | Размер страницы запросов данных для синхронизации. |
| RISK_CHECKER_CONSUL_ADDR | url string | нет | "http://localhost:8500" | Адрес Сonsul. |
| RISK_CHECKER_CONSUL_AUTH_USER | string | нет | "" | Название учетной записи Сonsul. Если название не указано, то настройки авторизации не будут применены. |
| RISK_CHECKER_CONSUL_AUTH_PASSWORD | string | нет | "" | Пароль учетной записи Сonsul. |
| RISK_CHECKER_TRACE_DURATION | boolean | нет | false | Признак необходимости трассировки выполнения команд |
| RISK_CHECKER_DISCOVERABLE_ID | string | нет | "another_RISK_CHECKER_service_instance" | ID сервиса в ServiceDiscovery |
| RISK_CHECKER_DISCOVERABLE_NAME | string | нет | "riskchecker" | Имя сервиса в ServiceDiscovery |
| RISK_CHECKER_DISCOVERABLE_HOST | string | да | "localhost" | Хост, публикуемый в ServiceDiscovery. По нему на данный сервис будут обращаться другие через HTTP. Указанный адрес должен быть виден другим сервисам. Пример: имя kubernetes/docker_swarm service |
| RISK_CHECKER_DISCOVERABLE_PORT | int | нет | Порт, публикуемый в ServiceDiscovery. По нему на данный сервис будут обращаться другие через HTTP. По умолчанию указывается порт, который слушает HTTP-сервер. | |
| RISK_CHECKER_DISCOVERABLE_LIVETIME | duration string | нет | 2 minutes | Период после последней отправки health check, в течение которого ServiceDiscovery считает данный сервис живым. |
| RISK_CHECKER_DISCOVERABLE_HEALTHPASS | string | нет | 1 minute | Периодичность отправки health check в ServiceDiscovery |
| RISK_CHECKER_SERVICE_TITLE | string | нет | "risk-checker" | Название сервиса для отображения |
| RISK_CHECKER_SERVICE_DESCRIPTION | string | нет | "Service RISK_CHECKER" | Описание сервиса для отображения |
| RISK_CHECKER_AKKA_HTTP_CLIENT_MAXCON | int | нет | 512 | Максимальное число одновременных исходящих HTTP-соединений |
| RISK_CHECKER_AKKA_HTTP_CLIENT_MAXREQ | int | нет | 1024 | Максимальное число одновременных исходящих HTTP-запросов |
| RISK_CHECKER_AKKA_HTTP_SERVER_MAXCON | int | нет | 1024 | Максимальное число одновременных входящих HTTP-соединений |
| RISK_CHECKER_INTERNALCMD_ALLOW | bool | нет | false | Можно ли сервису отправлять внутрисистемные команды |
| RISK_CHECKER_SENDERLIB_COMMANDS_CACHE_UPDATEPERIOD | duration string | нет | 10 minutes | Время кэширования данных по командам из CommandDiscovery |
| RISK_CHECKER_SENDERLIB_SERVICES_CACHE_UPDATEPERIOD | duration string | нет | 30 seconds | Время кэширования данных по сервисам из ServiceDiscovery |
| RISK_CHECKER_DB_HOST | string | да | Хост БД | |
| RISK_CHECKER_DB_PORT | int | да | Порт БД | |
| RISK_CHECKER_DB_NAME | string | да | Имя базы в БД | |
| RISK_CHECKER_DB_URL | jdbc url string | нет | JDBC-url для соединения с БД. По умолчанию собирается из других обязательных переменных. Можно указать только его, если не хочется отдельно указывать хост/порт/имя базы. | |
| RISK_CHECKER_DB_USER | string | да | Пользователь БД | |
| RISK_CHECKER_DB_PASSWORD | string | да | Пароль пользователя БД | |
| RISK_CHECKER_EXTERNAL_MIGRATIONS_RETRY_DELAY | duration string | нет | 15 seconds | Задержка между повторными попытками запуска внешних миграций |
| RISK_CHECKER_EXTERNAL_MIGRATIONS_RETRY_ATTEMPTS | int | нет | 5 | Максимальное количество попыток запуска внешних миграций |
| RISK_CHECKER_EXTERNAL_MIGRATIONS_SKIP_MIGRATIONS | bool | нет | false | Игнорировать ли внешние миграции |
| RISK_CHECKER_CUSTOM_CHANGE_MIGRATIONS_TIMEOUT | duration string | нет | 3 minutes | Максимальное время выполнения одной Liquibase-миграции customChange |
| RISK_CHECKER_LOG_LEVEL | string | нет | INFO | Общий уровень логирования в сервисе |
| RISK_CHECKER_LOG_LEVEL_AKKA | string | нет | INFO | Уровень логирования для akka |
| RISK_CHECKER_LOG_LEVEL_LIQUIBASE | string | нет | INFO | Уровень логирования для liquibase (миграции) |
| RISK_CHECKER_LOG_LEVEL_APPLICATION | string | нет | INFO | Уровень логирования для application |
| RISK_CHECKER_LOG_LEVEL_SLICK_STATEMENT | string | нет | OFF | Уровень логирования SQL-запросов slick в БД |
| RISK_CHECKER_LOG_LEVEL_SLICK_PARAMETER | string | нет | OFF | Уровень логирования параметров запросов slick в БД |
| RISK_CHECKER_LOG_LEVEL_SLICK_BENCHMARK | string | нет | OFF | Уровень логирование времени выполнения запросов slick |
| RISK_CHECKER_LOG_LEVEL_SLICK_RESULT | string | нет | OFF | Уровень логирование первых строк результатов запросов slick |
| RISK_CHECKER_LOG_LEVEL_KAFKA_PRODUCER | string | нет | WARN | Уровень логирования конфига kafka-producer |
| RISK_CHECKER_LOG_LEVEL_KAFKA_CONSUMER | string | нет | WARN | Уровень логирования конфига kafka-consumer |
| RISK_CHECKER_LOG_LEVEL_AKKAHTTPSENDER | string | нет | INFO | Уровень логирования для отправки команд через HTTP. На уровне INFO логируется трассировка, если она включена |
| RISK_CHECKER_LOG_LEVEL_KAFKASENDER | string | нет | INFO | Уровень логирования для отправки команд через Kafka. На уровне INFO логируется трассировка, если она включена |
| RISK_CHECKER_LOG_LEVEL_COMMANDSTATUSCLI | string | нет | INFO | Уровень логирования для проверки состояний команд в сервисе статусов |
| RISK_CHECKER_LOG_LEVEL_HTTP_CLIENT | string | нет | INFO | Уровень логирования HTTP-клиента |
| RISK_CHECKER_COMPLEX_RISK_PARALLELISM | int | нет | 1 | Параллелизм выполнения сложных рисков |
| RISK_CHECKER_LICENSE_MODE | string | нет | "features->default;mlPipeline->extended;services->default" | Описание конфигурации лицензии через ";" в формате: nameOfParameter->valueOfParameter |
| RISK_CHECKER_REPORT_DATE_PATTERN | string | нет | dd.MM.yyyy | Формат записи даты в отчёте по рискам |
| RISK_CHECKER_REPORT_TEMPLATE_BUCKET | string | нет | configs/riskchecker | Путь до папки в s3 с шаблонами. |
| RISK_CHECKER_REPORT_CLIENT_ZONE_ID | string | нет | Europe/Moscow | Таймзона, которая используется при генерации отчета. |
| RISK_CHECKER_LAMP_BUFFER_SIZE | int | нет | 10 | LAMP: размер буфера на отправку сообщений |
| RISK_CHECKER_LAMP_RECONNECT_SCHEDULE | schedule string | нет | I(2 seconds) | LAMP: стратегия переподключения (формат см. lamp.transport.model.Schedule) |
| RISK_CHECKER_LAMP_HOST | url string | нет | lamp-dev.dev.embedika.ru | LAMP: адрес |
| RISK_CHECKER_LAMP_PORT | int | нет | 443 | LAMP: порт |
| RISK_CHECKER_LAMP_TLS | boolean | нет | false | LAMP: использовать защищенное соединение или нет |
| RISK_CHECKER_LAMP_TLS_CERTIFICATE | string | нет | LAMP: путь файла с сертификатом для защищенного подключения | |
| RISK_CHECKER_LAMP_TLS_PRIVATE_KEY | string | нет | LAMP: путь файла с приватным ключем для защищенного подключения | |
| RISK_CHECKER_LAMP_TLS_ROOT_TRUSTED_CERTS | string | нет | LAMP: путь файла с центром сертификации (Certification Authority, CA) для защищенного подключения | |
| RISK_CHECKER_LAMP_TIMEOUT | duration string | нет | 1 minute | LAMP: таймаут отправки сообщения и получения результатов |
| RISK_CHECKER_LAMP_MAX_MESSAGE_SIZE | int | нет | 524288000 | LAMP: максимальный допустимый размер сообщений |
| RISK_CHECKER_SEGMENTOR_URI | url string | нет | http://localhost:1010/segment | RnD: http эндпоинт сервиса сегментации |
| RISK_CHECKER_VECTORIZER_URI | url string | нет | http://localhost:1011/vectorize | RnD: http эндпоинт сервиса векторизации |
| RISK_CHECKER_ML_DETECTION_PREDICT_URI | url string | нет | http://localhost:1012/predict | RnD: http эндпоинт сервиса исполнения ML-моделей Эмбедики |
| RISK_CHECKER_ML_DETECTION_REPLACE_MODEL_URI | url string | нет | http://localhost:1019/replace_model | RnD: http эндпоинт сервиса актуализации версий моделей Эмбедики |
| RISK_CHECKER_ML_DETECTION_CUSTOMERS_PREDICT_URI | url string | нет | http://localhost:1021/predict | RnD: http эндпоинт сервиса исполнения ML-моделей Пользователя |
| RISK_CHECKER_ML_DETECTION_CUSTOMERS_REPLACE_MODEL_URI | url string | нет | http://localhost:1020/replace_model | RnD: http эндпоинт сервиса актуализации версий моделей Пользователя |
| RISK_CHECKER_REGEXP_DETECTION_URI | url string | нет | http://localhost:1014/predict | RnD: http эндпоинт сервиса применения регулярных выражений |
| RISK_CHECKER_NER_DETECTION_URI | url string | нет | http://localhost:1015/predict | RnD: http эндпоинт сервиса выделения маленьких сущностей |
| RISK_CHECKER_COURTS_EXTRACTOR_URI | url string | нет | http://localhost:1014/predict | RnD: http эндпоинт сервиса выделения судов |
| RISK_CHECKER_PREDICTION_FORMATION_URI | url string | нет | http://localhost:1013/form | RnD: http эндпоинт сервиса формирования предсказаний |
| RISK_CHECKER_FS_URI | url string | нет | http://localhost:9000 | Адрес S3 файлового хранилища minio |
| RISK_CHECKER_FS_ACCESS_KEY_ID | string | нет | minioadmin | Идентификатор доступа к minio |
| RISK_CHECKER_FS_SECRET_ACCESS_KEY | string | нет | minioadmin | Секретный ключ доступа к minio |
| RISK_CHECKER_FS_UPLOAD_PARALLELISM | int | нет | 4 | Параллелизм загрузки файлов в minio |
| RISK_CHECKER_FS_CACHE_SIZE | int | нет | 1 | Максимальный размер кеша клиентов для хранилища файлов (количество активных соединений) |
| RISK_CHECKER_FS_CACHE_TTL | duration string | нет | Время жизни клиента в кеше | |
| RISK_CHECKER_FS_CONFIGS_BUCKET | string | нет | riskchecker | Название бакета в minio для файлов конфигурации: entities.json, risks.json, requirements.json, template.docx, company_names.txt (ext.) |
| RISK_CHECKER_FS_TEMP_BUCKET | string | нет | "temp" | Название бакета в Minio, в котором находятся временные файлы |
| RISK_CHECKER_ANALYZED_DOCUMENTS_BUCKET | string | нет | null | Название бакета для хранения обработанных документов, если не определено, то не копирует документы в дополнительный бакет. |
| RISK_CHECKER_KAFKA_CONNECTION_CHECK_TEST_MESSAGES_INTERVAL | duration string | нет | 4 minutes | Применяется только для producer-ов со способом аутентификации kerberos. Интервал отправки тестовых сообщений кафки в топик connectionCheck.testMessagesTopicName. Тестовые сообщения (null, service producer test) отправляются регулярно с этим интервалом. |
| RISK_CHECKER_KAFKA_CONNECTION_CHECK_INTERVAL | duration string | нет | 60 seconds | Применяется только для producer-ов со способом аутентификации kerberos. Интервал проверки того, сколько тестовых сообщений было отправлено за данный период. Если количество сообщений за этот период равно количеству сообщений за прошлый период, то начинается отсчет периода без сообщений. |
| RISK_CHECKER_KAFKA_CONNECTION_CHECK_FAILED_AFTER_INTERVAL | duration string | нет | 5 minutes | Применяется только для producer-ов со способом аутентификации kerberos. Максимальная продолжительность периода без успешно отправленных тестовых сообщений. По ее достижении сервис будет объявлен больным. |
Продуктовые миграции сервиса risk-checker
Ключи настройки:
- deleteAll - удаляет все записи по данному объекту (миграция "с нуля"). Необходим при изменениях в существующих объектах.
- cleanup - удаляет только записи, которых нет в миграции. Существующие записи, которые есть в миграции, пропускаются.
| Название | Описание | Файл | Удаление (cleanup) |
|---|---|---|---|
| Import catalogs | Каталоги и их элементы | catalogs.json | Каталогов (с содержимым), отсутствующих в миграции |
| Import policy rules | Экшены правил, разрешенные группам | actions.json | Версий политик, отсутствующих в миграции |
| Import subscriptions | Групповые подписки на уведомления | subscriptions.json | Подписок отдельных пользователей |
| Import tech constants | Техконстанты для событий журнала | techсonstants.json | Техконстант сервиса risk-checker, отсутствующих в миграции |
| Import user groups | Группы пользователей | groups.json | Групп пользователей, отсутствующих в миграции |
| Import requirements, | Требования чек-листа | requirements.json | Не обрабатывается |
| risks, | Риски на основе выделения сущностей | risks.json | Не обрабатывается |
| entities, | Сущности, выделяемые ML-сервисами | entities.json | Не обрабатывается |
| models | Модели ML-сервиса | models.json | Не обрабатывается |
Список команд сервиса risk-checker
В описании команд используется путь/route для отправки команды в сам сервис, а не в ApiGateway. В качестве Input-а для команд, сервис всегда ожидает CommandRequest (как и любой другой сервис, принимающий команды), так что в описании команды указано лишь описание поля payload для CommandRequest.
В сервисе предусмотрены следующие команды:
| Название команды | EntityType | Actions |
|---|---|---|
| Риск | ||
| Список рисков с указанными ID | Risk | Contract_ViewRisks |
| Список рисков | Risk | Contract_ViewRisks |
| Добавление/обновление рисков | Risk | Contract_EditRisk |
| Изменение простого риска | Risk | Contract_EditRisk |
| Изменение комплексного риска | Risk | Contract_EditRisk |
| Архивация риска | Risk | Contract_ArchiveRisk |
| Активация риска | Risk | Contract_EditRisk |
| Создание простого риска | Risk | Contract_CreateRisk |
| Именованная сущность | ||
| Список сущностей с указанными ID | NamedEntity | Contract_ViewEntities |
| Список сущностей | NamedEntity | Contract_ViewEntities |
| Добавление/обновление сущностей | NamedEntity | Contract_EditEntity |
| Создание сущности | NamedEntity | Contract_CreateEntity |
| Изменение сущности | NamedEntity | Contract_EditEntity |
| Архивация сущности | NamedEntity | Contract_EditEntity |
| Модель | ||
| Список моделей | Model | Contract_ViewModels |
| Активация моделей | Model | Contract_ActivateModels |
| Анализ | ||
| Анализ документа | Contract_ViewAnalyzer | |
| Выгрузка по анализу документа | Contract_ViewAnalyzer | |
| Сортировка результатов анализа | Contract_ViewAnalyzer | |
| Шаблон | ||
| Список шаблонов экспорта | Contract_ViewAnalyzer |
Сервис публикует события для следующих уведомлений:
| Код уведомления | EntityType | Описание |
|---|---|---|
| RiskCreated | Risk | Создан риск |
—Риск—
ListRisksByIds
На входе список ID рисков
[
"FineFee",
"ServiceDateSourcesLinksFound"
]
На выходе список рисков
[
{
"riskType": "Simple",
"name": "Штрафная неустойка",
"id": "FineFee",
"degree": "riskDegree_low",
"documentTypes": [],
"documentSubjects": [],
"mutualSettlementsTypes": [],
"entities": [
{
"id": "FineFee",
"name": "Штрафная неустойка",
"static": false,
"parentId": null,
"found": true
}
],
"recommendation": "...",
"requirement": {
"id": 11,
"text": "Вместо слова «штрафная» и т.п. неустойка однозначно формулировать условия о взыскании убытков в полной сумме сверх неустойки",
"name": "1. Чек-лист общий для всех ДД с резидентами",
"section": "1. Содержание договора",
"version": 1
},
"archived": false,
"created": "1699440881202",
"createdBy": "00000000-0000-0000-0000-000000000001",
"modified": "1699440881202",
"modifiedBy": "00000000-0000-0000-0000-000000000001",
"version": 3
},
{
"riskType": "Complex",
"name": "Сроки определены путем ссылки",
"id": "ServiceDateSourcesLinksFound",
"degree": "riskDegree_low",
"documentTypes": [],
"documentSubjects": [],
"mutualSettlementsTypes": [],
"entities": [
{
"id": "ServiceDateSourcesLinksSubNer",
"name": "Ссылки на другие источники",
"static": true,
"parentId": "ServiceDate",
"found": true
},
{
"id": "ServiceDate",
"name": "Срок оказания услуг/выполнения работ/поставки",
"static": false,
"parentId": null,
"found": true
}
],
"recommendation": "...",
"requirement": {
"id": 51,
"text": "\t\nПроверять наличие в договоре условия о начальном и конечном сроках выполнения работ / оказания услуг. Допускается следующие способы обозначения сроков:\n\nпутем указания конкретных календарных дат (с «___» _______ 20__ года по «___» ________ 20__ года);\n\nпутем указания периодов времени, отсчитываемых от «даты заключения договора» или совершения заказчиком определенных действий (например, перечисление аванса или передачи исходных данных. См. постановление Президиума ВАС РФ от 18.05.2010 № 1404/10).",
"name": "2. Чек-лист Подряд_Услуги",
"section": "",
"version": 1
},
"archived": false,
"created": "1699440881202",
"createdBy": "00000000-0000-0000-0000-000000000001",
"modified": "1699440881202",
"modifiedBy": "00000000-0000-0000-0000-000000000001",
"version": 3
}
]
Возвращает список рисков с указанными в запросе ID. Могут встречаться риски разных типов. Риски приведены к обобщенному виду.
Поддерживается только синхронный вызов.
| Команда | Путь |
|---|---|
| riskchecker_http_ListRisksByIds | HTTP POST "/riskchecker_http_ListRisksByIds" |
- На входе: List[String]
- На выходе: List[Risk]
ListRisks
На входе параметры поиска:
{
"query": "",
"context": {},
"sorting": {},
"paging": {
"page": 1,
"count": 2
}
}
На выходе страница с рисками
{
"items": [
{
"riskType": "Simple",
"name": "Штрафная неустойка",
"id": "FineFee",
"degree": "riskDegree_low",
"documentTypes": [],
"documentSubjects": [],
"mutualSettlementsTypes": [],
"entities": [
{
"id": "FineFee",
"name": "Штрафная неустойка",
"static": false,
"parentId": null,
"found": true
}
],
"recommendation": "...",
"requirement": {
"id": 11,
"text": "Вместо слова «штрафная» и т.п. неустойка однозначно формулировать условия о взыскании убытков в полной сумме сверх неустойки",
"name": "1. Чек-лист общий для всех ДД с резидентами",
"section": "1. Содержание договора",
"version": 1
},
"active": true,
"archived": false,
"created": "1699440881202",
"createdBy": "00000000-0000-0000-0000-000000000001",
"modified": "1699440881202",
"modifiedBy": "00000000-0000-0000-0000-000000000001",
"version": 3
},
{
"riskType": "Complex",
"name": "Сроки определены путем ссылки",
"id": "ServiceDateSourcesLinksFound",
"degree": "riskDegree_low",
"documentTypes": [],
"documentSubjects": [],
"mutualSettlementsTypes": [],
"entities": [
{
"id": "ServiceDateSourcesLinksSubNer",
"name": "Ссылки на другие источники",
"static": true,
"parentId": "ServiceDate",
"found": true
},
{
"id": "ServiceDate",
"name": "Срок оказания услуг/выполнения работ/поставки",
"static": false,
"parentId": null,
"found": true
}
],
"recommendation": "...",
"requirement": {
"id": 51,
"text": "\t\nПроверять наличие в договоре условия о начальном и конечном сроках выполнения работ / оказания услуг. Допускается следующие способы обозначения сроков:\n\nпутем указания конкретных календарных дат (с «___» _______ 20__ года по «___» ________ 20__ года);\n\nпутем указания периодов времени, отсчитываемых от «даты заключения договора» или совершения заказчиком определенных действий (например, перечисление аванса или передачи исходных данных. См. постановление Президиума ВАС РФ от 18.05.2010 № 1404/10).",
"name": "2. Чек-лист Подряд_Услуги",
"section": "",
"version": 1
},
"active": true,
"archived": false,
"created": "1699440881202",
"createdBy": "00000000-0000-0000-0000-000000000001",
"modified": "1699440881202",
"modifiedBy": "00000000-0000-0000-0000-000000000001",
"version": 3
}
],
"total": 47
}
Возвращает список рисков соответствующих параметрам поиска.
Поддерживается только синхронный вызов.
| Команда | Путь |
|---|---|
| riskchecker_http_ListRisks | HTTP POST "/riskchecker_http_ListRisks" |
Доступные поля для фильтрации и виды фильтров по ним:
| Поле | Виды фильтров |
|---|---|
| id | InSetQuery |
| name | InSetQuery, LikeQuery |
| documentType | InSetQuery |
| documentSubject | InSetQuery |
| mutualSettlementsType | InSetQuery |
| active | InSetQuery |
| archived | InSetQuery |
| riskType | InSetQuery |
| degree | InSetQuery |
| entityId / entity.id | InSetQuery |
| entity.name | InSetQuery, LikeQuery |
| entity.found | InSetQuery |
| entity.show | InSetQuery |
Доступные поля для сортировки:
| Поле | Примечание |
|---|---|
| name | |
| created | По умолчанию, по убыванию |
ApplyRiskMigrations
На входе описание рисков для добавления/обновление (или ничего)
[
{
"riskType": "SimpleRisk",
"name": "test1",
"id": "test1",
"degree": "riskDegree_low",
"active": false,
"documentTypes": [
"documentType_agreement"
],
"documentSubjects": [
"documentSubject_contract"
],
"mutualSettlementsTypes": [
"mutSettlementsType_expandable"
],
"requirementId": 1,
"entityId": "Unlimited",
"found": false,
"recommendation": "none"
},
{
"riskType": "ComplexRisk",
"name": "test2",
"id": "test2",
"degree": "riskDegree_low",
"active": false,
"documentTypes": [
"documentType_agreement"
],
"documentSubjects": [
"documentSubject_contract"
],
"mutualSettlementsTypes": [
"mutSettlementsType_expandable"
],
"recommendation": "Any more",
"entities": [
"nerField1"
]
}
]
На выходе список Id рисков
[
"e326cb31-7098-4137-842e-edb0abd3bbc6",
"900f42af-0686-4647-aaa4-dd1e6e9f6023"
]
Сохраняет/обновляет риски в базе по Json со стандартными рисками, или переданному в аргументах Json.
Поддерживается синхронный и асинхронный вызов.
| Команда | Путь |
|---|---|
| riskchecker_kafka_ApplyRiskMigrations | Kafka Topic "risk_checker_commands" |
- На входе: RiskMigrationDto
- На выходе список Id рисков
UpdateSimpleRisk
На входе новые данные риска
{
"id": "FineFee",
"name": "Гига штрафная неустойка",
"degree": "riskDegree_high",
"riskInputData": {
"documentTypes": [
"documentType_agreement"
],
"documentSubjects": [
"document",
""
],
"mutualSettlementsTypes": []
},
"entityId": "FineFee",
"found": false,
"recommendation": "...",
"requirement": {
"id": 1000001,
"text": "Очень новый текст требования",
"name": "1. Очень новое название требования",
"section": "1. Очень новый раздел требования",
"version": 1
},
"version": 4
}
На выходе ничего
{}
Команда обновляет простой риск.
Поддерживается синхронный и асинхронный вызов.
| Команда | Путь |
|---|---|
| riskchecker_kafka_UpdateSimpleRisk | Kafka Topic "risk_checker_commands" |
- На входе UpdateSimpleRiskDto
- На выходе: Unit
UpdateComplexRisk
На входе новые данные риска
{
"id": "WarrantyPeriodParametersMissing",
"name": "Расторжение без согласия предприятия",
"degree": "riskDegree_low",
"riskInputData": {
"documentTypes": [
"documentType_agreement"
],
"documentSubjects": [
"document",
""
],
"mutualSettlementsTypes": []
},
"entities": [
{
"id": "WarrantyPeriod",
"found": true,
"show": true
},
{
"id": "WarrantyPeriodParametersSubNer",
"found": true,
"show": false
}
],
"recommendation": "recommendation",
"requirement": {
"id": 42,
"text": "Какое-то требование",
"name": "Оч строгое требование",
"section": "Секция лыжных гонок",
"version": 1
},
"version": 1
}
На выходе ничего
{}
Команда обновляет комплексный риск.
Поддерживается синхронный и асинхронный вызов.
| Команда | Путь |
|---|---|
| riskchecker_kafka_UpdateComplexRisk | Kafka Topic "risk_checker_commands" |
- На входе UpdateComplexRiskDto
- На выходе: Unit
SetRiskArchived
На входе id риска и новое значение параметра
{
"riskId": "ContractSubjectMissing",
"archived": true,
"version": 7
}
На выходе ничего
{}
Архивирует или извлекает из архива комплексный или простой риск.
Поддерживается синхронный и асинхронный вызов.
| Команда | Путь |
|---|---|
| riskchecker_kafka_SetRiskArchived | Kafka Topic "risk_checker_commands" |
- На входе: SetRiskArchivedDto
- На выходе: Unit
SetRiskStatus
На входе id риска и новое значение active
{
"riskId": "ContractSubjectMissing",
"active": true,
"version": 1
}
На выходе ничего
{}
Активирует или деактивирует риск.
Поддерживается синхронный и асинхронный вызов.
| Команда | Путь |
|---|---|
| riskchecker_kafka_SetRiskStatus | Kafka Topic "risk_checker_commands" |
- На входе: SetRiskActive
- На выходе: Unit
CreateSimpleRisk
На входе id риска и новое значение параметра
{
"id": "HardRisk",
"name": "Жёсткий риск",
"degree": "riskDegree_high",
"entityId": "Unlimited",
"found": true,
"show": true,
"riskInputData": {
"documentTypes": [
"documentType_agreement"
],
"documentSubjects": [
"document",
"documentSubject_contract"
],
"mutualSettlementsTypes": [
"mutSettlementsType_expandable"
]
},
"recommendation": "Жёстко не упускать такого",
"requirementDto": {
"text": "Требование очень жёсткое",
"name": "Название жёсткого требования",
"section": "1. Очень важная"
}
}
На выходе ничего
{}
Добавляет новый простой риск в базу.
Поддерживается синхронный и асинхронный вызов.
| Команда | Путь |
|---|---|
| riskchecker_kafka_CreateSimpleRisk | Kafka Topic "risk_checker_commands" |
- На входе: CreateSimpleRiskDto
- На выходе: Unit
—Именованная сущность—
ListEntitiesByIds
На входе список ID сущностей
[
"Limited",
"FinancialDocumentDates"
]
На выходе список сущностей
[
{
"id": "Limited",
"name": "Ограниченная ответственность",
"static": false,
"projects": [],
"parentId": null,
"archived": false,
"created": 1700461709415,
"createdBy": "00000000-0000-0000-0000-000000000001",
"modified": 1701838574644,
"modifiedBy": "00000000-0000-0000-0000-000000000001",
"version": 2
},
{
"id": "FinancialDocumentDates",
"name": "Сроки предоставления финансовых документов",
"static": false,
"projects": [
{
"id": "1032ce5a-afaf-45a6-a1f0-b0ac036de15f",
"name": "Проект из контракта"
},
{
"id": "1b4dabb3-34ef-4b6d-8205-fa48d730bae0",
"name": "Еще один проект 25.12"
}
],
"parentId": null,
"archived": false,
"created": 1700461709415,
"createdBy": "00000000-0000-0000-0000-000000000001",
"modified": 1701838574644,
"modifiedBy": "00000000-0000-0000-0000-000000000001",
"version": 2
}
]
Возвращает список сущностей с указанными в запросе ID.
Поддерживается только синхронный вызов.
| Команда | Путь |
|---|---|
| riskchecker_http_ListEntitiesByIds | HTTP POST "/riskchecker_http_ListEntitiesByIds" |
- На входе: List[String]
- На выходе: List[NamedEntity]
ListEntities
На входе Search
{
"query": "static",
"context": {
"static": {
"values": [
"true"
],
"kind": "any"
}
},
"sorting": {
"fieldName": "name",
"order": "desc"
},
"paging": {
"page": 1,
"count": 1
}
}
На выходе сущности
{
"items": [
{
"id": "WrongLinks",
"name": "Противоречие в ссылках",
"static": true,
"projects": [],
"risks": [
{
"id": "WrongLinksFound",
"riskType": "Simple",
"name": "Найдено противоречие",
"degree": "riskDegree_high",
"recommendation": "...",
"requirementId": 1,
"active": true,
"archived": true,
"created": 1706524099191,
"createdBy": "00000000-0000-0000-0000-000000000001",
"modified": 1707125527278,
"modifiedBy": "00000000-0000-0000-0000-000000000001",
"version": 3
}
],
"parentId": null,
"archived": false,
"created": 1706524098909,
"createdBy": "00000000-0000-0000-0000-000000000001",
"modified": 1706524098909,
"modifiedBy": "00000000-0000-0000-0000-000000000001",
"version": 1
}
],
"total": 14
}
Возвращает страницу сущностей соответствующих параметрам поиска.
Поддерживается только синхронный вызов.
| Команда | Путь |
|---|---|
| riskchecker_http_ListEntities | HTTP POST "/riskchecker_http_ListEntities" |
- На входе: Search
- На выходе: Page[NamedEntity]
Доступные поля для фильтрации и виды фильтров по ним:
| Поле | Виды фильтров |
|---|---|
| id | InSetQuery |
| name | InSetQuery, LikeQuery |
| static | InSetQuery |
| created | RangeQuery |
| modified | RangeQuery |
Доступные поля для сортировки:
| Поле | Примечание |
|---|---|
| name | |
| created | По умолчанию, по возрастанию |
| modified |
Стандартная сортировка --"created".
UploadEntities
На входе ID файла JSON из временного хранилища
"a80d49f2-a0f7-444b-a6ae-5d74f71379af"
Пример файла JSON: список параметров сущностей для добавления/обновления NamedEntityUpsertDto
[
{
"id": "Unlimited",
"name": "Неограниченная ответственность",
"static": false
},
{
"id": "RetroactiveClause",
"name": "Ретроактивная оговорка",
"static": false
}
]
На выходе количество исходных сущностей, импортированных, не импортированных и список не импортированных сущностей
{
"input": 29,
"succeed": 28,
"failed": 1,
"failedEntities": [
{
"id": "LoanAbsence",
"name": "Отсутствие коммерческого кредита",
"static": false
}
]
}
Сохраняет/обновляет сущности в базе из файла JSON.
Поддерживается синхронный и асинхронный вызов.
| Команда | Путь |
|---|---|
| riskchecker_kafka_UploadEntities | Kafka Topic "risk_checker_commands" |
- На входе: UUID
- На выходе: UploadResult
CreateEntity
На входе id и имя сущности
{
"entityId": "LimitedOne",
"name": "Ограниченная ответственность один"
}
На выходе ничего
{}
Создаёт новую сущность
Поддерживается синхронный и асинхронный вызов. Синхронизируется с NerSetting в Marker
| Команда | Путь |
|---|---|
| riskchecker_kafka_CreateEntity | Kafka Topic "risk_checker_commands" |
- На входе: CreateNamedEntityDto
- На выходе: Unit
UpdateEntity
На входе id и новое имя сущности
{
"entityId": "Limited",
"name": "Ограниченная ответственность",
"version": 2
}
На выходе ничего
{}
Изменяет имя сущности
Поддерживается синхронный и асинхронный вызов. Синхронизируется с NerSetting в Marker
| Команда | Путь |
|---|---|
| riskchecker_kafka_UpdateEntity | Kafka Topic "risk_checker_commands" |
- На входе: UpdateNamedEntityDto
- На выходе: Unit
SetEntityArchived
На входе id сущности и новое значение параметра
{
"entityId": "ContractSubjectMissing",
"archived": true,
"version": 2
}
На выходе ничего
{}
Архивирует или извлекает из архива сущность.
Поддерживается синхронный и асинхронный вызов.
| Команда | Путь |
|---|---|
| riskchecker_kafka_SetEntityArchived | Kafka Topic "risk_checker_commands" |
- На входе: SetEntityArchivedDto
- На выходе: Unit
—Модель—
ListModels
На входе сущности и/или параметры поиска:
{
"query": "",
"context": {
},
"sorting": {
"fieldName": "model.number",
"order": "asc"
},
"paging": {
"page": 1,
"count": 2
}
}
На выходе список моделей
{
"items": [
{
"entityId": "ArbitrationClause",
"nameEntity": "Арбитражная оговорка",
"models": [
{
"modelId": "classifier_ArbitrationClause.catboost",
"number": 0,
"name": "Арбитражная оговорка",
"displayName": "V0 Арбитражная оговорка",
"recall": 80,
"precision": 72,
"fScore": 76,
"active": false,
"activated": null,
"created": 1710502104448,
"version": 1
},
{
"modelId": "classifier_ArbitrationClause_1.catboost",
"number": 1,
"name": "Арбитражная оговорка 1",
"displayName": "V1 Арбитражная оговорка 1",
"recall": 90,
"precision": 90,
"fScore": 90,
"active": false,
"activated": null,
"created": 1710502104449,
"version": 1
}
]
},
{
"entityId": "ActionsCoordination",
"nameEntity": "Согласование действий",
"models": [
{
"modelId": "classifier_ActionsCoordination.catboost",
"number": 0,
"name": "Согласование действий",
"displayName": "V0 Согласование действий",
"recall": 48,
"precision": 72,
"fScore": 58,
"active": true,
"activated": null,
"created": 1710502104448,
"version": 1
}
]
}
],
"total": 2
}
Команда позволяет получить список всех/выбранных моделей.
Поддерживается только синхронный вызов.
| Команда | Путь |
|---|---|
| riskchecker_http_ListModels | HTTP POST /riskchecker_http_ListModels |
- На входе Search
- На выходе: Page[ListModelsEntity]
Доступные поля для фильтрации и виды фильтров по ним:
| Поле | Виды фильтров | Описание |
|---|---|---|
| nameEntity | LikeQuery | Фильтрация по названию сущности |
| entityId | InSetQuery | Фильтрация по Ids сущностей |
Доступные поля для сортировки:
| Поле | Описание | Примечание |
|---|---|---|
| nameEntity | Название сущности | По умолчанию, по возрастанию |
| model.number | Номер модели |
Стандартная сортировка --"model.number".
ActivateModels
На входе список id моделей
[
"classifier_ArbitrationClause.catboost"
]
На выходе ничего
{}
Команда активации моделей разных сущностей
Нельзя передавать модели одной сущности - будет ошибка.
Поддерживается синхронный и асинхронный вызов.
| Команда | Путь |
|---|---|
| riskchecker_kafka_ActivateModels | Kafka Topic "risk_checker_commands" |
- На входе: List[String]
- На выходе: Unit
—Анализ—
GetAnalysis
На входе данные анализируемого документа
{
"url": "somebucket/3a0d88fb-42cf-4171-8feb-ed98c01b2da7",
"originalUrl": "someotherbucket/3a0d88fb-42cf-4171-8feb-ed98c01b2da7",
"documentType": "documentType_agreement",
"documentSubject": "documentSubject_contract",
"mutualSettlementsType": "mutSettlementsType_expandable",
"templateId": "templateRisks.docx"
}
На выходе результат анализа
[
{
"id": "code1",
"degree": "riskDegree_low",
"recommendation": "Recommendation 1",
"riskType": "Simple",
"name": "RiskStub1",
"entities": [
{
"id": "code11",
"name": "code11",
"span": {
"start": 15,
"length": 20
},
"found": true
}
]
},
{
"id": "code2",
"degree": "riskDegree_low",
"recommendation": "Recommendation 2",
"riskType": "Complex",
"name": "RiskStub1",
"entities": [
{
"id": "code21",
"name": "code21",
"span": {
"start": 25,
"length": 10
}
},
{
"id": "code22",
"name": "code22",
"span": null
}
]
},
{
"id": "code4",
"degree": "riskDegree_low",
"recommendation": "Recommendation 4",
"riskType": "Complex",
"name": "RiskStub4",
"entities": []
}
]
Команда запускает процесс анализа документа и возвращает результат. Этот процесс может занимать длительное время, рекомендуется вызывать асинхронно.
Команда может сохранить обрабатываемый документ, если это включено в конфигурации сервиса.
Поддерживается синхронный и асинхронный вызов.
| Команда | Путь |
|---|---|
| riskchecker_kafka_GetAnalysis | Kafka Topic "risk_checker_commands" |
- На входе: GetAnalysis
- На выходе: List[RiskAnalysis]
ExportAnalysis
На входе результат анализа (с некоторыми изменениями)
{
"fileName": "analysis.pdf",
"templateId": "templateRisks.docx",
"risks": [
{
"id": "stub-2",
"name": "Право на одностороннее изменение",
"degree": "riskDegree_low",
"recommendation": "Убрать право на одностороннее изменение",
"riskType": "Complex",
"entities": [
{
"id": "nerField22",
"span": "kzkzkzkzkkляляляяллялял ляляляляля",
"found": null
},
{
"id": "nerField13",
"span": "dfhdfhdfhdf sdgsdg sdf gsd",
"found": null
}
]
}
]
}
На выходе url pdf-файла с выгрузкой
"pdf/b80bd9b1-21e0-4e28-a58e-f695a48d1537"
Команда принимает результат анализа документа и возвращает ссылку на сгенерированный отчет. Входные данные аналогичны результату анализа с одной правкой: в поля "span" нужно указывать конкретные выделенные строки, а не объекты-спаны.
Поддерживается синхронный и асинхронный вызов.
| Команда | Путь |
|---|---|
| riskchecker_kafka_ExportAnalysis | Kafka Topic "risk_checker_commands" |
- На входе: AnalysisInput
- На выходе: String
SortAnalysis
На входе список рисков из результата анализа и Id шаблона выгрузки.
{
"templateId": "templateRisks.docx",
"risks": [
{
"id": "code2",
"degree": "riskDegree_low",
"recommendation": "Recommendation 2",
"riskType": "Complex",
"name": "RiskStub1",
"entities": [
{
"id": "code21",
"name": "code21",
"span": {
"start": 25,
"length": 10
}
},
{
"id": "code22",
"name": "code22",
"span": null
}
]
},
{
"id": "code1",
"degree": "riskDegree_low",
"recommendation": "Recommendation 1",
"riskType": "Simple",
"name": "RiskStub1",
"entities": [
{
"id": "code11",
"name": "code11",
"span": {
"start": 15,
"length": 20
},
"found": true
}
]
},
{
"id": "code4",
"degree": "riskDegree_low",
"recommendation": "Recommendation 4",
"riskType": "Complex",
"name": "RiskStub4",
"entities": []
}
]
}
На выходе упорядоченный список рисков
[
{
"id": "code1",
"degree": "riskDegree_low",
"recommendation": "Recommendation 1",
"riskType": "Simple",
"name": "RiskStub1",
"entities": [
{
"id": "code11",
"name": "code11",
"span": {
"start": 15,
"length": 20
},
"found": true
}
]
},
{
"id": "code2",
"degree": "riskDegree_low",
"recommendation": "Recommendation 2",
"riskType": "Complex",
"name": "RiskStub1",
"entities": [
{
"id": "code21",
"name": "code21",
"span": {
"start": 25,
"length": 10
}
},
{
"id": "code22",
"name": "code22",
"span": null
}
]
},
{
"id": "code4",
"degree": "riskDegree_low",
"recommendation": "Recommendation 4",
"riskType": "Complex",
"name": "RiskStub4",
"entities": []
}
]
Команда сортирует список рисков в соответствии с шаблоном выгрузки.
Поддерживается только синхронный вызов.
| Команда | Путь |
|---|---|
| riskchecker_http_SortAnalysis | HTTP POST "/riskchecker_http_SortAnalysis" |
- На входе: SortAnalysisDTO
- На выходе: List[RiskAnalysis]
—Шаблон—
ListAllTemplates
На входе пустой объект
{}
На выходе список шаблонов
[
{
"id": "templateRisks.docx",
"name": "Шаблон отчета по рискам",
"default": true,
"format": "docx",
"grouping": true,
"notFoundFirst": true,
"emptyFragment": "Test",
"created": 1710502104448,
"createdBy": "00000000-0000-0000-0000-000000000001",
"modified": 1710502104448,
"modifiedBy": "00000000-0000-0000-0000-000000000001",
"version": 1
}
]
Команда возвращает список всех шаблонов отчетов.
Поддерживается только синхронный вызов.
| Команда | Путь |
|---|---|
| riskchecker_http_ListAllTemplates | HTTP POST "/riskchecker_http_ListAllTemplates" |
- На входе: {}
- На выходе: List[TemplateStoreDTO]
Список маршрутов сервиса risk-checker
Сервис реализует маршруты для прямого обращения ML-сервисов (нельзя отправить такой запрос через ApiGateway).
| Путь | На входе | На выходе | Конфигурации | Описание |
|---|---|---|---|---|
| /model-mapping | {} | Map[string, string] | default/extended | Маппинг ID сущности -> ID модели Эмбедики |
| /model-mapping-customers | {} | Map[string, string] | extended | Маппинг ID сущности -> ID модели пользователей |
Объекты сервиса risk-checker
Типы данных, которые принимает на вход команд сервис или возвращает в результате работы команды.
—Риск—
Risk
Обобщенный вид для всех типов рисков.
Возможные типы:
Simple- ПростойComplex- Сложный
В таблице ниже в колонках "Простой" и "Сложный" указано, обязательно ли поле в том или ином типе рисков. Да - обязательно, нет - необязательно, прочерк - отсутствует в рисках данного типа.
| Поле | Тип | Простой | Сложный | Описание |
|---|---|---|---|---|
| riskType | string | да | да | Тип риска |
| name | string | да | да | Наименование риска |
| id | string | да | да | id риска |
| degree | string | да | да | Степень риска |
| documentTypes | string | да | да | Тип документа |
| documentSubjects | string | да | да | Предмет документа |
| mutualSettlementsTypes | string | да | да | Вид взаиморасчетов |
| entities | NamedEntity[] | да | да | ID сущностей |
| found | boolean | да | - | Найдена или нет |
| recommendation | string | да | да | Рекомендация |
| requirement | Requirement | да | да | Требование чек-листа |
| active | boolean | да | да | Активный ли риск |
| archived | boolean | да | да | Архивирован или нет |
| created | TimeStamp | да | да | Время создания |
| createdBy | UserId | да | да | Кем создан |
| modified | TimeStamp | да | да | Время последнего изменения |
| modifiedBy | UserId | да | да | Кто последний раз изменил |
| version | number | да | да | Версия |
Requirement
Информация о требовании чек-листа
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| id | int | да | Id сущности |
| text | string | да | Текст требования |
| name | string | да | Название чек листа |
| section | string | да | Название раздела чек-листа |
| version | number | да | Версия |
RequirementDto
Информация о требовании чек листа для создания риска
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| text | string | да | Текст требования |
| name | string | да | Название чек листа |
| section | string | да | Название раздела чек-листа |
RiskMigrationDto
Общие поля:
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| riskType | "SimpleRisk" или "ComplexRisk" | да | Какой тип риска |
| name | string | да | Название риска |
| id | string | да | id риска |
| active | boolean | нет | Активный ли риск (при создании дефолтно false) |
| degree | string | да | Степень риска |
| recommendation | string | да | Рекомендация |
| requirementId | int | да | Id требования |
| documentTypes | Map[string, boolean] | да | Тип документа |
| documentSubjects | Map[string, boolean] | да | Предмет документа |
| mutualSettlementsTypes | Map[string, boolean] | да | Вид взаиморасчетов |
SimpleRisk:
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| entityId | string | да | Поле именованной сущности |
| found | boolean | да | Присутствует ли сущность в тексте |
ComplexRisk:
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| entities | Map[String, Boolean] | да | Поля именованных сущностей и признак, найдена ли она |
SetRiskActive (DTO)
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| riskId | string | да | Id риска |
| active | boolean | да | Новое значение активности риска |
| version | int | да | Версия |
SetRiskArchived (DTO)
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| riskId | string | да | Id риска |
| archived | boolean | да | Новое значение архивности риска |
| version | int | да | Версия |
UpdateSimpleRiskDto
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| id | string | да | id риска |
| name | string | да | Название риска |
| degree | string | да | Степень риска |
| recommendation | string | да | Рекомендация |
| requirement | Requirement | да | Требование чек-листа |
| riskInputData | RiskInputData | да | Данные о документах риска |
| entityId | string | да | Код сущности |
| found | boolean | да | Найдена или нет |
| version | int | да | Версия |
UpdateComplexRiskDto
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| id | string | да | id риска |
| name | string | да | Название риска |
| degree | string | да | Степень риска |
| riskInputData | RiskInputData | нет | Данные о документах риска |
| entities | RiskToEntity[] | да | Сущности риска |
| recommendation | string | да | Рекомендация |
| requirement | Requirement | да | Требование |
| version | int | да | Версия |
CreateSimpleRiskDto
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| id | string | да | Id риска |
| name | string | да | Название риска |
| degree | string | да | Степень риска |
| entityId | string | да | Код сущности |
| found | boolean | да | Найдена или нет |
| show | boolean | да | Показывать или нет |
| riskInputData | RiskInputData | да | Данные о документах риска |
| recommendation | string | да | Рекомендация |
| requirementDto | RequirementDto | да | Требование |
RiskInputData
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| documentTypes | string[] | да | Тип документа |
| documentSubjects | string[] | да | Предмет документа |
| mutualSettlementsTypes | string[] | да | Вид взаиморасчетов |
RiskStoreDto
Плоское представление риска без связанных объектов
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| riskType | string | да | Тип риска |
| name | string | да | Наименование риска |
| id | string | да | id риска |
| degree | string | да | Степень риска |
| recommendation | string | да | Рекомендация |
| active | boolean | да | Активный ли риск |
| archived | boolean | да | Архивирован или нет |
| created | TimeStamp | да | Время создания |
| createdBy | UserId | да | Кем создан |
| modified | TimeStamp | да | Время последнего изменения |
| modifiedBy | UserId | да | Кто последний раз изменил |
| version | number | да | Версия |
—Именованная сущность—
NamedEntity
Информация о сущности
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| id | string | да | Код сущности |
| name | string | да | Название сущности |
| static | boolean | да | Признак привязки к Marker |
| projects | Project[] | да | Список проектов |
| archived | boolean | да | Признак архивности |
| parentId | string | нет | Код родительской сущности |
| created | TimeStamp | да | Время создания сущности |
| createdBy | UserId | да | Id пользователя, который создал сущность |
| modified | TimeStamp | да | Время последнего изменения сущности |
| modifiedBy | UserId | да | Id пользователя, который последний раз редактировал сущность |
| version | number | да | Версия объекта |
| risks | List[RiskStoreDto] | да | Риски использующие эту сущность |
NamedEntityUpsertDto
Информация о сущности для импорта
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| code | string | да | Код сущности |
| name | string | да | Название сущности |
| static | boolean | да | Признак привязки к Marker |
CreateNamedEntityDto
Информация для изменения имени сущности
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| entityId | string | да | Id сущности |
| name | string | да | Название сущности |
UpdateNamedEntityDto
Информация для изменения имени сущности
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| entityId | string | да | Id сущности |
| name | string | да | Название сущности |
| version | int | да | Версия |
SetEntityArchived (DTO)
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| entityId | string | да | Id сущности |
| archived | boolean | да | Новое значение архивности риска |
| version | int | да | Версия |
RiskToEntity
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| id | string | да | Id сущности |
| found | boolean | да | Найдено ли условие |
| show | boolean | да | Показывать ли в результатах |
UploadResult
Результат загрузки сущностей из файла
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| input | int | да | Количество сущностей в файле |
| succeed | int | да | Количество успешно импортированных сущностей |
| failed | int | да | Количество сущностей, не найденных в Marker |
| failedEntities | NamedEntityUpsertDto[] | нет | Список не импортированных сущностей |
Project
Информация о проекте
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| id | uuid | да | ID проекта |
| name | string | да | Название проекта |
—Модель—
ListModelsEntity
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| entityId | string | да | Id сущности |
| nameEntity | string | да | Название сущности |
| models | List[ModelVersionInfo] | да | Модели сущности |
ModelVersionInfo
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| modelId | string | да | Id модели |
| number | int | да | Номер модели |
| name | string | да | Название модели |
| displayName | string | да | Название модели с версией |
| recall | int | да | Полнота модели |
| precision | int | да | Точность модели |
| fScore | int | да | F мера |
| active | boolean | да | Активность модели |
| activated | TimeStamp | нет | Дата активации модели |
| created | TimeStamp | да | Дата обучения модели |
| version | int | да | Версия |
—Анализ—
GetAnalysis (DTO)
Запрос анализа документа
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| url | string | да | Ссылка на анализируемый файл |
| originalUrl | string | нет | Ссылка на файл до конвертации в pdf |
| documentType | string | нет | Тип документа |
| documentSubject | string | нет | Предмет документа |
| mutualSettlementsType | string | нет | Вид взаиморасчетов |
| templateId | string | нет | Id шаблона выгрузки, нужно для первичной сортировки |
RiskAnalysis
Информация по отдельному риску в результате анализа документа
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| id | string | да | id риска |
| degree | string | да | Степень риска |
| recommendation | string | да | Рекомендация |
| riskType | string | да | Тип риска |
| entities | AnalysisEntity[] | да | Список сущностей |
AnalysisEntity
Информация о сущности в результате анализа документа
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| id | uuid | да | ID сущности |
| span | TextSpan | нет | Позиция в тексте |
| found | boolean | да | Присутствует ли сущность в тексте (только простые риски) |
| name | string | да | Название сущности |
| subNers | AnalysisEntity[] | нет | Список подсущностей сущности |
| recommendation | string | нет | Рекомендация |
TextSpan
Позиция сущности в тексте
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| start | int | да | Позиция первого символа сущности от начала текста |
| length | int | да | Длина сущности в символах |
AnalysisInput
Входные данные для отчета по анализу
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| fileName | string | да | Имя возвращаемого файла |
| templateId | string | нет | Id шаблона, который нужно применить к файлу |
| risks | RiskAnalysisInput[] | да | Выделенные риски |
RiskAnalysisInput
Информация по отдельному риску в результате анализа документа (входные данные для отчета)
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| id | string | да | id риска |
| degree | string | да | Степень риска |
| recommendation | string | да | Рекомендация |
| riskType | string | да | Тип риска |
| entities | AnalysisEntityInput[] | да | Список сущностей |
AnalysisEntityInput
Информация о сущности в результате анализа документа (входные данные для отчета)
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| id | uuid | да | ID сущности |
| span | string | нет | Выделенный текст, соответствующий сущности |
| found | boolean | да | Присутствует ли сущность в тексте (только простые риски) |
| name | string | да | Название сущности |
| subNers | AnalysisEntityInput[] | нет | Список подсущностей сущности |
SortAnalysisDTO
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| risks | List[RiskAnalysis] | да | Список рисков |
| templateId | string | нет | Id шаблона выгрузки |
—Шаблон—
TemplateStoreDTO
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| id | string | да | Id шаблона |
| name | string | да | Название шаблона |
| default | boolean | да | Является ли шаблоном по умолчанию |
| format | "docx" \ | "pdf" | да |
| grouping | boolean | да | Группировка рисков |
| notFoundFirst | boolean | да | Показывать ли не найденные риски первыми |
| emptyFragment | string | нет | Фрагмент для пустого отчета |
| created | TimeStamp | да | Время создания |
| createdBy | UserId | да | Кем создан |
| modified | TimeStamp | да | Время последнего изменения |
| modifiedBy | UserId | да | Кто последний раз изменил |
| version | int | да | Версия |