Перейти к содержанию

Аддоны

Материал из Химсофт Вики

Список демонстрационных аддонов, показывающих возможности интеграционного сервиса.

Проверка даты регистрации. check-registration-date

Проверяет, не истёк ли срок регистрации пробы. Сравнивает дату регистрации из указанного поля с текущей датой. Если прошло более заданного количества дней (по умолчанию — 10), выдаёт ошибку. В противном случае показывает сообщение об успешной проверке.

   Просмотр кода
   
import { JournalRecordManager } from "../../src/servivces/worker/api/interactors"
import { MessageBoxResults } from "@triteia/types-integration-gui"
import { getDataFromDialog } from "../../src/gui/api"
import { DialogType } from "@triteia/types-integration-gui"

const config = {
    dateField: 'Дата регистрации',
    expirationLimit: 10,
    journalRecordId: 201, // Лаб. воздуха / Анализы завершены
    integrationResult: { message: 'Срок регистрации пробы не истёк !'}
}

const messages = {
    queryParamsNotFound: 'Отсутствуют необходимые параметры для выполнения аддона. Дальнейшее выполнение невозможно',
    socketNotFound: 'Отсутствует соединение с клиентом. Дальнейшее выполнение аддона невозможно',
    success: (recordId) => `Срок регистрации пробы не истёк ! Id записи ${recordId}`,
    expired: (limit, recordId) => `Срок регистрации пробы истёк!\nПрошло более ${ limit } дней с момента регистрации. Id записи: ${recordId}`,
    dateField: (dateField, stageName, journalRecordId) => [
        `Не заполнено либо отсутствует поле "${dateField}"`,
        `в этапе "${stageName || ''}".\nId записи: ${journalRecordId}`
    ].join(' ')
}

const errorHandlers = {
    queryParamsError: () => {
        throw new Error(messages.queryParamsNotFound)
    },
    socketError: () => {
        throw new Error(messages.socketNotFound)
    },
    dateError: (dateField, stageName, journalRecordId) => {
        throw new Error(messages.dateField(dateField, stageName, journalRecordId))
    },
    expirationError: () => {
        throw new Error(messages.expired(config.expirationLimit, config.journalRecordId))
    }
}

const getSocketId = (queryParams: any) => {
    const socketId = Array.isArray(queryParams?.socketId) && queryParams?.socketId?.length ? queryParams?.socketId[0] : '';

    if (!queryParams) errorHandlers.queryParamsError()
    if (!socketId) errorHandlers.socketError()
  
    return socketId
}

const getDaysByDate = (date: Date) => {
    const dayMs = 60 * 60 * 24 * 1000
    const timestamp = date.getTime()
    return timestamp/dayMs
}

const getConfig = (type: DialogType, title: string, message) => {
    return {
        type,
        config: {
            title,
            message
        }
    }
}

const getExpirationOffset = (registrationDate: string) => {
    const regDate = new Date(registrationDate)
    const today = new Date()
    return getDaysByDate(today) - getDaysByDate(regDate)
}

const showErrorMessage = async (message: string, socketId) => getDataFromDialog(getConfig('confirm', 'Ошибка', message), socketId);
const showSuccessMessage = async (message: string, socketId) => getDataFromDialog(getConfig('confirm', 'Внимание', message), socketId);

async function main({ queryParams }) {

    const socketId = getSocketId(queryParams)

    try {
        const journalRecordManager = await JournalRecordManager(config.journalRecordId)
        const date = journalRecordManager.getFieldValue(config.dateField)

        if (!date) errorHandlers.dateError(config.dateField, journalRecordManager?.data?.stage?.stage?.name, config.journalRecordId)

        const expirationOffset = getExpirationOffset(date as string)

        if (expirationOffset >= config.expirationLimit) errorHandlers.expirationError()

        await showSuccessMessage(messages.success(config.journalRecordId), socketId)

        return config.integrationResult
    } catch (err) {
        await showErrorMessage(err.message, socketId)
        return { error: err.message }
    }
}

module.exports = { main }

Проверка заполненности полей показателей. check-indicator-fields-filled

Проверяет заполненность полей показателей в записи журнала по настраиваемому списку. Проверяет наличие определённых показателей (например, "Аммоний-ион") и заполненность у них таких полей, как исполнители, методики, средний результат и др. Выдаёт ошибку, если показатели отсутствуют или не все поля заполнены.

   Просмотр кода
   
