NAV
json

Contract: анализатор документов

Contract by Embedika — решение для анализа и проверки документов на риски. Помогает быстро и эффективно выделять нежелательные условия в тексте документа и предлагает рекомендации по их устранению.

Архитектурные решения Contract

Записи об архитектурных решениях, реализованных в продукте Contract.

Продуктивизация

Context

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

Considered Options

  1. Вынести алгоритмы обработки рисков под каждого заказчика в отдельный jar-файл и подключать в зависимости от проекта.
    • В итоги пришли к универсальному алгоритму под все риски, из-за чего необходимость вынесения алгоритмов отдельно отпала.
  2. Вынести общий код сервиса в библиотеку, создавать на её основе реализацию сервиса под каждого заказчика.
    • Сложно поддерживать большое количество сервисов.
    • Нельзя просто развернуть один из сервисов у нового заказчика, т. к. он содержит кастом.
  3. Один универсальный сервис, который содержит в себе реализации под всех заказчиков, выбирать нужную настройками окружения.
    • Размер сервиса будет неограниченно возрастать и занимать лишнее место, т. к. использоваться будет только одна реализация.
    • Сложно поддерживать код, т. к. реализации начинают пересекаться внутри сервиса, отделить их будет большой проблемой.
  4. Один универсальный сервис, но весь кастом под заказчика выносится из исходного кода сервиса наружу.
    • Используется универсальный формат конфигов, которые понятны и могут поддерживаться не только программистами.
    • Конфиги + модели под конкретного заказчика нужно собирать в отдельный образ для облегчения развертывания.

Decision

Выполняем один универсальный сервис: risk-checker. Выносим кастомизацию под нужды заказчика в Json-файлы конфигурации.

Реализован перенос данных из Json во внешние сервисы и собственную БД путем выполнения Liquibase-миграции. Чтение Json выполняется из файлового хранилища S3.

Перед запуском сервиса должна выполняться джоба config-pusher (копирует файлы из образа в S3). Для контроля актуальности данных используется файл version с номером релиза - и в коде сервиса, и в S3 номера релиза должны совпадать (миграция упадет при несовпадении).

Positive Consequences

Negative Consequences

Импорт конфигурации системы

Context

Для работы анализатора нужно загрузить первоначальные данные в систему (требования чек-листа, риски, сущности, модели, каталоги, группы пользователей, политики, подписки, техконстанты). Набор первоначальных данных определяется требованиями заказчика и берется из Json-файлов ( см. Продуктивизация).

Considered Options

  1. Загрузка данных командой.
    • На каждую разновидность объекта нужна отдельная команда на импорт и интерфейс для её выполнения.
    • Не обеспечивается автоматическое развертывание, необходимое для некоторых объектов (группы и политики).
    • Нужна инструкция для админа с порядком импорта.
    • Некоторые миграции зависят друг от друга и не могут выполняться раздельно, а делать одновременный импорт из разных файлов сложно.
  2. Миграция Verdi (ExternalMigration) - механизм, встроенный в шаблон сервиса Verdi.
    • Выполняется при каждом перезапуске сервиса, хотя достаточно один раз при развертывании релиза (лишняя нагрузка, замедление запуска, вопросы от техподдержки).
    • Для каждой миграции нужно придумывать свой механизм вычисления needExecution из-за разной архитектуры API сервисов.
    • Не понятно, выполнилась миграция или нет, т. к. нет чейнджлога.
    • Сервис запускается и работает, даже если упала миграция.
  3. Миграция Liquibase:
    • Сервис не будет запущен, если упала миграция, что гарантирует обновление всех данных.
    • В таблице databasechangelog отображаются выполенные миграции.
    • Удалением из databasechangelog можно инициировать перезапуск миграции при необходимости.

Decision

Миграции импорта кастомизации под заказчика используют Liquibase. Для удобства они имеют схожую структуру и наследуются от трейта SystemImport. Перезапуск миграции из кода инициируется изменением номера задачи в названии Changeset / имени автора.

