Слой информационных объектов

Пакет @morphcluster/carabi

Обзор

carabi — это клиентская библиотека для работы с информационными объектами (документами) в экосистеме CSP. Она предоставляет высокоуровневый API для взаимодействия с сервисами управления документами, а также вспомогательные утилиты для кэширования, работы со структурой и данными.

Библиотека построена поверх NATS-интеграции и использует ServiceNats для прозрачного вызова удалённых сервисов.


Клиенты

Клиенты наследуются от ServiceNats и предоставляют методы для вызова удалённых сервисов через NATS. Все методы принимают параметры, объект workspace (устаревший, всегда null) и логгер.

1. Documents

Назначение: Низкоуровневая работа с документами (чтение/запись значений, информация, проверки).

Методы:

Метод Параметры Описание
getInfo { documentId } Получить основную информацию (тип, статус, дата, создатель)
getDescr { documentId } Получить описание документа (по правилам именования)
getValues { dockind, documentId, propNames } Получить значения указанных свойств
setValues { dockind, documentId, values } Установить значения свойств
dublicate { dockind, documentId } Создать копию документа
insertRefs { dockind, documentId, propName, values } Добавить ссылки в множественное поле
deleteRefs { dockind, documentId, propName, values } Удалить ссылки
checkNull { dockind, documentId } Проверить обязательные поля
listIdByProps { dockind, values, count? } Найти ID документов по свойствам (AND)
listPropsByProps { dockind, props, filter?, count? } Выбрать документы с указанными полями
listByUniqueFields { dockind, values } Найти по уникальным полям
getUniqueCollisions { dockind, documentId } Найти конфликты уникальности

2. DocumentLists

Назначение: Расширенный поиск документов с фильтрацией по статусам.

Методы:

Метод Параметры Описание
listIdByProps { dockind, values, statuses?, notStatuses?, count? } Найти ID с фильтром по статусам
listPropsByProps { dockind, props, filter?, statuses?, notStatuses?, count? } Вывести поля с фильтрацией
listByUniqueFields { dockind, values } Поиск по уникальным полям
getUniqueCollisions { dockind, documentId } Проверить коллизии

3. DockindStructure

Назначение: Управление метаданными типа документа (статусы, свойства, функции, действия, права).

Методы:

Метод Параметры Описание
getInfo { docKind } Получить базовую информацию
setMain { oldDocKind, newDocKind, description, parentId } Обновить описание и родителя
getStatuses { docKind } Получить список статусов
setStatuses { docKind, deleteIds, statuses, newOrder } Обновить статусы
getProps { docKind } Получить свойства
setProps { docKind, props, deleteIds } Обновить свойства
getFunctions { docKind } Получить функции (DB/CSP)
setFunctions { docKind, funcs, deleteIds } Обновить функции
setActions { docKind, deleteIds, actions } Обновить действия
setNames { docKind, names } Обновить правила именования
setPermissions { docKind, roles, deleteRoleIds } Обновить права доступа
getIdByName { docKind } Получить ID по имени
getNameById { docKindId } Получить имя по ID
updateDockindNames {} Отложенное обновление всех имён

Событие: onChanged — генерируется при любом изменении структуры.


4. DockindImporter

Назначение: Импорт/экспорт метаданных в форматах XML и JSON.

Методы:

Метод Параметры Описание
importXml { root, vocabs, types } Импорт структуры из XML
exportXml { dockind } Экспорт структуры в XML

5. DocDataImporter

Назначение: Импорт/экспорт данных документов (содержимого).

Методы:

Метод Параметры Описание
importXml { XML } Импорт данных из XML
exportXml { columnsXML, filterXML } Экспорт данных в XML

Классы - Хелперы

DocumentsHelper

Назначение: Высокоуровневый фасад для работы с документами. Предоставляет объектно-ориентированный API, скрывая детали низкоуровневых вызовов.

Зависимости: QueriesHelper, DockindCache, Documents, DocumentLists.

Методы:

Метод Описание
createDocument(log, session, docKindName, trxId?) Создать новый документ. Возвращает Document.
loadDocument(log, session, docKindName, documentId, trxId?) Загрузить существующий документ. Возвращает Document.
loadDocList(log, session, docKindName, options) Загрузить список документов по фильтру. Возвращает массив Document.
getDocKindByDocumentId(log, documentId) Получить тип документа по ID документа.

Параметры options для loadDocList:

Пример:

const helper = new DocumentsHelper(host);
// ... зависимости подгружаются автоматически
const doc = await helper.createDocument(log, session, 'INVOICE');
await doc.setValues({ amount: 1000 }, true); // autocommit

DockindCache

Назначение: Кэширование типов документов (DocumentKind) с автоматической загрузкой и инвалидацией.

Особенности:

Внутренние PromiseSingleton:

Пример:

const cache = new DockindCache(host);
const dockind = await cache.get(log, 'INVOICE');
// dockind — это DocumentKind

DocumentKind

Назначение: Модель типа документа, загружаемая из БД. Содержит всю структуру: свойства, статусы, привязки.

Свойства:

Свойство Тип Описание
id number ID типа
name string Имя типа
description string Описание
tableName string Имя таблицы в БД
properties DocProperty[] Список свойств
propEvents DocEventProperty[] Привязки свойств к статусам (read/write/not null)
statuses Array<{id, name, descr}> Список статусов
loaded boolean Загружен ли объект

Методы:

Метод Описание
load(log) Загрузить структуру из БД
getTableName() Получить имя таблицы
getPropFieldName(prop) Получить имя поля для свойства
getUniqueProps() Получить уникальные свойства

DocProperty:


Document

Назначение: Обёртка над документом с кэшированием значений и отслеживанием изменений.

Конструктор:

new Document(log, session, docKind, { Documents, QueriesHelper, trxId })

Свойства:

Методы:

Метод Описание
getValues(propNames) Получить значения нескольких свойств (с кэшированием)
getValue(propName) Получить значение одного свойства
setValues(values, autocommit) Установить значения (с отслеживанием изменений)
commitValues() Сохранить накопленные изменения в БД
insertRefs(propName, values) Добавить ссылки (без кэширования)
setStatus(newStatusName) Сменить статус документа
loadFromJson(data) Загрузить документ из JSON (полученного из listPropsByProps)

Важно: setValues не вызывает commitValues автоматически, если autocommit = false. Это позволяет группировать изменения в рамках одной транзакции.


VocabsHelper

Назначение: Загрузка справочников по имени с кэшированием и защитой от конкурентных запросов.

Методы:

Метод Описание
getVocab(log, vocabName) Получить объект Vocab по имени (загружается асинхронно)

Пример:

const helper = new VocabsHelper(host);
const vocab = await helper.getVocab(log, 'CURRENCY');
// vocab.id — ID справочника

Vocab

Назначение: Модель справочника (пока только загружает ID по имени).

