Слой информационных объектов
- Пакет @morphcluster/carabi
- Хост PgDocuments
- Сервис DockindStructure
- Сервис LegacyXml2Select
- Сервисы CarabiQuery и DoclistStructure
- Планировщик задач DocScheduler (CRON_TABLE)
Пакет @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:
-
props: string[]— имена свойств для вывода -
filter: object— фильтр по значениям -
statuses: string[]— ограничение по статусам -
notStatuses: string[]— исключение статусов -
count: number— максимальное количество (по умолчанию 100000) -
trxId: number— идентификатор транзакции (опционально)
Пример:
const helper = new DocumentsHelper(host);
// ... зависимости подгружаются автоматически
const doc = await helper.createDocument(log, session, 'INVOICE');
await doc.setValues({ amount: 1000 }, true); // autocommit
DockindCache
Назначение: Кэширование типов документов (DocumentKind) с автоматической загрузкой и инвалидацией.
Особенности:
- Использует
MemoryCacheAsyncс TTL 10 часов, максимум 100 типов. - Предоставляет методы
getById(log, docKindId)иget(log, docKindName). - Автоматически инвалидируется при изменении структуры через событие
onChanged. Для принудительной очистки вызовитеclearCache().
Внутренние PromiseSingleton:
-
vocabNames— список справочников -
dockindNames— список типов документов
Пример:
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:
-
id,name,descr— идентификатор, имя, описание -
propKind— тип свойства (1 — строка, 9 — ссылка, 10 — справочник и т.д.) -
formatBase— базовый тип (text, numeric, timestamp, ref, int8) -
formatLogic— логический тип (text, numeric, date, ref, vocab) -
multi— множественное -
unique— уникальное -
refDocKinds— для ссылок: список допустимых типов -
fieldName— имя поля для синхронизации таблиц
Document
Назначение: Обёртка над документом с кэшированием значений и отслеживанием изменений.
Конструктор:
new Document(log, session, docKind, { Documents, QueriesHelper, trxId })
Свойства:
-
id— ID документа -
docKind— объектDocumentKind -
valuesCache— кэш значений свойств -
valuesChanged— Set имён изменённых свойств
Методы:
| Метод | Описание |
|---|---|
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 по имени).
Свойства:
-
id— ID справочника -
name— имя -
loaded— флаг загрузки
DocInstaller
Назначение: Автоматическая установка структуры и данных документов из файлов при старте приложения. Используется для развёртывания типов документов и миграций.
DocInstaller (главный)
Зависимости: DockindInstaller, DocDataInstaller.
Методы (запросы):
| Метод | Описание |
|---|---|
getStatus() |
Получить статус установки |
run() |
Запустить полную установку (типы + данные) |
dockindsRun() |
Запустить только установку типов |
docDataRun() |
Запустить только установку данных |
docDataGetLast() |
Получить последнюю установленную версию данных |
Конфигурация:
-
skipInstall: true— пропустить автоматическую установку при старте.
DockindInstaller
Назначение: Установка типов документов из XML-файлов.
Путь: ./dockinds/<категория>/
Структура каталога:
dockinds/
└── my_category/
├── category.json # Метаданные категории (опционально)
├── INVOICE_types.xml # Структура типа INVOICE
└── INVOICE_vocabs.xml # Справочники для типа (опционально)
Формат category.json:
{
"name": "Моя категория",
"roles": ["ROLE_ADMIN"]
}
Логика:
- Сканирует подкаталоги в
./dockinds/. - Для каждой категории загружает все пары
*_types.xmlи*_vocabs.xml. - Вычисляет SHA-256 хеш содержимого.
- Сравнивает с хешем в таблице
DOCKIND_VERSIONS. - Если изменилось — вызывает
DockindImporter.importXml. - После успешной установки вызывает
PKG_XML_REPL_CS.REVISION_STRUCTURE.
DocDataInstaller
Назначение: Установка данных документов из XML-файлов (миграции).
Путь: ./doc-data/<номер_версии>/*.xml
Логика:
- Проверяет наличие таблицы
MIGRATIONS_DATA. - Сканирует подкаталоги в
./doc-data/с числовыми именами. - Для каждой версии, которая ещё не установлена или была с ошибкой:
- Выполняет все
*.xmlфайлы черезDocDataImporter.importXml. - В случае успеха записывает запись со статусом
done. - В случае ошибки — запись со статусом
errorи текстом ошибки.
- Выполняет все
- Если миграция завершилась ошибкой, последующие не выполняются.
Метод resolveError: Позволяет вручную пометить ошибочную миграцию как выполненную (перезапуск с этой версии пропускается).
Хост PgDocuments
Обзор
Хост PgDocuments предоставляет набор сервисов для управления информационными объектами (документами) в системе MorphCluster. Основная функциональность включает:
- Управление структурой типов документов (DocKind) — свойства, статусы, действия, права доступа
- Работа с документами — создание, чтение, обновление, удаление
- Импорт/экспорт метаданных и данных в XML/JSON
- Генерация и синхронизация таблиц документов в PostgreSQL
- Выполнение бизнес-логики через функции и действия
Структура сервисов
Клиенты (ServiceNats)
Клиенты не описываются в данной документации, но они используются сервисами для межсервисного взаимодействия:
- Eventer — отправка событий, управление пользовательскими соединениями
- SysProcesses — управление фоновыми бизнес-процессами
Основные сервисы
1. DockindStructure
Ответственность: Управление структурой типов документов (DocKind): статусы, свойства, функции, действия, права доступа, правила именования.
Зависимости: QueriesHelper, OraLongTransactions, SysProcesses
События:
-
onChanged— генерируется при любом изменении структуры типа документа
Основные методы:
| Метод | Описание |
|---|---|
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) |
Поддерживаемые типы функций:
-
DB — вызов хранимой процедуры PostgreSQL (формат
schema.function) -
CSP — вызов метода удалённого сервиса (формат
ServiceName.method)
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", физическое удаление) |
Логика действия:
- Проверка допустимости текущего статуса (
FROM_STATUS_IDS) - (Опционально) Смена статуса на
TO_STATUS_IDс вызовом pre-process функций - (Опционально) Вызов функции, привязанной к действию
- Запуск post-process функций для нового статуса
- Запуск глобальных (anykind) функций
7. DocTables
Ответственность: Генерация и синхронизация структур таблиц документов в PostgreSQL для быстрого поиска и отчетов.
Зависимости: QueriesHelper, OraLongTransactions, DockindCache
Основные методы:
| Метод | Описание |
|---|---|
recreate({ docKind }) |
Полностью пересоздать таблицу, представление и процедуру синхронизации для типа, затем синхронизировать все данные |
recreateStruct({ docKind }) |
Пересоздать только структуру таблицы (без представления и данных) |
recreateView({ docKind }) |
Пересоздать представление для типа документа (объединяет основную таблицу и словари) |
recreateAll({}) |
Пересоздать структуры для всех типов документов (последовательно) |
createSyncProcedure({ dockind }) |
Сгенерировать PL/pgSQL-процедуру синхронизации для типа |
documentSync({ docKind, documentId }) |
Синхронизировать один документ с его таблицей |
documentSyncKind({ docKind }) |
Синхронизировать все документы указанного типа (пакетная обработка) |
Архитектура таблиц:
- Основная таблица:
doc_tables.<dockind>_t— содержит single-свойства - Дочерние таблицы:
doc_tables.<dockind>_t_<prop>— для multi-свойств - Представление:
doc_tables.<dockind>_v— объединяет данные для удобного чтения
8. DockindImporter
Ответственность: Импорт метаданных из XML и JSON в базу данных.
Зависимости: DockindStructure, QueriesHelper, DocumentsHelper, OraLongTransactions
Основные методы:
| Метод | Описание |
|---|---|
importXml({ root, vocabs, types }) |
Импорт структуры из XML (словари + типы документов) |
importJson({ root, data }) |
Импорт структуры из JSON |
Внутренние классы:
- XmlImporter — парсинг XML, создание/обновление словарей, типов, статусов, свойств, действий, имён, функций
- JsonImporter — аналогичный функционал для JSON (более современный формат)
Поддерживаемые сущности при импорте (JSON):
- Словари (
vocabs) - Типы документов (
name,descr) - Статусы (
statusesс цветами, функциями, правами) - Свойства (
propsс типом, мульти, уникальностью, статусными масками, ссылками, правами, функциями) - Правила именования (
names) - Действия (
actionsс условиями, переходами, правами, функциями) - Права доступа (
permissionsна уровне ролей)
9. DockindExporter
Ответственность: Экспорт метаданных типа документа в JSON.
Зависимости: DockindStructure, QueriesHelper, DocumentsHelper, OraLongTransactions
Основные методы:
| Метод | Описание |
|---|---|
exportJson({ dockind }) |
Экспортировать полную структуру типа документа в JSON |
Внутренний класс: JsonExporter
Экспортируемые данные:
- Основная информация (
name,descr) - Используемые словари (
vocabsсо значениями) - Статусы (
statusesс цветами, правами, функциями) - Свойства (
propsс типами, параметрами, статусными масками, ссылками, правами, функциями) - Правила именования (
names) - Действия (
actionsс условиями, переходами, правами, функциями)
10. DocDataImporter
Ответственность: Импорт данных документов из внешних источников (XML).
Зависимости: QueriesHelper, DocumentsHelper, DockindCache, Documents
Основные методы:
| Метод | Описание |
|---|---|
importXml({ dataXml, uniqueProps }) |
Импортировать данные документов из XML |
Логика импорта:
- Парсинг XML, извлечение структуры документов
- Для каждого документа:
- Поиск существующего документа по уникальным полям (если указаны)
- Если найден — применение правил слияния (добавление, перезапись, стирание)
- Если не найден — создание нового документа
- Заполнение свойств документа (включая ссылки на подчинённые документы)
- Установка статуса
Правила слияния:
-
0— значение не меняется -
2— добавление новых значений в множество -
3— перезапись значения -
4— стирание значения
Вспомогательные модули
db-functions.mjs
Содержит определения SQL-функций для csp_documents (схема CSP-документов). Эти функции используются сервисами для работы с базой данных:
-
get_all_dockinds— получить все типы документов -
get_document_info— получить информацию о документе -
get_dockind_id_by_name/get_dockind_name_by_id— преобразование ID/имени -
get_dockind_props— свойства типа документа -
get_dockind_prop_events— статусные маски свойств -
get_document_values/get_document_refs— чтение значений и ссылок - и другие
DocFunctionsInstaller
Наследуется от DbFunctionsInstaller и устанавливает функции из db-functions.mjs при старте сервиса.
Сервис DockindStructure
Сервис предназначен для управления структурой информационных объектов (DocKind) в системе. Он позволяет настраивать атрибуты типов документов: основные свойства, статусы, реквизиты, функции, действия, права доступа, а также переименовывать документы определённого типа.
Зависимости
-
QueriesHelper— выполнение SQL-запросов и вызов хранимых процедур. -
OraLongTransactions— управление длительными транзакциями. -
SysProcesses— запуск фоновых процессов бизнес-логики (используется для отложенного обновления имён документов).
События
-
onChanged— генерируется при любом изменении структуры информационного объекта. Полезно для сброса кэшей или оповещения других компонентов системы.
Запросы
Все запросы выполняются через HTTP POST (если в схеме указано "http": "POST"), либо доступны только внутренне (если "http": null). Почти все запросы требуют авторизации ("anonymous": false), административные методы отмечены флагом "needAdmin": true.
getInfo
Получить идентификатор и описание типа документа по его системному имени.
Параметры запроса:
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
docKind |
string | да | Системное имя типа документа |
Ответ:
| Поле | Тип | Описание |
|---|---|---|
id |
number | Идентификатор типа (DOCKIND_ID) |
description |
string | Человекочитаемое описание |
Ошибки:
-
ComplexError("Не найден тип документа ...")— если указанный тип не существует.
setMain
Обновить основные атрибуты типа документа: описание, родительскую папку. Переименование (изменение oldDocKind на newDocKind) запрещено.
Параметры запроса:
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
oldDocKind |
string | нет | Текущее системное имя (должно совпадать с newDocKind, если указано) |
newDocKind |
string | да | Новое системное имя (не может отличаться от oldDocKind) |
description |
string | нет | Новое описание |
parentId |
number | нет | ID родительской папки (категории) |
Примечания:
- Требует прав администратора (
needAdmin: true). - Выполняется в рамках сессии (
sessionпередаётся из контекста).
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):
-
DOCPROP_KIND— тип реквизита (number). -
DOCPROP_ID— ID реквизита (number, для существующих). -
DOCPROP_FPATH,DOCPROP_PRESENTATION,DOCPROP_SQL,DOCPROP_OBJECT,DOCPROP_DESCR,DOCPROP_NAME,DOCPROP_SCRIPT,DEFAULT_VALUE,DOCPROP_PRESENTATION_OPTIONS— строковые атрибуты (CLOB). -
DOCPROP_UNIQUE,DOCPROP_MULTI— булевы флаги (передаются как 1/0). -
DOCPROP_RULE_CHILD,DOCPROP_RULE_PARENT,DOCPROP_REPEAT,DOCPROP_TREE_KIND,DOCPROP_RULE,DOCPROP_VALID,DOC_FORMAT— числовые поля. -
RefLinks— опциональный массив объектов{ DocKindId, XmlFilter }, перед отправкой сериализуется в JSON. -
Statuses— массив объектов вида{ eventId, required, visible, writable }для настройки доступности реквизита в разных статусах.
Требования: needAdmin: true.
getFunctions
Получить список функций (триггеров/обработчиков), привязанных к типу документа.
Параметры запроса:
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
docKind |
string | условно | Системное имя типа. |
docKindId |
number | условно | ID типа. |
session |
object | нет | Сессия. |
trxId |
string | нет | Транзакция. |
Ответ: массив объектов функций. Каждый объект содержит:
-
DOCEVENTKIND_IDS,DOCPROP_IDS,DK_ACTION_IDS— массивы чисел, полученные парсингом строк с разделителем,. - Прочие поля, возвращаемые БД.
Требования: 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 – фасад, предоставляющий внешние методы.
- LegacyXml2SelectDb – сервис‑помощник для доступа к базе данных (получение метаданных, выполнение функций).
- LegacyXml2SelectInnerPg – ядро парсинга XML и построения SQL.
- PropertyBuilder – построитель условий для свойств документов.
- MacroParser – парсер макросов (функции, литералы).
- SqlQuery / WhereCondition – утилиты для программного конструирования SQL-выражений и оптимизации WHERE-условий.
Все компоненты располагаются в одном модуле и экспортируются как единое целое.
Сервис LegacyXml2Select
Назначение: Принимает XML‑строку, параметры режима запроса и прав доступа, преобразует её в объект SqlQuery (или сразу в SQL‑строку) и возвращает результат.
Зависимости
-
QueriesHelper– обязательный (указан вrequirements), предоставляет доступ к выполнению запросов к PostgreSQL. -
LegacyXml2SelectDb– обязательный (добавляется как вложенный сервис в конструкторе).
Методы (запросы)
parseToObj({ session, xml, queryMode=0, permissions=1 })
Преобразует XML в объект SqlQuery (без построения финального SQL‑текста).
Параметры:
-
session(объект, опционально) – должен содержатьuserId, используется для фильтрации прав. -
xml(string) – XML‑строка запроса. -
queryMode(number, по умолчанию0) – режим запроса:-
0– полный запрос (выбирает поля документа), -
1– подсчёт количества (COUNT), -
2– только идентификаторы документов, -
3‑6– специальные режимы (логика меняется).
-
-
permissions(number, по умолчанию1) – уровень проверки прав доступа (-1– без проверки,1– стандартная).
Возвращает: экземпляр SqlQuery.
parseToSql({ session, xml, queryMode=0, permissions=1 })
Выполняет parseToObj, а затем вызывает sql.build(), возвращая готовый SQL‑запрос.
Параметры: те же, что у parseToObj.
Возвращает: строку SQL.
macroParse({ macro })
Парсит строку‑макрос в абстрактное синтаксическое дерево.
Параметры:
-
macro(string) – строка, содержащая вызов функции, литерал или идентификатор.
Возвращает: объект с полем 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 |
нет | строка | Зарезервировано; не используется |
Логика работы:
- Если внутри
<reference>нет ни вложенных<reference>,<property>,<status>,<operation>, ни<select>, и режим запроса = 4–6, то такой элемент приreferencing="join"или внешнем соединении превращается в условие1=1. - В остальных случаях для
<reference>генерируется подзапросEXISTS(илиNOT EXISTSприreferencing="is null"), в котором проверяется наличие связанных документов и дополнительно накладываются вложенные условия (свойства, статусы, другие ссылки). - При
referencing="join"и режимах 4–6 (специальные режимы отчётов) возможен сценарий сOUTER JOIN, но детали определяются вложенными условиями.
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:
-
-2(DIRECT): фильтр по идентификаторам документов.-
doc_prop_value– список ID через запятую, например"10,20,30". -
valuevar– имя функции, возвращающей массив ID (вызывается черезXml2SelectDb.execFunc).
-
-
-4: фильтр по дате события (event_date). Дляcondition='<=...'значение автоматически корректируется на конец дня. -
-5,-6: фильтр по пользователю события (event_user). -
-7: фильтр по текстовому описанию (doc_descr). Для операторовLIKE/NOT LIKE– сравнение без учёта регистра.
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>
-
name="and"– все вложенные условия объединяются черезAND. -
name="or"– черезOR. - Атрибут
nameможно опустить; тогда элемент становится прозрачным контейнером (вложенные условия просто передаются на уровень выше без добавления собственной группы).
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-запросов к базе данных документов, получения структурированных списков (доклистов, ссылочных полей), а также вспомогательной информации о колонках и фильтрах.
- CarabiQuery – основной сервис для выборки данных из доклистов, референсных списков и справочников типов документов.
- DoclistStructure – вспомогательный сервис для получения метаданных колонок и структуры доклистов/рефлистов.
Для запросов, требующих авторизации, в объекте запроса обязательно наличие поля 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– идентификатор документа -
doc_status_descr– описание статуса -
event_date– дата события (строка в форматеDD.MM.YYYY HH24:MI:SS) -
doc_status_owner– ФИО создателя -
doc_status_modifier– ФИО изменившего -
doc_descr– полное наименование документа -
doc_status_id,doc_status_name– системные поля статуса -
doc_status_owner_id– ID создателя -
pr_special– служебное поле -
attach_count,child_count,files– счётчики вложений и дочерних документов -
PR_<имя_свойства>– динамические колонки, соответствующие свойствам документа (имена начинаются сPR_)
Пример:
[
{
"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 | нет | Явное указание типа документов (обычно определяется автоматически) |
Ответ: объект с полями:
-
columns– массив колонок целевого типа документов (формат как вgetDoclistColumns) -
info– объект с базовой информацией о типе (поляDOCKIND_ID,DOCKIND_NAME, …) -
statusColors– массив объектов статусов с цветовой индикацией -
xmlFilters– массив предустановленных XML-фильтров для выбора
3. getReflistColumns
Назначение: получить колонки для референс-листа (аналогично getDoclistColumns, но без привязки к конкретному доклисту).
Права: авторизованные пользователи.
Параметры:
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
docpropId |
number | нет | ID свойства-ссылки |
dockindId |
number | нет | ID типа документов |
Ответ: массив колонок (та же структура, что и в getDoclistColumns).
4. getReflistOptionsColumns
Назначение: получить колонки для диалога выбора документа в ссылку (обычно те же, что и в рефлисте, но могут отличаться правами).
Права: авторизованные пользователи.
Параметры:
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
docpropId |
number | да | ID свойства-ссылки |
propDockindId |
number | да | ID типа документов для выбора |
Ответ: массив колонок.
Примечания по фильтрации
Текстовый фильтр (filter)
- Если переданная строка состоит только из цифр и длиннее 4 символов, сервис сначала пытается найти документ по
DOCUMENT_IDв указанном типе. - Если документ не найден или фильтр не числовой, выполняется поиск подстроки без учёта регистра в поле
doc_descr(черезLIKE '%...%').
JSON-фильтр по колонкам (filterCols)
Ожидается строка в формате JSON с массивом условий:
{
"filter": [
{
"field_name": "PR_NUMBER",
"value": "123",
"operator": "="
}
]
}
-
field_name– системное имя колонки (например,DOCUMENT_ID,EVENT_DATE,PR_*). -
value– значение для сравнения. -
operator– оператор (=,!=,<,>,LIKE, и т.д.). Если не указан, для строковых полей применяетсяLIKE, для числовых –=, для дат –>=или<=.
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) планировщик:
- Собирает задачи, у которых
NEXT_RUN <= текущего временииSYS_PROCESS_IDотсутствует (т.е. процесс не запущен). - Запускает полную перезагрузку задач и их обработку, при наличии собранных задач
3. Обработка задачи (_processTask)
Для каждой активной задачи выполняется логика:
Если NEXT_RUN в будущем → пропустить
Иначе если SYS_PROCESS_ID отсутствует → запустить задачу (_runTask)
Иначе если процесс с таким ID не найден в sysprocs → запустить задачу заново
Иначе если процесс завершён с ошибкой → вызвать _finishTask с текстом ошибки
Иначе если процесс завершён успешно → вызвать _finishTask без ошибки
Иначе процесс ещё выполняется → ничего не делать
4. Запуск задачи (_runTask)
- Создаётся новый системный процесс:
- тип
csp– для вызова CSP‑сервиса (параметры берутся изCSP_SERVICE_PARAMS); - тип
db– для вызова DB‑функции.
- тип
- В документе CRON_TABLE проставляется
SYS_PROCESS_IDи текущее время вDAILY_START_TIME. - После этого планировщик перезагружает списки задач и процессов.
Если на этапе запуска возникает исключение, вызывается _finishTask с текстом ошибки.
5. Завершение задачи / расчёт следующего запуска (_finishTask)
Шаги:
-
Определение интервала
- Если есть ошибка → используется
INTERVAL_ERROR(илиINTERVAL, еслиINTERVAL_ERRORне задан). - Если ошибки нет → используется
INTERVAL.
- Если есть ошибка → используется
-
Обновление счётчика ошибок
- При ошибке:
COUNT_ERRORувеличивается на 1. - При успехе:
COUNT_ERRORсбрасывается в 0.
- При ошибке:
-
Проверка лимита ошибок
- Если
COUNT_ERROR > MAX_COUNT_ERROR→ задача переводится в статусCRON_TABLE_ERRORи больше не запускается.
- Если
-
Расчёт следующего времени запуска
- Выполняется SQL‑запрос:
SELECT (<INTERVAL_выражение>) as RESULT. - Результат преобразуется в
dayjs‑объект. - Если выражение пустое, результат невалиден или запрос не удался → задача переводится в статус
CRON_TABLE_PASSIVE(отключена). - Иначе
NEXT_RUNустанавливается на вычисленную дату/время.
- Выполняется SQL‑запрос:
-
Обновление документа
- Сбрасывается
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
Если INTERVAL (и INTERVAL_ERROR) не заданы, то:
- После успешного выполнения задачи
NEXT_RUNостанетсяNULL. - При следующем цикле проверки планировщик будет считать, что
NEXT_RUNуже наступил (условиеtask.NEXT_RUN && task.NEXT_RUN.isAfter(...)не сработает, т.к.NEXT_RUN—null). - В результате задача будет запускаться повторно сразу после предыдущего завершения (зацикливание).
Рекомендация: всегда задавайте явное INTERVAL или переводите задачу в неактивный статус вручную после разового выполнения.
Обработка ошибок и отказоустойчивость
-
Счётчик ошибок (
COUNT_ERROR) увеличивается при любом сбое:- Ошибка запуска задачи (исключение в
_runTask). - Завершение системного процесса со статусом
failed.
- Ошибка запуска задачи (исключение в
-
Раздельный интервал после ошибки позволяет задать более частое повторение (например,
NOW() + INTERVAL '5 minutes') или более длительную паузу. -
Лимит ошибок (
MAX_COUNT_ERROR): по достижении лимита задача автоматически деактивируется (статусCRON_TABLE_ERROR). Это предотвращает бесконечные попытки заведомо ошибочной задачи. -
Невалидное расписание (ошибка вычисления
NEXT_RUNили пустойINTERVAL) переводит задачу в статусCRON_TABLE_PASSIVE— она исключается из обработки до ручного вмешательства.
Жизненный цикл задачи (на примере)
-
Создание
Добавляется документCRON_TABLEсо статусомACTIVE, заполняются поляCSP_SERVICE/DB_FUNCTION,INTERVAL,MAX_COUNT_ERROR(опционально). -
Первый запуск
- Если
NEXT_RUNне задан илиNEXT_RUN <= текущего времени→ планировщик запускает задачу. -
SYS_PROCESS_IDполучает ID нового системного процесса. -
DAILY_START_TIMEфиксирует момент старта.
- Если
-
Выполнение
Планировщик не вмешивается в ход работы процесса. Процесс выполняется асинхронно. -
Завершение процесса
- Системный процесс переходит в статус
completedилиfailed. - Триггер
trgProcessChangedнемедленно вызывает перезагрузку планировщика. - Планировщик обрабатывает завершённую задачу через
_finishTask:- Рассчитывается
NEXT_RUN(с учётом ошибки, если была). - Обновляются
COUNT_ERROR,DAILY_END_TIME,ERROR_TEXT. - Сбрасывается
SYS_PROCESS_ID. - При необходимости меняется статус документа.
- Рассчитывается
- Системный процесс переходит в статус
-
Повторный запуск
Когда текущее время достигнет новогоNEXT_RUN, планировщик снова запустит задачу. -
Отключение задачи
- Автоматически: при превышении
MAX_COUNT_ERRORили невалидномINTERVAL. - Вручную: изменить статус документа на любой, кроме
CRON_TABLE_ACTIVE.
- Автоматически: при превышении
Особенности и ограничения
1. Механизм блокировки повторной перезагрузки
- Используется флаг
reloadingи отложенный вызовneedReloadдля предотвращения одновременной перезагрузки из разных таймеров/триггеров.
2. Сессия выполнения
- Задачи запускаются от имени пользователя
userId = 5056с правами администратора (isAdmin: true). - Это зашито в коде и не настраивается через CRON_TABLE.
3. Поведение при NEXT_RUN = NULL
Как уже отмечено, это приводит к немедленному повторному запуску после завершения. Если вам нужно однократное выполнение, после успеха следует вручную перевести задачу в статус CRON_TABLE_PASSIVE или CRON_TABLE_ERROR (например, через отдельный процесс).
4. Типы вызываемых функций
-
CSP‑сервис – должен быть зарегистрирован в системе. Параметры передаются через
CSP_SERVICE_PARAMSв виде JSON-строки. - DB‑функция – хранимая функция в базе данных. Вызов происходит без параметров (но можно передать через глобальные переменные сессии или отдельный механизм).
Рекомендации по настройке
-
Всегда задавайте
INTERVALдаже для периодических задач. Для разовых задач используйте ручное отключение или запланируйте удаление документа после выполнения. -
Указывайте
MAX_COUNT_ERROR– разумное значение (например, 3–5) для защиты от «зависших» ошибочных задач. -
Используйте
INTERVAL_ERROR, если после сбоя нужно повторить попытку быстрее, чем обычно. -
Проверяйте SQL‑выражения в консоли базы данных перед внесением в
INTERVAL. - Избегайте слишком частых запусков менее 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.