import { JournalRecordManager } from "../../src/servivces/worker/api/interactors"
import { getDataFromDialog } from "../../src/gui/api"
import type { DialogType } from "@triteia/types-integration-gui"
import type { JournalRecordIndicatorResponse } from "../../src/servivces/worker/api/controllers/journal-records"
import type { IJournalRecordManager } from "../../src/servivces/worker/api/interactors/JournalRecordManager/interface"

type IndicatorProp = { label: string, get: () => unknown }
type IndicatorPropsConfig = Record<string, IndicatorProp>

const indicatorPropsConfig = (indicator): IndicatorPropsConfig => {
    return {
        executors: {
            label: 'Исполнители', 
            get: () => indicator?.result?.executors
        },
        methodic: {
            label: 'Методики', 
            get: () => indicator?.methodics
        },
        averageResult: {
            label: 'Средний результат', 
            get: () => indicator?.result?.averageValue
        },
        averageRoundedValue: {
            label: 'Средний округлённый результат', 
            get: () => indicator?.result?.averageRoundedValue
        }
    }
}

const config = {
    requiredFields: [
        'Источник',
        'Место отбора',
        'Дата регистрации',
        'Шифр пробы',
        'Время регистрации'
    ],
    indicatorsList: [
        'Аммоний-ион'
    ],
    journalRecordId: 144, // Мк / Тест_Ушакова
    integrationResult: { message: 'Все поля заполнены!' }
}

const messages = {
    socketNotFound: 'Отсутствует соединение с клиентом. Дальнейшее выполнение аддона невозможно',
    queryParamsNotFound: 'Отсутствуют необходимые параметры для выполнения аддона. Дальнейшее выполнение невозможно',
    success: 'Все необходимые поля заполнены!',
    emptyIndicators: (recordId) => `в записи с Id ${recordId} отсутствуют показатели`,
    emptyFieldsError: (fields, recordId) => `Поля ${fields.map(f => `"${f}"`).join(', ')} не заполнены в записи с ID ${recordId}`,
    indicators: (indicators: string[], recordId) => `Показатели ${indicators.map(f => `"${f}"`).join(', ')} отсутствуют в записи с ID ${recordId}`,
    emptyIndicatorsProps: (props: Record<string, string[]>, recordId) => {
        const propsString = Object.keys(props).map(prop => !isEmptyArray(props[prop]) ? `${prop}: ${props[prop].map(p => `"${p}"`).join(', ')}` : '').join('; ')
        return `В записи с Id ${recordId} отсутствуют либо не заполнены следующие поля у показателей: ${propsString}`
    }
}

const errorHandlers = {
    queryParamsError: () => {
        throw new Error(messages.queryParamsNotFound)
    },
    fieldsError: (emptyFields, recordId) => {
        throw new Error(messages.emptyFieldsError(emptyFields, recordId))
    },
    socketError: () => {
        throw new Error(messages.socketNotFound)
    },
    indicatorsError: (recordId) =>{
        throw new Error(messages.emptyIndicators(recordId))
    },
    notFoundIndicators: (indicators: string[], recordId: number) => {
        throw new Error(messages.indicators(indicators, recordId))
    },
    notFilledIndicatorProps: (props: Record<string, string[]>) => {
        throw new Error(messages.emptyIndicatorsProps(props, config.journalRecordId))
    }
}

const getConfig = (type: DialogType, title: string, message) => {
    return {
        type,
        config: {
            title,
            message
        }
    }
}

const getSocketId = (queryParams: any) => {
    const socketId = Array.isArray(queryParams?.socketId) && queryParams?.socketId?.length ? queryParams?.socketId[0] : '';

    if (!queryParams) errorHandlers.queryParamsError()
    if (!socketId) errorHandlers.socketError()
  
    return socketId
}

const showErrorMessage = async (message: string, socketId) => getDataFromDialog(getConfig('confirm', 'Ошибка', message), socketId);
const showSuccessMessage = async (message: string, socketId) => getDataFromDialog(getConfig('confirm', 'Внимание', message), socketId);

const isEmptyArray = (arr: unknown[]) => {
    return Array.isArray(arr) && arr.length === 0
}

const hasIndicators = (journalRecordManager: IJournalRecordManager) => {
    const indicators = journalRecordManager?.data?.indicators
    return Array.isArray(indicators) && indicators.length > 0
}