Свойства:


DocInstaller

Назначение: Автоматическая установка структуры и данных документов из файлов при старте приложения. Используется для развёртывания типов документов и миграций.

DocInstaller (главный)

Зависимости: DockindInstaller, DocDataInstaller.

Методы (запросы):

Метод Описание
getStatus() Получить статус установки
run() Запустить полную установку (типы + данные)
dockindsRun() Запустить только установку типов
docDataRun() Запустить только установку данных
docDataGetLast() Получить последнюю установленную версию данных

Конфигурация:


DockindInstaller

Назначение: Установка типов документов из XML-файлов.

Путь: ./dockinds/<категория>/

Структура каталога:

dockinds/
  └── my_category/
      ├── category.json          # Метаданные категории (опционально)
      ├── INVOICE_types.xml      # Структура типа INVOICE
      └── INVOICE_vocabs.xml     # Справочники для типа (опционально)

Формат category.json:

{
  "name": "Моя категория",
  "roles": ["ROLE_ADMIN"]
}

Логика:

  1. Сканирует подкаталоги в ./dockinds/.
  2. Для каждой категории загружает все пары *_types.xml и *_vocabs.xml.
  3. Вычисляет SHA-256 хеш содержимого.
  4. Сравнивает с хешем в таблице DOCKIND_VERSIONS.
  5. Если изменилось — вызывает DockindImporter.importXml.
  6. После успешной установки вызывает PKG_XML_REPL_CS.REVISION_STRUCTURE.

DocDataInstaller

Назначение: Установка данных документов из XML-файлов (миграции).