Positive Consequences

Negative Consequences

risk-checker: сервис анализатора

Сервис принимает запросы для работы с рисками. Состояние хранится в PostgreSQL. Команды могут приходить как по HTTP, так и через Kafka в топик risk_checker_commands.

Сервис разбит на несколько модулей, в виде sbt проектов:

Информация по добавлению команд можно прочитать в описании шаблона

Локальный запуск сервиса risk-checker

При запуске сервиса ожидается, что уже развернута необходимая инфраструктура:

Запуск из консоли с помощью 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_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_NAME 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_CLIENT_ZONE_ID string нет Europe/Moscow Таймзона, которая используется при генерации отчета.
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_TIMEOUT duration string нет 1 minute 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_RATE_LIMITING_CONCURRENCY int нет 10 Ограничение на количество одновременно запущенных проверок документов
RISK_CHECKER_RATE_LIMITING_TIMEOUT duration string нет 1 minute Таймаут на запросы проверки документа.

Продуктовые миграции сервиса risk-checker

Ключи настройки:

Название Описание Файл Удаление (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 Не обрабатывается
templates Шаблоны отчета с настройками templates.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"

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"

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"

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"

SetRiskArchived

На входе id риска и новое значение параметра

{
  "riskId": "ContractSubjectMissing",
  "archived": true,
  "version": 7
}

На выходе ничего

{}

Архивирует или извлекает из архива комплексный или простой риск.

Поддерживается синхронный и асинхронный вызов.

Команда Путь
riskchecker_kafka_SetRiskArchived Kafka Topic "risk_checker_commands"

SetRiskStatus

На входе id риска и новое значение active

{
  "riskId": "ContractSubjectMissing",
  "active": true,
  "version": 1
}

На выходе ничего

{}

Активирует или деактивирует риск.

Поддерживается синхронный и асинхронный вызов.

Команда Путь
riskchecker_kafka_SetRiskStatus Kafka Topic "risk_checker_commands"

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"

Именованная сущность

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"

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"

Доступные поля для фильтрации и виды фильтров по ним:

Поле Виды фильтров
id InSetQuery
name InSetQuery, LikeQuery
static InSetQuery
parentId InSetQuery
archived InSetQuery
created RangeQuery
modified RangeQuery

Доступные поля для сортировки:

Поле Примечание
name
created По умолчанию, по возрастанию
modified

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"

CreateEntity

На входе id и имя сущности

{
  "entityId": "LimitedOne",
  "name": "Ограниченная ответственность один"
}

На выходе ничего

{}

Создаёт новую сущность

Поддерживается синхронный и асинхронный вызов. Синхронизируется с NerSetting в Marker

Команда Путь
riskchecker_kafka_CreateEntity Kafka Topic "risk_checker_commands"

UpdateEntity

На входе id и новое имя сущности

{
  "entityId": "Limited",
  "name": "Ограниченная ответственность",
  "version": 2
}

На выходе ничего

{}

Изменяет имя сущности

Поддерживается синхронный и асинхронный вызов. Синхронизируется с NerSetting в Marker

Команда Путь
riskchecker_kafka_UpdateEntity Kafka Topic "risk_checker_commands"

SetEntityArchived

На входе id сущности и новое значение параметра

{
  "entityId": "ContractSubjectMissing",
  "archived": true,
  "version": 2
}

На выходе ничего

{}

Архивирует или извлекает из архива сущность.

Поддерживается синхронный и асинхронный вызов.

Команда Путь
riskchecker_kafka_SetEntityArchived Kafka Topic "risk_checker_commands"

Модель

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

Доступные поля для фильтрации и виды фильтров по ним:

Поле Виды фильтров Описание
nameEntity LikeQuery Фильтрация по названию сущности
entityId InSetQuery Фильтрация по Ids сущностей

Доступные поля для сортировки:

Поле Описание Примечание
nameEntity Название сущности По умолчанию, по возрастанию
model.number Номер модели

Стандартная сортировка --"model.number".

ActivateModels

На входе список id моделей

[
  "classifier_ArbitrationClause.catboost"
]

На выходе ничего

{}

Команда активации моделей разных сущностей

Нельзя передавать модели одной сущности - будет ошибка.

Поддерживается синхронный и асинхронный вызов.

Команда Путь
riskchecker_kafka_ActivateModels Kafka Topic "risk_checker_commands"

Анализ

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"

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"

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"

Шаблон

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"

Список маршрутов сервиса 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

Обобщенный вид для всех типов рисков.

Возможные типы:

В таблице ниже в колонках "Простой" и "Сложный" указано, обязательно ли поле в том или ином типе рисков. Да - обязательно, нет - необязательно, прочерк - отсутствует в рисках данного типа.

Поле Тип Простой Сложный Описание
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 да Версия

Lamp: сервисы интеллектуализации

lamp-router

Сервис выступает точкой входа в систему lamp, принимает запросы и проводит их по маршрутам. Также обеспечивает кэширование.

Локальный запуск сервиса

Для нужд разработки contract и marker достаточно переменных среды:

Переменная Тип Описание
ROUTER_ROUTES json array string Route JSON с описанием маршрутов
ROUTER_SERVICES_JSON json string JSON с указанием адресов сервисов

Взаимодействие с lamp-router

Установка клиента lamp-router

val lampClient: Seq[ModuleID] = Seq(
  "com.embedika.lamp" %% "proto20"       % lamp20ProtoVersion,
  "com.embedika.lamp" %% "lamp20-client" % lamp20ClientVersion,
)

Взаимодействие с lamp-router выполняется через клиент, api клиента довольно простое. Стоит учитывать, что клиент и router не преобразуют данные, поэтому полученные из клиента байты нужно преобразовать согласно используемому маршруту самостоятельно.

Если ответ в формате json, то нужно провести десериализацию, если protobuf, то нужно извлечь данные в подходящий класс.

Модели сервиса lamp-router

Route

Поле Тип Обязательное Описание
name string да Название
nodes Array[ServiceNode \ BeginNode ] да

ServiceNode

Узел для работы с сервисами Lamp

Поле Тип Обязательное Описание
name string да Название
out string да Выход
params Map нет Параметры

BeginNode

Узел с фиксированным именем "begin"

Поле Тип Обязательное Описание
out string да Выход

extraction-pdfium

Сервис извлечения текста из pdf файлов с использованием pdfium.

Локальный запуск сервиса

Поддерживаемые переменные среды:

Переменная Тип Значение по умолчанию Описание
EXTRACTION_PDFIUM_EOL_SEPARATOR string "\u205F" Строка которую нужно заменить на EXTRACTION_PDFIUM_EOL_SEPARATOR_REPLACEMENT
EXTRACTION_PDFIUM_EOL_SEPARATOR_REPLACEMENT string "\u2005" Строка на которую нужно заменить EXTRACTION_PDFIUM_EOL_SEPARATOR
EXTRACTION_PDFIUM_EOL_PAGE_SEPARATOR string "\u205F" Строка через которую склеивается экстракция с разных страниц

Также сервис поддерживает переменные среды play framework.

Параметры маршрутов

В поле params в узле маршрута extraction-pdfium можно указать следующие параметры:

Параметр Тип Обязательное Описание
requestType "proto" \ "file" да
responseType "proto" \ "json" \ "file"

Взаимодействие с extraction-pdfium

Можно работать через lamp-router или напрямую. При работе через lamp-router вызывается метод process.

/process

Принимает MultiPartFormData.

Параметр Тип Описание
data BytesMessage или MultiPartFile Файл pdf в формате protobuf
params Map[String, String] Параметры маршрута

Возвращаемое значение зависит от параметра responseType.

Модели сервиса extraction-pdfium

ExtractionMessage

Поле Тип Обязательное Описание
content string да Текст
fromPdfExtractor true да Секретный параметр, значение которого где-то полезно, но это не точно