const getNotFoundIndicators = (indicators: JournalRecordIndicatorResponse[], indicatorsList = config.indicatorsList) => {
    return indicatorsList.filter(ind => indicators.every(ljInd => ljInd?.indicator?.name?.toLowerCase() !== ind.toLocaleLowerCase()))
} 

const getNotFilledResultsFields = (indicators: JournalRecordIndicatorResponse[]): Record<string, string[]> => {
    return indicators.reduce((acc, indicator) => {
        const config = indicatorPropsConfig(indicator)
        return {
            ...acc,
            [indicator?.indicator?.name]: Object.keys(config).reduce((acc, prop) => {
                if (!config[prop].get()) return [...acc, config[prop].label]
                return acc
            }, [] as string[])
        }
    }, {}) as Record<string, string[]>
}

const hasNotFilledProps = (indicatorsProps: Record<string, string[]>) => {
    return Object.keys(indicatorsProps).some(indicator => !isEmptyArray(indicatorsProps[indicator]))
}

const hasNotFoundIndicators = (indicators: string[]) => !isEmptyArray(indicators)

async function main({ queryParams }) {
    if (!queryParams) errorHandlers.queryParamsError()
    const socketId = getSocketId(queryParams)

    try {
        const journalRecordManager = await JournalRecordManager(config.journalRecordId)

        if (!hasIndicators(journalRecordManager)) {
            errorHandlers.indicatorsError(journalRecordManager.journalRecordId)
        }

        const indicators = journalRecordManager?.data?.indicators

        const notFoundIndicators = getNotFoundIndicators(indicators)
        if (hasNotFoundIndicators(notFoundIndicators)) { 
            errorHandlers.notFoundIndicators(notFoundIndicators, journalRecordManager.journalRecordId)
        }

        const emptyIndicatorProps = getNotFilledResultsFields(indicators)
        if (hasNotFilledProps(emptyIndicatorProps)) {
            errorHandlers.notFilledIndicatorProps(emptyIndicatorProps)
        }

        showSuccessMessage(messages.success, socketId)
    } catch (err) {
        await showErrorMessage(err.message, socketId)
        return { error: err.message }
    }
}

module.exports = { main }

Проверка заполненности атрибутов записи ЛЖ. check-record-fields-filled

Проверяет заполненность заданных полей в записи журнала (например, "Источник", "Место отбора", "Дата регистрации" и др.). Если какое-либо из обязательных полей не заполнено, выдаётся соответствующая ошибка.

   Просмотр кода
   
import { JournalRecordManager } from "../../src/servivces/worker/api/interactors"
import { getDataFromDialog } from "../../src/gui/api"
import { DialogType } from "@triteia/types-integration-gui"
import { IJournalRecordManager } from "../../src/servivces/worker/api/interactors/JournalRecordManager/interface"

const config = {
    requiredFields: [
        'Источник',
        'Список. Целое число',
        'Строка',
        'Целое число',
        'Вещественное число',
        'Логический тип',
        'Дата',
        'Время',
    ],
    journalRecordId: 144,  // Мк / Тест_Ушакова
    integrationResult: { message: 'Все поля заполнены!' }
}

const messages = {
    socketNotFound: 'Отсутствует соединение с клиентом. Дальнейшее выполнение аддона невозможно',
    queryParamsNotFound: 'Отсутствуют необходимые параметры для выполнения аддона. Дальнейшее выполнение невозможно',
    success: 'Все необходимые поля заполнены!',
    emptyFieldsError: (fields, recordId) => `Поля ${fields.map(f => `"${f}"`).join(', ')} не заполнены в записи с ID ${recordId}`,
}

const errorHandlers = {
    queryParamsError: () => {
        throw new Error(messages.queryParamsNotFound)
    },
    fieldsError: (emptyFields, recordId) => {
        throw new Error(messages.emptyFieldsError(emptyFields, recordId))
    },
    socketError: () => {
        throw new Error(messages.socketNotFound)
    }
}

const getConfig = (type: DialogType, title: string, message) => {
    return {
        type,
        config: {
            title,
            message
        }
    }
}

const getSocketId = (queryParams: any) => {
    const socketId = Array.isArray(queryParams?.socketId) && queryParams?.socketId?.length ? queryParams?.socketId[0] : '';

    if (!queryParams) errorHandlers.queryParamsError()
    if (!socketId) errorHandlers.socketError()
  
    return socketId
}