Путь: ./doc-data/<номер_версии>/*.xml

Логика:

  1. Проверяет наличие таблицы MIGRATIONS_DATA.
  2. Сканирует подкаталоги в ./doc-data/ с числовыми именами.
  3. Для каждой версии, которая ещё не установлена или была с ошибкой:
    • Выполняет все *.xml файлы через DocDataImporter.importXml.
    • В случае успеха записывает запись со статусом done.
    • В случае ошибки — запись со статусом error и текстом ошибки.
  4. Если миграция завершилась ошибкой, последующие не выполняются.

Метод resolveError: Позволяет вручную пометить ошибочную миграцию как выполненную (перезапуск с этой версии пропускается).

Хост PgDocuments

Обзор

Хост PgDocuments предоставляет набор сервисов для управления информационными объектами (документами) в системе MorphCluster. Основная функциональность включает:


Структура сервисов

Клиенты (ServiceNats)

Клиенты не описываются в данной документации, но они используются сервисами для межсервисного взаимодействия:


Основные сервисы

1. DockindStructure

Ответственность: Управление структурой типов документов (DocKind): статусы, свойства, функции, действия, права доступа, правила именования.

Зависимости: QueriesHelper, OraLongTransactions, SysProcesses

События:

Основные методы:

Метод Описание
getInfo({ docKind }) Получить базовую информацию о типе документа (ID, описание)
setMain({ oldDocKind, newDocKind, description, parentId }) Обновить основную информацию (только описание и родительскую папку)
getStatuses({ docKind, docKindId }) Получить список статусов (событий) типа документа
setStatuses({ docKind, deleteIds, statuses, newOrder }) Обновить статусы: удалить, изменить, добавить, переупорядочить
getProps({ docKind, docKindId }) Получить список свойств типа документа
setProps({ docKind, props, deleteIds }) Обновить свойства: удалить, изменить, добавить
setProperty({ docKindId, property }) Внутренний метод для сохранения одного свойства с его статусными масками и ссылками
getFunctions({ docKind, docKindId }) Получить функции, привязанные к типу документа
setFunctions({ docKind, funcs, deleteIds }) Обновить функции (DB или CSP) с их привязкой к статусам и свойствам
setActions({ docKind, deleteIds, actions }) Обновить действия (переходы между статусами)
setNames({ docKind, names }) Обновить правила именования документов
setPermissions({ docKind, roles, deleteRoleIds }) Установить права доступа для ролей (создание, видимость/редактирование статусов и свойств)
getIdByName({ docKind }) Получить ID типа документа по имени
getNameById({ docKindId }) Получить имя типа документа по ID
updateDockindNames({ dockindId }) Отложенное обновление описаний всех документов типа
createDbFunction({ schema, name }) Создать пустую PL/pgSQL-функцию, если она не существует

2. Documents

Ответственность: Низкоуровневая работа с документами — чтение/запись значений, информация о документе, проверка обязательных полей.

Зависимости: QueriesHelper, DockindCache

Основные методы:

Метод Описание
getInfo({ documentId }) Получить основную информацию о документе (тип, статус, дата, создатель)
getDescr({ documentId }) Получить описание документа (сгенерированное по правилам именования)
getValues({ dockind, documentId, propNames }) Получить значения указанных свойств документа (поддерживает простые и ссылочные поля)
setValues({ dockind, documentId, values }) Установить значения свойств документа в рамках транзакции
insertRefs({ dockind, documentId, propName, values }) Добавить ссылки на другие документы в множественное ссылочное поле
deleteRefs({ dockind, documentId, propName, values }) Удалить указанные ссылки из множественного ссылочного поля
checkNull({ dockind, documentId }) Проверить, заполнены ли обязательные для текущего статуса поля

3. DocumentLists

Ответственность: Поиск и выборка списков документов по значениям свойств.

Зависимости: QueriesHelper, DockindCache, Documents

Основные методы:

Метод Описание
listIdByProps({ dockind, values, statuses, notStatuses, count }) Найти ID документов по значениям свойств (AND-условия)
listPropsByProps({ dockind, props, filter, statuses, notStatuses, count }) Выбрать документы с указанными полями для вывода
listByUniqueFields({ dockind, values }) Найти документы по уникальным полям (автоматически определяются по конфигурации)
getUniqueCollisions({ dockind, documentId }) Найти документы с конфликтами по уникальным полям (исключая переданный ID)

4. DocumentFuncs

Ответственность: Выполнение бизнес-функций, привязанных к статусам и свойствам документов.

Зависимости: QueriesHelper, DockindCache, Documents, GlobalServices, Eventer

Основные методы:

Метод Описание
processStatus({ dockind, documentId, statusName, params, session, postprocess }) Выполнить все функции, привязанные к указанному статусу (pre- или post-process)
processProperty({ dockind, documentId, propName, session }) Выполнить функции, привязанные к изменению свойства
processAnykindFuncs({ dockind, documentId, params, session }) Выполнить глобальные (anykind) функции для документа
runFunc({ func, dockind, documentId, params, session, trxId }) Выполнить конкретную функцию (DB или CSP)

Поддерживаемые типы функций:


5. DocCardValues

Ответственность: Высокоуровневая работа со значениями документов в контексте карточки (UI-транзакции).

Зависимости: QueriesHelper, DockindCache, Documents, DocumentFuncs, DocumentLists

Основные методы:

Метод Описание
getValDisplay({ documentId, propName }) Получить отображаемое значение поля (например, имя справочника вместо ID)
getValues({ documentId, propName }) Получить массив значений простого поля
setValues({ cardId, documentId, propName, value/values }) Установить значения простого поля в рамках карточной транзакции
getRefs({ documentId, propName }) Получить список связанных документов для ссылочного поля
setRefs({ cardId, documentId, propName, refDocumentIds }) Заменить весь список связанных документов
clearRefs({ cardId, documentId, propName }) Очистить ссылочное поле
insertRefs({ cardId, documentId, propName, refDocumentIds }) Добавить ссылки в множественное поле
deleteRefs({ cardId, documentId, propName, refDocumentIds }) Удалить указанные ссылки
createRefDoc({ cardId, documentId, propName, parentId }) Создать новый документ, привязанный к ссылочному полю
deleteRefDocs({ cardId, documentId, propName, refDocumentIds }) Удалить связанные документы (полное удаление)
commit({ cardId }) Зафиксировать транзакцию карточки (проверка обязательных полей и уникальности)
rollback({ cardId }) Откатить транзакцию карточки

6. DocCardActions

Ответственность: Выполнение действий (переходов между статусами) с документами.

Зависимости: QueriesHelper, DockindCache, Documents, DocumentFuncs, DocCardValues, SysProcesses, DocumentLists

Основные методы:

Метод Описание
runActions({ dockind, documentIds, actionId, actParams, cardId, session }) Выполнить действие над одним или несколькими документами
runAction({ dockind, documentId, action, actParams, cardId, session }) Внутренний метод выполнения одного действия (проверка статуса, смена статуса, вызов функций)
runGlobalAction({ action, actParams, cardId, session }) Выполнить глобальное действие (без привязки к документу)
create({ dockind, parentId, classifPropId, classifId, session }) Создать новый документ с опциональным родителем и классификатором
deleteDocs({ dockind, documentIds, session }) Пометить документы как удалённые и запустить фоновую очистку
processDelete({ dockind, documentId, session }) Отложенная постобработка удаления (вызов функций статуса "deleted", физическое удаление)

Логика действия:

  1. Проверка допустимости текущего статуса (FROM_STATUS_IDS)
  2. (Опционально) Смена статуса на TO_STATUS_ID с вызовом pre-process функций
  3. (Опционально) Вызов функции, привязанной к действию
  4. Запуск post-process функций для нового статуса
  5. Запуск глобальных (anykind) функций

7. DocTables

Ответственность: Генерация и синхронизация структур таблиц документов в PostgreSQL для быстрого поиска и отчетов.

Зависимости: QueriesHelper, OraLongTransactions, DockindCache

Основные методы:

Метод Описание
recreate({ docKind }) Полностью пересоздать таблицу, представление и процедуру синхронизации для типа, затем синхронизировать все данные
recreateStruct({ docKind }) Пересоздать только структуру таблицы (без представления и данных)
recreateView({ docKind }) Пересоздать представление для типа документа (объединяет основную таблицу и словари)
recreateAll({}) Пересоздать структуры для всех типов документов (последовательно)
createSyncProcedure({ dockind }) Сгенерировать PL/pgSQL-процедуру синхронизации для типа
documentSync({ docKind, documentId }) Синхронизировать один документ с его таблицей
documentSyncKind({ docKind }) Синхронизировать все документы указанного типа (пакетная обработка)

Архитектура таблиц:


8. DockindImporter

Ответственность: Импорт метаданных из XML и JSON в базу данных.

Зависимости: DockindStructure, QueriesHelper, DocumentsHelper, OraLongTransactions

Основные методы:

Метод Описание
importXml({ root, vocabs, types }) Импорт структуры из XML (словари + типы документов)
importJson({ root, data }) Импорт структуры из JSON

Внутренние классы:

Поддерживаемые сущности при импорте (JSON):


9. DockindExporter

Ответственность: Экспорт метаданных типа документа в JSON.

Зависимости: DockindStructure, QueriesHelper, DocumentsHelper, OraLongTransactions

Основные методы:

Метод Описание
exportJson({ dockind }) Экспортировать полную структуру типа документа в JSON

Внутренний класс: JsonExporter

Экспортируемые данные:


10. DocDataImporter

Ответственность: Импорт данных документов из внешних источников (XML).

Зависимости: QueriesHelper, DocumentsHelper, DockindCache, Documents

Основные методы:

Метод Описание
importXml({ dataXml, uniqueProps }) Импортировать данные документов из XML

Логика импорта:

  1. Парсинг XML, извлечение структуры документов
  2. Для каждого документа:
    • Поиск существующего документа по уникальным полям (если указаны)
    • Если найден — применение правил слияния (добавление, перезапись, стирание)
    • Если не найден — создание нового документа
  3. Заполнение свойств документа (включая ссылки на подчинённые документы)
  4. Установка статуса

Правила слияния:


Вспомогательные модули

db-functions.mjs

Содержит определения SQL-функций для csp_documents (схема CSP-документов). Эти функции используются сервисами для работы с базой данных:

DocFunctionsInstaller

Наследуется от DbFunctionsInstaller и устанавливает функции из db-functions.mjs при старте сервиса.

Сервис DockindStructure

Сервис предназначен для управления структурой информационных объектов (DocKind) в системе. Он позволяет настраивать атрибуты типов документов: основные свойства, статусы, реквизиты, функции, действия, права доступа, а также переименовывать документы определённого типа.

Зависимости

События

Запросы

Все запросы выполняются через HTTP POST (если в схеме указано "http": "POST"), либо доступны только внутренне (если "http": null). Почти все запросы требуют авторизации ("anonymous": false), административные методы отмечены флагом "needAdmin": true.

getInfo

Получить идентификатор и описание типа документа по его системному имени.

Параметры запроса:

Поле Тип Обязательное Описание
docKind string да Системное имя типа документа

Ответ:

Поле Тип Описание
id number Идентификатор типа (DOCKIND_ID)
description string Человекочитаемое описание

Ошибки:


setMain

Обновить основные атрибуты типа документа: описание, родительскую папку. Переименование (изменение oldDocKind на newDocKind) запрещено.

Параметры запроса:

Поле Тип Обязательное Описание
oldDocKind string нет Текущее системное имя (должно совпадать с newDocKind, если указано)
newDocKind string да Новое системное имя (не может отличаться от oldDocKind)
description string нет Новое описание
parentId number нет ID родительской папки (категории)

Примечания:


getStatuses

Получить список всех статусов (событий) для заданного типа документа.

Параметры запроса:

Поле Тип Обязательное Описание
docKind string условно Системное имя типа. Используется, если не передан docKindId.
docKindId number условно ID типа. Если указан, docKind игнорируется.
session object нет Сессия пользователя (автоматически подставляется при HTTP-вызове).

Ответ: Массив объектов со следующими полями:

Поле Тип Описание
EVENT_ID number Уникальный идентификатор статуса
EVENT_NAME string Системное имя статуса
EVENT_DESCR string Отображаемое описание
COLOR_NAME string Название цвета (может быть null)
COLOR_CODE string Код цвета в формате Delphi (например, $00D6FED6)

setStatuses

Изменить набор статусов типа документа: удалить, обновить существующие, добавить новые, установить порядок. Операция обёрнута в транзакцию.

Параметры запроса:

Поле Тип Обязательное Описание
docKind string условно Системное имя типа (если не указан docKindId).
docKindId number условно ID типа.
deleteIds array of number нет Список ID статусов, которые необходимо удалить.
statuses array нет Массив статусов для добавления/обновления. Каждый объект содержит:
· EVENT_ID (number, <0 для новых),
· EVENT_NAME (string),
· EVENT_DESCR (string),
· COLOR_NAME (string),
· COLOR_CODE (string).
newOrder array of number нет Новый порядок ID статусов (включая только что созданные).
session object нет Сессия пользователя.
trxId string нет Идентификатор внешней транзакции (для встраивания в более крупные операции).

Требования: needAdmin: true.


getProps

Получить все реквизиты (свойства) типа документа.

Параметры запроса:

Поле Тип Обязательное Описание
docKind string условно Системное имя типа.
docKindId number условно ID типа.
session object нет Сессия пользователя.

Ответ: массив объектов реквизитов (структура зависит от БД).


setProps

Массовое изменение реквизитов типа документа: удаление, создание/обновление, установка порядка. Внутри транзакции последовательно обрабатываются все переданные свойства.

Параметры запроса:

Поле Тип Обязательное Описание
docKind string да Системное имя типа.
props array нет Массив объектов свойств для вставки/обновления. Каждый объект должен содержать поля согласно PKG_KIND_PROPERTIES_CS.UPDATE_PROPERTY (см. описание отдельных полей в setProperty). Если у свойства указаны Statuses, они также обновляются.
deleteIds array of number нет ID реквизитов, подлежащих удалению.
statuses (Не используется в текущей реализации, оставлен для совместимости)
session object нет Сессия.
trxId string нет Внешняя транзакция.

Детали полей объекта свойства (property):

Требования: needAdmin: true.


getFunctions

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

Параметры запроса:

Поле Тип Обязательное Описание
docKind string условно Системное имя типа.
docKindId number условно ID типа.
session object нет Сессия.
trxId string нет Транзакция.

Ответ: массив объектов функций. Каждый объект содержит:

Требования: needAdmin: true.


setFunctions

Обновить перечень функций типа документа. Предварительно для каждой функции вида schema.name создаётся заглушка в БД (если ещё не существует).

Параметры запроса:

Поле Тип Обязательное Описание
docKind string условно Системное имя типа.
docKindId number условно ID типа.
funcs array нет Массив объектов функций (формат определяется БД). Поле db_function обязательно должно иметь вид schema.function_name.
deleteIds array of number нет ID функций для удаления.
notValidateFuncs boolean нет Если true, пропустить проверку формата db_function.
session object нет Сессия.
trxId string нет Транзакция.

Требования: needAdmin: true.


setActions

Управление действиями (actions), доступными для типа документа. Поддерживает добавление, обновление, удаление и изменение порядка.

Параметры запроса:

Поле Тип Обязательное Описание
docKind string условно Системное имя типа.
docKindId number условно ID типа.
deleteIds array of number нет ID действий для удаления.
actions array нет Массив объектов действий. Каждый объект должен иметь поле changed (boolean). Если changed === true, объект будет передан в БД для вставки/обновления. Если false, используется только его id для сохранения порядка.
session object нет Сессия.
trxId string нет Транзакция.

Требования: needAdmin: true.


setNames

Запускает процесс обновления имён всех документов заданного типа (например, после изменения правил формирования наименования). Выполняется немедленное сохранение новых правил именования и создание фонового процесса через сервис SysProcesses.

Параметры запроса:

Поле Тип Обязательное Описание
docKind string условно Системное имя типа.
docKindId number условно ID типа.
names object да Новые правила формирования имён (структура определяется логикой БД).
session object нет Сессия.
trxId string нет Транзакция.

Требования: needAdmin: true.


updateDockindNames

Служебный метод, вызываемый фоновым процессом. Последовательно обновляет описания (DESCR) всех документов, принадлежащих указанному типу. Может выполняться долго, поэтому не должен вызываться напрямую из HTTP (хотя endpoint открыт).

Параметры запроса:

Поле Тип Обязательное Описание
dockindId number нет ID типа документа. Если не указан, будет ошибка.

Требования: needAdmin: true.


setPermissions

Управление правами ролей на тип документа: создание, доступ к статусам и реквизитам.

Параметры запроса:

Поле Тип Обязательное Описание
docKind string условно Системное имя типа.
docKindId number условно ID типа.
roles array нет Массив объектов прав ролей. Каждый объект: id (роль), creation (0/1), statuses (структура прав на статусы), properties (права на реквизиты).
deleteRoleIds array of number нет ID ролей, для которых нужно удалить все права на данный тип.
session object нет Сессия.
trxId string нет Транзакция.

Требования: needAdmin: true.


getIdByName

Получить числовой идентификатор типа документа по его системному имени.

Параметры запроса:

Поле Тип Обязательное Описание
docKind string да Системное имя типа.

Ответ: число (RESULT) — идентификатор.


getNameById

Получить системное имя типа документа по его ID.

Параметры запроса:

Поле Тип Обязательное Описание
docKindId number да ID типа.

Ответ: строка — системное имя.

Сервис LegacyXml2Select

LegacyXml2Select – это сервис, который предоставляет возможность парсить XML-запросы, сформированные в стиле «формальных выборок», и генерировать соответствующие SQL SELECT-запросы к документам в БД. Основное назначение – обеспечить обратную совместимость со старыми механизмами поиска.

Сервис состоит из нескольких компонентов:

Все компоненты располагаются в одном модуле и экспортируются как единое целое.

Сервис LegacyXml2Select

Назначение: Принимает XML‑строку, параметры режима запроса и прав доступа, преобразует её в объект SqlQuery (или сразу в SQL‑строку) и возвращает результат.

Зависимости

Методы (запросы)

parseToObj({ session, xml, queryMode=0, permissions=1 })

Преобразует XML в объект SqlQuery (без построения финального SQL‑текста).

Параметры:

Возвращает: экземпляр SqlQuery.

parseToSql({ session, xml, queryMode=0, permissions=1 })

Выполняет parseToObj, а затем вызывает sql.build(), возвращая готовый SQL‑запрос.

Параметры: те же, что у parseToObj.

Возвращает: строку SQL.

macroParse({ macro })

Парсит строку‑макрос в абстрактное синтаксическое дерево.

Параметры:

Возвращает: объект с полем tree – AST макроса (например, { type: 'function', value: 'NOW', args: [] }).

Формат XML‑запроса для LegacyXml2Select

Сервис LegacyXml2Select преобразует XML‑описание выборки документов в SQL‑запрос SELECT.
Корневой элемент — <query>, внутри которого обязательно присутствует элемент <formal>, задающий условия фильтрации.


1. Корневая структура

<?xml version="1.0"?>
<query>
  <formal dockind_id="ID_ВИДА_ДОКУМЕНТА" [name="and|or"]>
     <!-- набор условий -->
  </formal>
</query>

Атрибуты <formal>:

Атрибут Обязательный Тип Описание
dockind_id да integer Идентификатор вида документа (dockind_id) целевой таблицы
name нет and/or Логическая операция, объединяющая все условия верхнего уровня (по умолчанию and)

2. Элементы внутри <formal> и <reference>

Допускаются следующие элементы (в любом порядке и в любых сочетаниях):

Элемент Назначение
<reference> Ссылка на другой документ / тип документа (JOIN / EXISTS)
<property> Условие на значение свойства документа
<status> Фильтр по статусу (виду события) документа
<operation> Логическая группа условий (AND / OR)
<select> (Зарезервирован; влияет на логику outer join, но вывод не меняет)

Все они могут вкладываться внутрь <reference> и <operation>.


3. Элемент <reference>

Описывает переход к связанному документу через свойство‑ссылку. Реализуется либо как EXISTS/NOT EXISTS, либо как JOIN (в зависимости от атрибута referencing и режима запроса).

<reference
  docprop_id="ID_СВОЙСТВА_ССЫЛКИ"
  referencing="join|is null"
  dockind_id="ID_ЦЕЛЕВОГО_ВИДА"
  [condition="l|nl|g|ng|e|ne"]
  [count="целое_число"]
  [valuevar="строка"]
  [leftp="строка"]
  [rightp="строка"]
>
  <!-- вложенные reference, property, status, operation -->
</reference>
Атрибут Обязат. Тип Значения / Описание
docprop_id да integer Идентификатор свойства‑ссылки (из model_documents.doc_kind_properties)
referencing да строка join – обычная связь, проверяется существование связанного документа;
is null – анти‑связь, условие NOT EXISTS (связанного документа нет)
dockind_id да integer Идентификатор вида документа, на который ссылаемся
condition нет l,nl,g,ng,e,ne Условие сравнения количества связанных документов (используется вместе с count; реализовано частично – вызывает ошибку)
count нет integer Ожидаемое количество документов для сравнения (см. condition)
valuevar нет строка Зарезервировано; в текущей реализации не используется
leftp нет строка Зарезервировано; не используется
rightp нет строка Зарезервировано; не используется

Логика работы:


4. Элемент <property>

Задаёт фильтр по значению конкретного свойства документа (или по служебному идентификатору).

<property
  docprop_id="ID_СВОЙСТВА"
  condition="код_операции"
  [doc_prop_value="значение"]
  [valuevar="макрос"]
  [value="значение"]
  [type="s|t|n|d|v"]
  [kindtype="число"]
/>
Атрибут Обязат. Тип Описание / Возможные значения
docprop_id да integer Идентификатор свойства документа. Особые значения:
-2 – ID документа (прямая выборка по document_id);
-4 – дата события (event_date);
-5, -6 – пользователь, породивший событие (event_user);
-7 – описание документа (doc_descr). Остальные числа – обычные свойства из doc_kind_properties
condition да строка Код операции сравнения (см. таблицу ниже)
doc_prop_value нет* строка Непосредственное значение для сравнения. Допускается использование макросов (см. раздел 6). *Обязательно, если только не используется IS NULL/IS NOT NULL.
valuevar нет строка Ссылка на переменную или макрос; если задана и condition != 'DIRECT', подменяет собой doc_prop_value.
value нет строка Альтернативное значение (например, для работы со словарями; приоритет ниже doc_prop_value).
type нет символ Тип свойства (берётся из БД, если не указан):
s – строка, t – текст, n – число, d – дата, v – ссылка на словарь и т.п.
kindtype нет integer Подтип свойства (берётся из БД). Влияет на построение условия (например, 4 – иерархический словарь, 10 – мультизначное свойство).

Коды операций (condition) и их SQL‑эквиваленты:

Код SQL оператор Примечание
e = или IN IN используется для свойств типа v, t и kindtype=4 (словарь)
ne <> или NOT IN аналогично
l <
nl >=
g >
ng <=
like LIKE
not like NOT LIKE
in IN Только для строковых типов (s, t), если kindtype != 4
d DIRECT Специальный режим: прямое присоединение таблицы свойств без EXISTS (используется для docprop_id=-2)
is null IS NULL
is not null IS NOT NULL
min MIN (зарезервировано, используется в агрегациях)
max MAX (зарезервировано)

Особые docprop_id:


5. Элемент <status>

Фильтрация по статусу (виду события) документа.

<status doceventkind_id="ID_СОБЫТИЯ" />

Может встречаться многократно. Каждый экземпляр задаёт одно значение doceventkind_id.
В SQL формируется условие:
dt_{level}.doceventkind_id IN (0, список_ID_событий)

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


6. Элемент <operation>

Группирует несколько условий с заданной логической связкой.

<operation name="and|or">
   <!-- reference, property, status, другие operation -->
</operation>

7. Элемент <select> (зарезервирован)

Присутствует в коде, но не влияет на итоговый SQL. Его наличие/отсутствие используется только во внутренней логике определения, нужно ли создавать OUTER JOIN.
Пример:

<select />

В текущей реализации его содержимое игнорируется.


8. Подстановка макросов в значениях

В атрибутах doc_prop_value, valuevar, value (а также @_valuevar у <reference>) могут использоваться макросы.
Поддерживаются следующие макросы (регистр важен):

Макрос Подстановка
@USERID ID текущего пользователя (documents.get_user_id)
@USERNAME Полное имя пользователя (Фамилия Имя Отчество)
@ROLEID ID текущей роли пользователя (documents.get_role_id)
@ROLENAME Название роли
@DEPARTID Идентификатор подразделения пользователя
@DATE Текущая дата/время (SYSDATE); может комбинироваться с функциями: @DATE+1, @DATE-7 и т.п.
GET_USER_FILIALS Вызов функции GET_USER_FILIALS (и другие подобные)
NOW, TODAY, WORKDAY, MONTHDAY, *YEAR* Вызов соответствующей функции БД, возвращающей дату

Макросы распознаются по точному совпадению (@USERID) или по вхождению в строку (например, TO_DATE('@DATE','DD.MM.YYYY') приводит к подстановке SYSDATE).

Если значение начинается с буквы и содержит скобки (например, my_func(1,2)), то оно рассматривается как вызов функции БД и выполняется через Xml2SelectDb.execFunc или execDate.


9. Примеры

Простейший запрос (получить все документы вида 10)

<query>
  <formal dockind_id="10" />
</query>

Фильтр по свойствам и статусу

<query>
  <formal dockind_id="10" name="and">
    <property docprop_id="100" condition="e" doc_prop_value="Иванов"/>
    <property docprop_id="101" condition="g" doc_prop_value="1000"/>
    <status doceventkind_id="3"/>
    <status doceventkind_id="5"/>
  </formal>
</query>

Ссылка на связанный документ

<query>
  <formal dockind_id="10">
    <reference docprop_id="200" referencing="join" dockind_id="20">
      <property docprop_id="201" condition="like" doc_prop_value="%утверждён%"/>
    </reference>
  </formal>
</query>

Анти‑ссылка (NOT EXISTS)

<reference docprop_id="200" referencing="is null" dockind_id="20"/>

Использование макроса

<property docprop_id="102" condition="e" doc_prop_value="@USERID"/>

Группировка условий с OR

<operation name="or">
  <property docprop_id="100" condition="e" doc_prop_value="A"/>
  <property docprop_id="100" condition="e" doc_prop_value="B"/>
</operation>

Выборка по списку ID

<property docprop_id="-2" condition="d" doc_prop_value="101,205,330"/>

или через функцию:

<property docprop_id="-2" condition="d" valuevar="my_package.get_docs(55)"/>

Сервисы CarabiQuery и DoclistStructure

Общие сведения

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

Для запросов, требующих авторизации, в объекте запроса обязательно наличие поля session с корректной сессией пользователя (содержит userId).


Сервис CarabiQuery

1. getDoclistDataSql

Назначение: получить SQL-запрос для выборки данных доклиста без его выполнения.
Права: требует needAdmin: true.

Параметры запроса:

Поле Тип Обязательное Описание
docListId number да Идентификатор доклиста
statusList string нет Список ID статусов через запятую (например "1,2,3")
filter string нет Текстовый фильтр (поиск по контексту или номеру документа)
filterCols string нет JSON-фильтр по колонкам (см. формат в FiltersBuilder)
xmlFilter string нет Дополнительный XML-фильтр, подменяющий XML_SEARCH доклиста
orderBy string нет Имя колонки и направление сортировки (напр. "EVENT_DATE DESC")
resTreeValue string нет Код классификатора для фильтрации по дереву ресурсов

Формат ответа:

{
  "SQL": "<сгенерированный SQL-запрос>"
}

2. fetchDoclistData

Назначение: получить страницу данных доклиста.
Права: доступно авторизованным пользователям.

Параметры: те же, что у getDoclistDataSql, плюс параметры пагинации:

Поле Тип По умолчанию Описание
count number 10 Количество записей на страницу
offset number 0 Смещение (начиная с 0)

Ответ:
Массив объектов, соответствующих строкам доклиста. Поля каждой строки включают:

Пример:

[
  {
    "document_id": 12345,
    "doc_status_descr": "Утверждён",
    "event_date": "15.01.2025 10:30:00",
    "doc_status_owner": "Иванов Иван Иванович",
    "doc_status_modifier": "Петров Пётр Петрович",
    "doc_descr": "Договор №123 от 10.01.2025",
    "doc_status_id": 2,
    "doc_status_name": "APPROVED",
    "doc_status_owner_id": 101,
    "pr_special": null,
    "attach_count": 3,
    "child_count": 0,
    "files": 2,
    "pr_number": "123",
    "pr_date": "10.01.2025",
    ...
  }
]

3. getDoclistDataCnt

Назначение: получить общее количество записей в доклисте с учётом фильтров.
Права: авторизованные пользователи.

Параметры: совпадают с getDoclistDataSql (без пагинации).
Ответ: число (integer) – количество документов.

4. fetchDoclistDataRow

Назначение: получить одну строку доклиста по идентификатору документа.
Права: авторизованные пользователи.

Параметры:

Поле Тип Обязательное Описание
docListId number да ID доклиста
documentId number да ID конкретного документа

Ответ:
Объект с данными строки (такой же, как в массиве fetchDoclistData) или null, если документ не найден.

5. fetchReflistData

Назначение: получить данные ссылочного поля (референс-листа) для конкретного документа.
Права: авторизованные пользователи.

Параметры:

Поле Тип Обязательное Описание
docKind string да Системное имя типа документа, из которого просматривается ссылка
documentId number да ID текущего документа
docPropId number да ID свойства-ссылки (идентификатор свойства в модели)
parentId number нет ID родительского документа для иерархических ссылок (если дерево)
statusId string нет Фильтр по статусам целевых документов (через запятую)
filter string нет Текстовый фильтр
filterCols string нет JSON-фильтр по колонкам
orderBy string нет Сортировка
count number нет (10) Размер страницы
offset number нет (0) Смещение

Ответ: массив объектов с данными целевых документов (структура аналогична fetchDoclistData).

6. getReflistDataCnt

Назначение: получить количество документов в ссылочном списке.
Права: авторизованные пользователи.
Параметры: аналогичны fetchReflistData, но без count/offset.
Ответ: число.

7. fetchReflistDataRow

Назначение: получить одну строку из ссылочного списка (целевой документ) по его ID.
Права: авторизованные пользователи.
Параметры:

Поле Тип Обязательное Описание
documentId number да ID целевого документа

Ответ: объект строки или null.

8. fetchReflistOptions

Назначение: получить список возможных документов для назначения в ссылку (диалог выбора).
Права: авторизованные пользователи.

Параметры:

Поле Тип Обязательное Описание
docKind string да Системное имя типа документа-источника
documentId number нет ID текущего документа (для подстановки переменных в XML-фильтр)
docPropId number да ID свойства-ссылки
dockindIdProp number да ID типа документа, доступного для выбора
filter object нет Расширенные фильтры. Состав: xml (XML-фильтр), statusIds, context, columns, classifId
orderBy string нет Сортировка
count number нет (10) Размер страницы
offset number нет (0) Смещение

Ответ: массив объектов доступных документов.

9. fetchDockindData

Назначение: получить список документов заданного типа (без привязки к конкретному свойству-ссылке).
Права: авторизованные пользователи.

Параметры:

Поле Тип Обязательное Описание
docKind string да Системное имя типа документа
statusList string нет Список ID статусов через запятую
xmlFilter string нет XML-фильтр
filter string нет Текстовый фильтр
filterCols string нет JSON-фильтр по колонкам
orderBy string нет Сортировка
count number нет (10) Размер страницы
offset number нет (0) Смещение

Ответ: массив объектов документов (формат аналогичен fetchDoclistData).

10. getSqlFromXml

Назначение: отладочный метод для получения сгенерированного SQL из произвольного XML.
Права: needAdmin: true.

Параметры:

Поле Тип Обязательное Описание
xml string да XML-строка с блоком <query><formal ...>

Ответ: объект с единственным полем SQL (строка).


Сервис DoclistStructure

1. getDoclistColumns

Назначение: получить полную структуру колонок доклиста с учётом пользовательских настроек (ширина, видимость, порядок).
Права: авторизованные пользователи.

Параметры:

Поле Тип Обязательное Описание
doclistId number да ID доклиста

Ответ: массив объектов, каждый из которых описывает одну колонку:

Поле Тип Описание
SHOW_ORDER number Порядковый номер для отображения
DOCPROP_ID number ID свойства модели (для системных колонок < 0)
DOCPROP_NAME string Человекочитаемое название
PROP_SYS_NAME string Системное имя колонки (напр. DOCUMENT_ID, PR_DATE, DOC_STATUS_DESCR)
DOCPROP_KIND number Тип свойства
DOCPROP_OBJECT string Код типа данных ('1' – целое, '4' – строка, '32' – дата и т.д.)
MULTI number Признак множественного значения
SYS_COLUMN number Флаг системной колонки
WIDTH number Ширина в пикселях (пользовательская или по умолчанию)
VISIBLE number Флаг видимости (1 – показывать, 0 – скрыта)
ORDERBY string null
DOCLIST_ID number null
IS_FIXED, IS_GROUP и др. number Флаги расширенных настроек колонки

2. getReflistStructure

Назначение: получить полную информацию для отображения ссылочного списка, включая колонки, статусы и доступные XML-фильтры.
Права: авторизованные пользователи.

Параметры:

Поле Тип Обязательное Описание
docpropId number да ID свойства-ссылки
dockindId number нет Явное указание типа документов (обычно определяется автоматически)

Ответ: объект с полями:

3. getReflistColumns

Назначение: получить колонки для референс-листа (аналогично getDoclistColumns, но без привязки к конкретному доклисту).
Права: авторизованные пользователи.

Параметры:

Поле Тип Обязательное Описание
docpropId number нет ID свойства-ссылки
dockindId number нет ID типа документов

Ответ: массив колонок (та же структура, что и в getDoclistColumns).

4. getReflistOptionsColumns

Назначение: получить колонки для диалога выбора документа в ссылку (обычно те же, что и в рефлисте, но могут отличаться правами).
Права: авторизованные пользователи.

Параметры:

Поле Тип Обязательное Описание
docpropId number да ID свойства-ссылки
propDockindId number да ID типа документов для выбора

Ответ: массив колонок.


Примечания по фильтрации

Текстовый фильтр (filter)

JSON-фильтр по колонкам (filterCols)

Ожидается строка в формате JSON с массивом условий:

{
  "filter": [
    {
      "field_name": "PR_NUMBER",
      "value": "123",
      "operator": "="
    }
  ]
}

XML-фильтр (xmlFilter, xmlSearch)

Формат соответствует внутреннему представлению условий в подсистеме LegacyXml2Select.
Пример:

<query>
  <formal dockind_id="123" namevar="MYDOCTYPE" haschild="0" docrefs="1">
    <property docprop_id="100" condition="e" doc_prop_value="Hello"/>
    <reference docprop_id="200" condition="e" referencing="join">
      <status doceventkind_id="1"/>
    </reference>
  </formal>
</query>

Для деталей синтаксиса обратитесь к документации по LegacyXml2Select.


Аутентификация и сессия

Все запросы (кроме getDoclistDataSql и getSqlFromXml, требующих needAdmin) доступны обычным авторизованным пользователям.
Объект запроса должен содержать поле session с пользовательской сессией:

{
  "session": {
    "userId": 123,
    ...
  },
  "docListId": 42,
  ...
}

При использовании HTTP-транспорта сессия обычно передаётся через механизмы платформы Morphcluster (куки, заголовки) – в документации по ядру уточните способ передачи.

Планировщик задач DocScheduler (CRON_TABLE)

Планировщик DocScheduler предназначен для периодического запуска задач (CSP‑сервисов или DB‑функций) по расписанию, задаваемому с помощью SQL‑выражений. Управление задачами осуществляется через документы типа CRON_TABLE.

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


Документ CRON_TABLE: поля и их назначение

Для создания задачи необходимо добавить документ с dockind = "CRON_TABLE" и статусом "CRON_TABLE_ACTIVE".
Поддерживаются следующие свойства:

Поле Тип Описание
NUM число/строка Идентификатор (номер) задачи.
DESCR строка Описание задачи (назначение).
SYS_PROCESS_ID число ID запущенного системного процесса (заполняется автоматически).
DB_FUNCTION строка Имя DB‑функции для вызова (если не используется CSP).
CSP_SERVICE строка Имя CSP‑сервиса для вызова.
CSP_SERVICE_PARAMS строка (JSON) Параметры вызова CSP‑сервиса в формате JSON.
INTERVAL строка SQL‑выражение, вычисляющее следующую дату/время запуска (см. ниже).
INTERVAL_ERROR строка SQL‑выражение для следующего запуска после ошибки (если не задано, используется INTERVAL).
MAX_COUNT_ERROR число Максимальное количество последовательных ошибок, после которого задача переводится в статус CRON_TABLE_ERROR.
COUNT_ERROR число Текущий счётчик последовательных ошибок (заполняется автоматически).
FIRST_RUN datetime Первый запланированный запуск (опционально, используется для проверки).
LAST_RUN datetime Время последнего запуска (заполняется автоматически).
NEXT_RUN datetime Следующее время запуска (рассчитывается автоматически).
DAILY_START_TIME datetime Время фактического начала выполнения задачи (заполняется автоматически).
DAILY_END_TIME datetime Время окончания выполнения задачи (заполняется автоматически).
ERROR_TEXT строка Текст последней ошибки (заполняется автоматически).
PERIODICAL_RUN не используется (зарезервировано)
DEL_ON_FINISH не используется (зарезервировано)

Важно: Для запуска задачи необходимо указать либо CSP_SERVICE (с возможными CSP_SERVICE_PARAMS), либо DB_FUNCTION.


Принцип работы планировщика

1. Загрузка задач

При старте и далее каждые 10 минут или при изменениях в CRON_TABLE (таймер reloadTimer) планировщик перечитывает все активные документы CRON_TABLE_ACTIVE.
Также перезагрузка происходит при любом изменении статуса системного процесса (через триггер trgProcessChanged) — например, после завершения задачи.

2. Цикл проверки расписания

Каждые 30 секунд (таймер checkTimer) планировщик:

3. Обработка задачи (_processTask)

Для каждой активной задачи выполняется логика:

Если NEXT_RUN в будущем → пропустить
Иначе если SYS_PROCESS_ID отсутствует → запустить задачу (_runTask)
Иначе если процесс с таким ID не найден в sysprocs → запустить задачу заново
Иначе если процесс завершён с ошибкой → вызвать _finishTask с текстом ошибки
Иначе если процесс завершён успешно → вызвать _finishTask без ошибки
Иначе процесс ещё выполняется → ничего не делать

4. Запуск задачи (_runTask)

Если на этапе запуска возникает исключение, вызывается _finishTask с текстом ошибки.

5. Завершение задачи / расчёт следующего запуска (_finishTask)

Шаги:

  1. Определение интервала

    • Если есть ошибка → используется INTERVAL_ERROR (или INTERVAL, если INTERVAL_ERROR не задан).
    • Если ошибки нет → используется INTERVAL.
  2. Обновление счётчика ошибок

    • При ошибке: COUNT_ERROR увеличивается на 1.
    • При успехе: COUNT_ERROR сбрасывается в 0.
  3. Проверка лимита ошибок

    • Если COUNT_ERROR > MAX_COUNT_ERROR → задача переводится в статус CRON_TABLE_ERROR и больше не запускается.
  4. Расчёт следующего времени запуска

    • Выполняется SQL‑запрос: SELECT (<INTERVAL_выражение>) as RESULT.
    • Результат преобразуется в dayjs‑объект.
    • Если выражение пустое, результат невалиден или запрос не удался → задача переводится в статус CRON_TABLE_PASSIVE (отключена).
    • Иначе NEXT_RUN устанавливается на вычисленную дату/время.
  5. Обновление документа

    • Сбрасывается SYS_PROCESS_ID, проставляется DAILY_END_TIME, ERROR_TEXT, новый NEXT_RUN и COUNT_ERROR.
    • При необходимости изменяется статус документа (на CRON_TABLE_ERROR или CRON_TABLE_PASSIVE).
    • Выполняется перезагрузка списков задач и процессов.

Настройка расписания (INTERVAL и INTERVAL_ERROR)

Планировщик не использует классические cron‑выражения. Вместо этого для вычисления следующей даты запуска применяются произвольные SQL‑выражения, возвращающие timestamp.

Формат

Выражение должно быть валидным SQL‑выражением для СУБД, на которой работает MorphCluster. Рекомендуется использовать NOW() как точку отсчёта.

Примеры

Цель SQL‑выражение для INTERVAL
Каждые 5 минут NOW() + INTERVAL '5 minutes'
Каждый час NOW() + INTERVAL '1 hour'
Ежедневно в 03:00 DATE_TRUNC('day', NOW()) + INTERVAL '1 day' + INTERVAL '3 hours'
Каждый понедельник в 09:00 NEXT_DAY(NOW(), 'MONDAY') + INTERVAL '9 hours' (зависит от диалекта SQL)
Через 1 день после успешного выполнения NOW() + INTERVAL '1 day'

Особенность при пустом INTERVAL

Если INTERVALINTERVAL_ERROR) не заданы, то:

Рекомендация: всегда задавайте явное INTERVAL или переводите задачу в неактивный статус вручную после разового выполнения.


Обработка ошибок и отказоустойчивость


Жизненный цикл задачи (на примере)

  1. Создание
    Добавляется документ CRON_TABLE со статусом ACTIVE, заполняются поля CSP_SERVICE/DB_FUNCTION, INTERVAL, MAX_COUNT_ERROR (опционально).

  2. Первый запуск

    • Если NEXT_RUN не задан или NEXT_RUN <= текущего времени → планировщик запускает задачу.
    • SYS_PROCESS_ID получает ID нового системного процесса.
    • DAILY_START_TIME фиксирует момент старта.
  3. Выполнение
    Планировщик не вмешивается в ход работы процесса. Процесс выполняется асинхронно.

  4. Завершение процесса

    • Системный процесс переходит в статус completed или failed.
    • Триггер trgProcessChanged немедленно вызывает перезагрузку планировщика.
    • Планировщик обрабатывает завершённую задачу через _finishTask:
      • Рассчитывается NEXT_RUN (с учётом ошибки, если была).
      • Обновляются COUNT_ERROR, DAILY_END_TIME, ERROR_TEXT.
      • Сбрасывается SYS_PROCESS_ID.
      • При необходимости меняется статус документа.
  5. Повторный запуск
    Когда текущее время достигнет нового NEXT_RUN, планировщик снова запустит задачу.

  6. Отключение задачи

    • Автоматически: при превышении MAX_COUNT_ERROR или невалидном INTERVAL.
    • Вручную: изменить статус документа на любой, кроме CRON_TABLE_ACTIVE.

Особенности и ограничения

1. Механизм блокировки повторной перезагрузки

2. Сессия выполнения

3. Поведение при NEXT_RUN = NULL

Как уже отмечено, это приводит к немедленному повторному запуску после завершения. Если вам нужно однократное выполнение, после успеха следует вручную перевести задачу в статус CRON_TABLE_PASSIVE или CRON_TABLE_ERROR (например, через отдельный процесс).

4. Типы вызываемых функций


Рекомендации по настройке

  1. Всегда задавайте INTERVAL даже для периодических задач. Для разовых задач используйте ручное отключение или запланируйте удаление документа после выполнения.
  2. Указывайте MAX_COUNT_ERROR – разумное значение (например, 3–5) для защиты от «зависших» ошибочных задач.
  3. Используйте INTERVAL_ERROR, если после сбоя нужно повторить попытку быстрее, чем обычно.
  4. Проверяйте SQL‑выражения в консоли базы данных перед внесением в INTERVAL.
  5. Избегайте слишком частых запусков менее 30 секунд

Пример документа CRON_TABLE

{
  "dockind": "CRON_TABLE",
  "status": "CRON_TABLE_ACTIVE",
  "props": {
    "NUM": 101,
    "DESCR": "Ежечасная архивация логов",
    "DB_FUNCTION": "archive_logs",
    "INTERVAL": "NOW() + INTERVAL '1 hour'",
    "INTERVAL_ERROR": "NOW() + INTERVAL '5 minutes'",
    "MAX_COUNT_ERROR": 3,
    "FIRST_RUN": "2025-01-01T00:00:00"
  }
}

Этот документ заставит планировщик вызывать DB‑функцию archive_logs каждый час. При возникновении ошибки следующая попытка будет через 5 минут. После трёх последовательных ошибок задача перейдёт в статус CRON_TABLE_ERROR.


Заключение

Планировщик DocScheduler предоставляет гибкий механизм запуска задач по расписанию на основе SQL‑выражений. Настройка через документы CRON_TABLE позволяет динамически добавлять, изменять и отключать задачи без перезапуска сервиса. Важно правильно заполнять поля INTERVAL и контролировать обработку ошибок через MAX_COUNT_ERROR и INTERVAL_ERROR.