const showErrorMessage = async (message: string, socketId) => getDataFromDialog(getConfig('confirm', 'Ошибка', message), socketId);
const showSuccessMessage = async (message: string, socketId) => getDataFromDialog(getConfig('confirm', 'Внимание', message), socketId);

const isEmptyArray = (arr: unknown[]) => {
    return arr.length === 0
}

const getNotFilledFields = (fields: string[], journalRecordsManager: IJournalRecordManager) => {
    console.log(journalRecordsManager.data.attributes, 'data.attributes')
    return fields.filter(f => !journalRecordsManager.getFieldValue(f))
}

async function main({ queryParams }) {
    if (!queryParams) errorHandlers.queryParamsError()
    const socketId = getSocketId(queryParams)

    try {
        const journalRecordManager = await JournalRecordManager(config.journalRecordId)
        const emptyFields = getNotFilledFields(config.requiredFields, journalRecordManager)

        if (isEmptyArray(emptyFields)) {
            showSuccessMessage(messages.success, socketId)
            return config.integrationResult
        } else errorHandlers.fieldsError(emptyFields, config.journalRecordId)
    } catch (err) {
        await showErrorMessage(err.message, socketId)
        return { error: err.message }
    }
}

module.exports = { main }

Проверка движения пробы. check-sample-moving

Проверяет маршрут движения пробы по этапам. Получает историю перемещений записи и определяет, происходило ли движение (нахождение более чем на одном этапе). Отображает маршрут или сообщает, что движение не происходило.

   Просмотр кода
   
import { getDataFromDialog } from "../../src/gui/api"
import { JournalsRecordRouteController } from "../../src/servivces/worker/api/controllers/journals-record-route"
import { apiInstance } from "../../src/servivces/worker/api/interactors/ApiInstance"
import type { DialogType } from "@triteia/types-integration-gui"
import type { JournalRecordRouteDto } from "../../src/servivces/worker/api/controllers/journal-records"

const config = {
    journalRecordId: 114 // Лаб. воздуха / Анализы завершены
}

const messages = {
    socketNotFound: 'Отсутствует соединение с клиентом. Дальнейшее выполнение аддона невозможно',
    queryParamsNotFound: 'Отсутствуют необходимые параметры для выполнения аддона. Дальнейшее выполнение невозможно',
    route: (routes: JournalRecordRouteDto[], recordId: number) => `Машрут пробы: ${routes.map(r => `"${r.stageName}"`).join(' -> ')}. Id записи ЛЖ: ${recordId}`, 
    notMoved: (recordId: number) => `Движение пробы не происходило. Id записи ЛЖ: ${recordId}`, 
}

const errorHandlers = {
    queryParamsError: () => {
        throw new Error(messages.queryParamsNotFound)
    },
    socketError: () => {
        throw new Error(messages.socketNotFound)
    }
}

const getConfig = (type: DialogType, title: string, message) => {
    return {
        type,
        config: {
            title,
            message
        }
    }
}

const getSocketId = (queryParams: any) => {
    const socketId = Array.isArray(queryParams?.socketId) && queryParams?.socketId?.length ? queryParams?.socketId[0] : '';

    if (!queryParams) errorHandlers.queryParamsError()
    if (!socketId) errorHandlers.socketError()
  
    return socketId
}

const showErrorMessage = async (message: string, socketId) => getDataFromDialog(getConfig('confirm', 'Ошибка', message), socketId);
const showSuccessMessage = async (message: string, socketId) => getDataFromDialog(getConfig('confirm', 'Внимание', message), socketId);

const isSampleMoved = (moves: JournalRecordRouteDto[]) => {
    return Array.isArray(moves) && moves.length > 1
}

async function main({ queryParams }) {
    if (!queryParams) errorHandlers.queryParamsError()
    const socketId = getSocketId(queryParams)

    try {
        const journalsRecordRouteController = new JournalsRecordRouteController(apiInstance)
        const sampleMoves = await journalsRecordRouteController.getJournalRecordRoute(config.journalRecordId)

        if (isSampleMoved(sampleMoves)) {
            showSuccessMessage(messages.route(sampleMoves, config.journalRecordId), socketId)
        } else {
            showSuccessMessage(messages.notMoved(config.journalRecordId), socketId)
        }
    } catch (err) {
        await showErrorMessage(err.message, socketId)
        return { error: err.message }
    }
}

module.exports = { main }

Проверка прав пользователя. check-user-rights

Проверяет права доступа пользователя к определённым ресурсам (объекты анализа, методики, записи ЛЖ). Отображает таблицу с типами доступа (чтение, запись и т.д.) и наличием прав по каждому ресурсу.

   Просмотр кода
   
import { getDataFromDialog } from "../../src/gui/api"
import { apiInstance } from "../../src/servivces/worker/api/interactors/ApiInstance"
import { 
    PermissionController, 
    PermissionResource, 
    PermissionRwAccess
} from "../../src/servivces/worker/api/controllers/permisson"

import { TableBuilder } from "../../src/gui/builder"
import type { DialogType, TableConfig } from "@triteia/types-integration-gui"
import type { JournalRecordRouteDto } from "../../src/servivces/worker/api/controllers/journal-records"

const accessNamesMap = {
    [PermissionRwAccess.EXEC]: 'Выполнение',
    [PermissionRwAccess.READ]: 'Чтение',
    [PermissionRwAccess.WRITE]: 'Запись',
}

const requiredResources = [
    PermissionResource.ANALYSIS_OBJECT, 
    PermissionResource.METHODOLOGY,
    PermissionResource.JOURNAL_RECORD
]

const resourcesNamesMap = {
    [PermissionResource.ANALYSIS_OBJECT]: 'Объекты анализа', 
    [PermissionResource.METHODOLOGY]: 'Методики', 
    [PermissionResource.JOURNAL_RECORD]: 'Записи ЛЖ'
}

const getAccessRightsTable = async (tableBuilder: TableBuilder, permissionController: PermissionController): Promise<TableConfig> => {
    const rows = (await Promise.all(requiredResources.map(async (source: PermissionResource) => {
            const sourceCombinations = await Promise.all(Object.keys(PermissionRwAccess).map(async (action) => {
                const access = await permissionController.getSourcePermission(source, PermissionRwAccess[action])
                return { source: resourcesNamesMap[source], action: accessNamesMap[PermissionRwAccess[action]], access: access.hasPermission }
            }))
            return sourceCombinations
        }   
    ))).flat()
    const table = tableBuilder
        .name('simpleTable')
        .label('Таблица')
        .isAddable(false)
        .actionsCol(false)
        .addColumn('Ресурс', 'source', false)
        .config('input', { name: 'source', rules: [{ required: true }] }, { placeholder: '', disabled: false })
        .next()
        .addColumn('Тип доступа', 'action', false)
        .config('input', { name: 'action' }, { type: 'string', placeholder: '', disabled: false })
        .next()
        .addColumn('Доступ', 'access', false)
        .config('checkbox', { name: 'access' }, { type: 'boolean', placeholder: '', disabled: false })
        .next()
        .setRows(rows)
        .build();
  return table
}

const messages = {
    socketNotFound: 'Отсутствует соединение с клиентом. Дальнейшее выполнение аддона невозможно',
    queryParamsNotFound: 'Отсутствуют необходимые параметры для выполнения аддона. Дальнейшее выполнение невозможно',
    route: (routes: JournalRecordRouteDto[], recordId: number) => `Маршрут пробы: ${routes.map(r => `"${r.stageName}"`).join(' -> ')}. Id записи ЛЖ: ${recordId}`, 
    notMoved: (recordId: number) => `Движение пробы не происходило. Id записи ЛЖ: ${recordId}`, 
}

const errorHandlers = {
    queryParamsError: () => {
        throw new Error(messages.queryParamsNotFound)
    },
    socketError: () => {
        throw new Error(messages.socketNotFound)
    }
}

const getConfig = (type: DialogType, title: string, message) => {
    return {
        type,
        config: {
            title,
            message
        }
    }
}

const getSocketId = (queryParams: any) => {
    const socketId = Array.isArray(queryParams?.socketId) && queryParams?.socketId?.length ? queryParams?.socketId[0] : '';
    if (!queryParams) errorHandlers.queryParamsError()
    if (!socketId) errorHandlers.socketError()
    return socketId
}

const showErrorMessage = async (message: string, socketId) => getDataFromDialog(getConfig('confirm', 'Ошибка', message), socketId);

const showTable = async (builder: TableBuilder, controller: PermissionController, socketId: string) => 
    await getDataFromDialog({ type: 'input-data', config: [await getAccessRightsTable(builder, controller)] }, socketId)


async function main({ queryParams }) {
    if (!queryParams) errorHandlers.queryParamsError()
    const socketId = getSocketId(queryParams)
    try {
        await showTable(new TableBuilder, new PermissionController(apiInstance), socketId)
    } catch (err) {
        await showErrorMessage(err.message, socketId)
        return { error: err.message }
    }
}

module.exports = { main }

Заполнение атрибутов записи ЛЖ. fill-record-fields

Автоматически заполняет заданные поля в записи журнала (например, даты, место отбора, шифр пробы и др.). Есть возможность использования ключевых слов для сопоставления полей, если точные названия не совпадают.

   Просмотр кода
   
import { JournalRecordManager } from "../../src/servivces/worker/api/interactors"
import { getDataFromDialog } from "../../src/gui/api"
import { DialogType } from "@triteia/types-integration-gui"
import { IJournalRecordManager } from "../../src/servivces/worker/api/interactors/JournalRecordManager/interface"
import { JournalRecordAttributeFieldResponse } from "../../src/servivces/worker/api/controllers/lj-eav-attribute-fields"
import { FieldMatch } from "../../src/servivces/worker/api/interactors/JournalRecordManager/interface"

const date = new Date().toISOString().split('T')[0]
const config = {
    requiredFields: [
        { name: 'Дата регистрации', value: date, keywords: ['дат', 'регистр'] },
        { name: 'Место отбора', value: 'Скважина 516563Г ', keywords: ['мест', 'отбор'] },
        { name: 'Дата отбора', value: date, keywords: ['дат', 'отбор'] },
        { name: 'Шифр пробы', value: 'shifr 123', keywords: ['дат', 'регистр']},
        { name: 'Список. Целое число', value: 666, keywords: ['спис', 'цел', 'числ'] },
        { name: 'Помещение', value: 'помещение', keywords: ['помещ']},
    ] as FieldMatch[],
    journalRecordId: 118, // Мк / 111
    integrationResult: { message: 'Все поля заполнены!' }
}

const messages = {
    socketNotFound: 'Отсутствует соединение с клиентом. Дальнейшее выполнение аддона невозможно',
    queryParamsNotFound: 'Отсутствуют необходимые параметры для выполнения аддона. Дальнейшее выполнение невозможно',
    success: (recordId) => `Все необходимые поля заполнены! Id записи: ${recordId}`,
    emptyFieldsError: (fields, recordId) => `Поля ${fields.map(f => `"${f}"`).join(', ')} не заполнены в записи с ID ${recordId}`,
}

const errorHandlers = {
    queryParamsError: () => {
        throw new Error(messages.queryParamsNotFound)
    },
    socketError: () => {
        throw new Error(messages.socketNotFound)
    }
}

const getConfig = (type: DialogType, title: string, message) => {
    return {
        type,
        config: {
            title,
            message
        }
    }
}

const getSocketId = (queryParams: any) => {
    const socketId = Array.isArray(queryParams?.socketId) && queryParams?.socketId?.length ? queryParams?.socketId[0] : '';
    if (!queryParams) errorHandlers.queryParamsError()
    if (!socketId) errorHandlers.socketError()
    return socketId
}

const showErrorMessage = async (message: string, socketId) => getDataFromDialog(getConfig('confirm', 'Ошибка', message), socketId);
const showSuccessMessage = async (message: string, socketId) => getDataFromDialog(getConfig('confirm', 'Внимание', message), socketId);

const fieldsMatcher = (field: JournalRecordAttributeFieldResponse, searchField: FieldMatch) => {
    return searchField.keywords.every(k => String(field.name).toLocaleLowerCase().includes(k.toLocaleLowerCase()))
}

const fillFields = async (fields: FieldMatch[], journalRecordsManager: IJournalRecordManager) => {
    await journalRecordsManager.setFieldsValues(fields, journalRecordsManager, fieldsMatcher)
}

async function main({ queryParams }) {
    if (!queryParams) errorHandlers.queryParamsError()
    const socketId = getSocketId(queryParams)

    try {
        const journalRecordManager = await JournalRecordManager(config.journalRecordId)
        await fillFields(config.requiredFields, journalRecordManager)
        showSuccessMessage(messages.success(journalRecordManager.journalRecordId), socketId)
        return config.integrationResult
    } catch (err) {
        await showErrorMessage(err.message, socketId)
        return { error: err.message }
    }
}

module.exports = { main }

Деление данных. copy-journal-record

Создаёт копию записи журнала на заданном этапе маршрута. Выводит сообщение с ID новой записи.