Класс/коллекция (class)

Описание

Метаданные пользовательского класса.
Позволяет определить структуру для данных и правила ее обслуживания. Для каждого класса в REST-API появляется endpoint /rest/v1/model/CLASSPATH и возможность производить операции через WebSocket-API с capability=rest.

Может размещать данные в памяти, в распределенной объектной БД, в реляционной БД postgres (с партициями для исторических данных и без), в брокере Kafka, а также сохранять данные в аналитической колоночной БД Clickhouse.

Каждая коллекция публикует изменения, доставляемые подписчикам (подписки через websocket-API, авторизуемые на основании ролей).

Поддерживает несколько режимов работы: скоростное чтение, скоростное уведомление, асинхронный режим, синхронный режим.
Каждый из них обеспечивает внутреннюю целостность, не допуская изменения исходной последовательсности запросов при их обработке и рассылке уведомлений. Исключение составляет обработка различных сущностей в режимах, использующих параллельную обработку. +

Поддерживает наследование свойств.
Поддерживает ограничение доступа к данным для различных пользователей к методам и коллекциям по ролям (role.routes и iam_all.json), а также на основе сложных фильтров к конкретным данным на чтение, изменение, видимость полей и возможность их изменения (class.opts.security_filter_read, class.opts.security_filter_write, class.properties..security_filter_read, class.properties..security_filter_write).
Классы в распределенной объектной БД доступна возможность автоудаления по времени жизни с автоматическим продлением при сохранении; при этом ограничено максимально возможное количество записей в коллекции в связи с тем, что для применения фильтра к выборке производится поэлементный перебор всей коллекции.

Ограничения

  • Коллекция недоступна в мастер-домене.

Поля

Структура сущности
{
  "id": uuid,
  "classname": str,
  "name": str,
  "description": str,
  "parent_id": uuid,
  "properties": [
    {
      "name": str,
      "data_type": str,
      "multi": bool,
      "required": bool,
      "default": any,
      "idclass": uuid,
      "items": array<str>,
      "security_filter_read": array,
      "security_filter_write": array
    }
  ]: array<obj>,
  "storage_mode": str,
  "integrity_mode": str,
  "cache_mode": str,
  "opts": {
    "title": str,
    "comment": str,
    "dms_group": object,
    "check_required_fill_defaults": bool,
    "max_limit": int,
    "max_mask": array<str>,
    "max_size": int,
    "store_changehistory_mode": str,
    "caption_property": str,
    "expires_mode": str,
    "expires_ttl_property": str,
    "expires_ts_property": str,
    "storage_instance": str,
    "filestorage_instance": str,
    "lookup_properties": array<str>,
    "partition_property": str,
    "partition_interval": str,
    "partition_count": int,
    "replication_factor": str,
    "notify_transactions": bool,
    "cache_sec": int,
    "cache_limit": int,
    "security_filter_read": array,
    "security_filter_write": array
  },
  "ext": {
    "ct": date,
    "lwt": date
  }
}
Table 1. Поля
Спецификация Описание

Поле: id
Режим: inout
Тип: uuid
По умолчанию: generated

Идентификатор. Может быть задан при создании, иначе генерируется системой.

Поле: classname
Режим: in
Тип: str
По умолчанию: required

Имя коллекции класса. Может содержать путь через '/'. Как правило в множественном значении.

Поле: name
Режим: in
Тип: str
По умолчанию: empty

Отображаемое название класса

Поле: description
Режим: in
Тип: str
По умолчанию: empty

Описание класса

Поле: parent_id
Режим: in
Тип: uuid
По умолчанию: empty

Идентификатор класса-предка. Наследует все его поля.

Поле: properties
Режим: in
Тип: array<object>
По умолчанию: empty

Список свойств экземпляров класса.
Каждое свойство содержит:

  • name  —  Обязательное поле. Англоязычное название свойства, применяемое в API и при формировании БД.

  • data_type  —  Обязательное поле. Тип значения. Варианты значений:

    • string - строка;

    • boolean - переключатель;

    • integer - целое число 32 бит;

    • long - целое число 64 бит;

    • float - дробное число;

    • increment - целое число 64 бит. Разрешено только для storage_mode = category, history, transactionlog. Допускается только одно поле инкремента на класс, включая все наследованные поля. Каждая операция создания и замены сущности производит увеличение инкремента в классе, даже если операция завершается неудачей - соответственно могут быть пустоты в последовательности. Последнее значение инкремента сохраняется в объектном хранилище, так что при загрузке класса производится его обнаружение. Тем не менее можно сгенерировать ситуацию, когда последнее значение инкремента для класса не считается при загрузке, и может возникнуть конфликт идентичных значений.

    • date - дата;

    • time - время;

    • datetime - дата и время;

    • uuid - уникальный идентификатор 128 бит;

    • enum - перечисление, требует указания дополнительного поля items;

    • any - произвольный объект, хранится в json-формате;

    • entity - ссылка на другую сущность модели данных, требует указания дополнительного поля idclass;

    • attachment - файловое вложение. Значение заполняется автоматически при загрузке вложения через REST-API, при чтении сущности возвращает метаданные файла в виде json-объекта. Доступ к валожениям в REST API осуществляется путем сцепления пути к сущности и имени свойства.

  • caption  —  По умолчанию пустая строка. Читаемое название свойства.

  • multi  —  По умолчанию false. Переключает поле в режим списка. Вместо числа - массив чисел, вместо вложения - список вложений и т.д. В случае вложений - доступ в REST API осуществляется к конкретному файлу по имени через название свойства как часть пути.

  • required  —  По умолчанию false. Признак обязательного заполнения свойства.

  • default  —  По умолчанию null. Значение по умолчанию для заполнения свойства.

  • idclass  —  Только для data_type='object'.

  • items  —  Только для data_type='enum'.

  • security_filter_read  —  По умолчанию []. Фильтр на доступ к просмотру значения поля для конкретного пользователя, от имени которого выполняется запрос на чтение. Формат и условия применения аналогичны class.opts.security_filter_read. Если использует зависимость от значений полей конкретной сущности, то при выборке из коллекции поле исключается. Работает аналогично параметру 'mask' при выборке из коллекции.

  • security_filter_write  —  По умолчанию []. Фильтр на доступ к изменению значения поля для конкретного пользователя, от имени которого выполняется запрос. Перемножается на фильтр в параметре 'security_filter_read' поля. Формат и условия применения аналогичны class.opts.security_filter_write.

Поле: storage_mode
Режим: in
Тип: string
По умолчанию: category

Режим хранения:

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

  • ets - хранение в оперативной памяти экземпляра. Тестовый или некритичный к потере данных режим. Скорость ~15000 операций в секунду.

  • ram - хранение в распределенной объектной БД (mnesia on ram only). Не сохраняет данные на диск. Целостность и сохранность данных обеспечивается пока доступен один из экземпляров группы микросервисов, ответственной за обслуживание класса. Производительность операций доступа по ключу и операций записи ~10000 в секунду в расчете на один свободный поток обработчик.

  • runtime - хранение в распределенной объектной БД (mnesia on disc+ram). Сохраняет данные на диск и под нагрузкой значительно загружает дисковую подсистему на запись. Производительность операций доступа по ключу и операций записи ~10000 в секунду в расчете на один свободный поток обработчик.

  • category - хранение в реляционной БД postgresql без партицирования. Скорость до 10000 операций в секунду в режиме параллельной обработки, ~3000 операций в секунду в синхронном режиме.

  • history - хранение в реляционной БД postgresql с партицированием по дате. Требует указания размерности партишена (год, месяц, день), и поля со значением для патицирования.
    в* transactionlog - отправка данных в кластер Kafka. При обнаружении storage с type=clickhouse с тем же значением instance автоматически генерирует таблицу-приемщик из Kafka в ClickHouse (ReplicatedReplacingMergeTree), и делает доступными операции чтения.

Поле: integrity_mode
Режим: in
Тип: string
По умолчанию: sync_fast_read

Режим обслуживания:
* async - N(=10) очередей чтения с распределением по хешам идентификаторов, очередь чтения не используется.
* sync - одна очередь записи, одна очередь чтения.
* sync_fast_read - N(=10) очередей чтения с распределением по хешам идентификаторов, M(=10) очередей чтения. Отправка уведомления после сохранения в БД. Читатели ждут завершения более ранних операций записи.
* sync_fast_notify - N(=10) очередей чтения с распределением по хешам идентификаторов, M(=10) очередей чтения. Отправка уведомления об изменении перед сохранением в БД. Читатели не ждут завершения более ранних операций записи.

Поле: cache_mode
Режим: in
Тип: string
По умолчанию: temp

Режим кэширования в памяти. Имеет смысл только для типов category, history, transactionlog.

  • full - кэшируется весь объем данных. Применимо только для type=category. Чтение производится из кэша - поиск по идентификатору в кэше быстрый, но выборка при большом объеме может быть медленнее чем в оригинальном движке БД. Не применяется для storage_mode = 'transactionlog'

  • temp - кэшируется последнее используемое в ограниченном объеме. Удаляется автоматически при переполнении кэша. Поиск по идентификатору в кэше быстрый, выборка всегда производится в оригинальном хранилище БД.

  • none - кэш не используется.

В режиме хранения 'transactionlog' без использования хранилища clickhouse автоматически применяется режим 'none'.
В режиме хранения 'transactionlog' с использованием хранилища clickhouse режим 'full' автоматически сбрасывается в 'temp'. А режим 'none' предполагает отсутствие обращений на чтение, замену и обновление данных по крайней мере некоторое время после последней операции модификации, поскольку данные достигают кликхауса асинхронно и с некоторой задержкой.

Поле: opts
Режим: in
Тип: object
Составное поле

Поле: opts.title
Режим: in
Тип: str
По умолчанию: empty

Произвольный заголовок

Поле: opts.comment
Режим: in
Тип: str
По умолчанию: empty

Произвольный комментарий

Поле: opts.section
Режим: in
Тип: str
По умолчанию: empty

Section name to select responsible dms group (by configuration option sections).

Поле: opts.dms_group
Режим: in
Тип: object
По умолчанию: empty

Site → role group index. Default - unique (less number) dms group for domain
Не реализовано

Поле: opts.check_required_fill_defaults
Режим: in
Тип: bool
По умолчанию: true

if entities should be checked for required and filled by defaults by the server. Model can economy

Поле: opts.max_limit
Режим: in
Тип: int
По умолчанию: 100

How many items could be requested on read in max.

Поле: opts.max_mask
Режим: in
Тип: array<string>
По умолчанию: empty

Max mask of properties, that could be returned on collection read.

Поле: opts.max_size
Режим: in
Тип: int
По умолчанию: 10000

Max size of storage (only for 'ram' and 'runtime').
Max 1000000.
For storage_mode = 'ram', 'runtime'.

Поле: opts.store_changehistory_mode
Режим: in
Тип: str
По умолчанию: none

Режим сохранения лога транзакций по всем изменениям сущностей класса.
Возможные варианты:

  • none - Сохранение лога транзакций выключено.

  • sync - Сохранение лога транзакций происходит в синхронном режиме. Работа с классом тормозится вплоть до завершения размещения информации в логе транзакций.

  • async - Сохранение лога транзакций происходит в асинхронном режиме с сохранением последовательности изменений. При большой нагрузке выстраиваются очереди для размещения информации в лог транзакций.

В качестве лога используется класс модели данных 'platform/log/HistoryChanges'.
Он является единым и единственным приемником всего потока изменений по настроенным на логирование транзакций классам.

Класс истории изменений по умолчанию создается из fixture-дескриптора с типом storage_mode='history' и размещением в storage_instance='auto'.
Дескриптор применяется на каждом перезапуске домена в том случае, если значение 'ext.fixture_version' у обнаруженной сущности меньше.

При необходимости класс можно скорректировать, разместив в другое хранилище или по другому адресу. Главное - значения 'ext.fixture_version', 'opts.store_changehistory_mode', структуру полей, а также оставить тип 'history' или 'transactionlog'.
В дальнейшем необходимо будет отслеживать изменения фиксчи при обновлениях системы.

Поле: opts.caption_property
Режим: in
Тип: str
По умолчанию: empty

Имя свойства с именем, которое следует отображать для сущности, в частности в истории изменений.

Поле: opts.stat_mode
Режим: in
Тип: str
По умолчанию: "default"

Режим ежеминутного логирования статистики по классу.
Возможные варианты:

  • disabled - Логирование статистики по классу принудительно выключено.

  • default - Логирование статистики по классу на уровне medium управляется конфигурационной настройкой микросервиса dms

  • low - Низкий уровень ежеминутного логирования статистики. Запись появляется только если класс работает с качественными отклонениями от нормы.

  • medium - Средний уровень ежемингутного логирования статистики. В дополнение к 'low' строка с показателями появляется, если класс обрабатывал запросы. Также появляются 2 строчки с оценкой производительности потоков обработчиков и уведомлений за последнюю минуту: количество, минимальное время выполнения в расчете на 1 запрос, максимальное время выполнения в расчете на один запрос, среднее время выполнения одного запроса.

  • high - Высокий уровень ежеминутного логирования статистики. Информация по потокам обработчикам выводится многострочно в расчете по каждой операции (чтение коллекции, чтение сущности, поиск по ключу, модификация, замена, удаление, очистка)

Поле: opts.worker_r_count
Режим: in
Тип: str
По умолчанию: 0

Количество параллельных потоков обработки операций чтения.
Значение 0 применяет заданные настройки по умолчанию (dms' class_readers_count).
Имеет смысл только для классов, работающих в режимах с параллельной обработкой (все, кроме 'sync').
Допускаются значения от 0 до 64.

Поле: opts.worker_w_count
Режим: in
Тип: str
По умолчанию: 0

Количество параллельных потоков обработки операций записи.
Значение 0 применяет заданные настройки по умолчанию (dms' class_writers_count).
Имеет смысл только для классов, работающих в режимах с параллельной обработкой (все, кроме 'sync').
Допускаются значения от 0 до 64.

Поле: opts.expires_mode
Режим: in
Тип: str
По умолчанию: "none"

when to auto set (reset) timestamp in ts property
Only for storage_mode = runtime.
Values:

  • none - режим автоудаления не используется.

  • modify - таймштамп выставляется автоматически в момент любой модификации сущности.

  • create - таймштамп выставляется автоматически только при создании сущности.

  • custom - таймштамп выставляется только вручную с помощью REST.

Поле: opts.expires_ttl_property
Режим: in
Тип: str
По умолчанию: empty

Property of int to setup auto ttl (time-to-live) in seconds.
Only for storage_mode = runtime when opts.expires_mode != none.

Поле: opts.expires_ts_property
Режим: in
Тип: str
По умолчанию: empty

Property of long to setup ts in milliseconds from 1970 (unix time * 1000).
Only for storage_mode = runtime when opts.expires_mode != none.

Поле: opts.aggr_cache_ttl_ms
Режим: in
Тип: int
По умолчанию: 1000

Время хранения в кеше результатов выполнения запросов на чтение агрегированных данных.
Применяется для storage_mode = runtime и ram.

Запросы на агрегацию данных в перечисленных хранилищах производятся полным сканированием, поэтому в объемных коллекциях потребляют ресурсы.
Если возможен регулярный одновременный опрос одних и тех же агрегированных данных, например получение количества элементов с фильтром из дашбордов пользовательских приложений, то имеет смысл использовать кэш результатов вычисления агрегации данных.
Значение 0 отключает кеш.

Поле: opts.dirty_write_enabled
Режим: in
Тип: bool
По умолчанию: false

Выключатель отладочного режима для ускоренной работы класса с типами 'ram' и 'runtime' без использования транзакций на операции записи.
Это позволяет резко увеличить производительность класса при использовании конфигурации, где Active-Passive экземпляры DMS разделены сетью с длинным или нестабильным пингом.

Поле: opts.storage_instance
Режим: in
Тип: str or object
По умолчанию: auto

InstanceKey or #{Site ⇒ InstanceKey}.
Only for storage_mode = category, history, transactionlog.

При отсутствии настроенного хранилища с кодом 'auto' класс автоматически привязывается к модельной базе ('era_model_DOMAIN'), созданной через основное подключение к БД Postgres домена).

Поле: opts.filestorage_instance
Режим: in
Тип: str or object
По умолчанию: "auto"

InstanceKey or #{Site ⇒ InstanceKey} (for attachments), when InstanceKey defines storage of type s3, fs, nfs, fsync.
Used only when properties of data_type = attachment found.
Реальный путь к вложениям формируется одинаково вне зависимости от типа хранилища:

  • Классы-категории, единичное вложение  —  …​/Domain/ClassName/Id12/Id34/Id56/IdRest/PropertyName

  • Классы-категории, множественное вложение  —  …​/Domain/ClassName/Id12/Id34/Id56/IdRest/PropertyName/FileName

  • Классы-истории, единичное вложение  —  …​/Domain/ClassName/PartDate/Id12/Id34/Id56/IdRest/PropertyName

  • Классы-истории, множественное вложение  —  …​/Domain/ClassName/PartDate/Id12/Id34/Id56/IdRest/PropertyName/FileName

При отсутствии настроенного хранилища с кодом 'auto' класс автоматически привязывается к размещению на системных файловых серверах.

Поле: opts.lookup_properties
Режим: in
Тип: array<str>
По умолчанию: empty

List of property names for lookup operation (indexes, separate fields etc).
Only for storage_mode = category, history, transactionlog.

Поле: opts.partition_property
Режим: in
Тип: str
По умолчанию: empty

Property of type=datetime to make partitioned history storage.
Optional for storage_mode = history (pg+partition) - uses date to build new partition table in postgresql database.
Required for storage_mode = transactionlog (kafka+clickhouse) - uses date as clickhouse primary key prefix.

Поле: opts.partition_interval
Режим: in
Тип: str
По умолчанию: month

Size of partition in partitioned history storage.
Для storage_mode = history (pg+partition) - определяет размер одной партиции и, равно, условия создания новой партиции при размещении данных.
Для storage_mode = transactionlog (kafka+clickhouse) - использует дату в качестве основного ключа сортировки при размещении данных в ClickHouse.
Возможные значения:

  • year - партиция на год

  • month - партиция на месяц

  • day - партиция на день

Поле: opts.partition_count
Режим: in
Тип: int
По умолчанию: 2

How many partitions does topic have (1-10).
Only for storage_mode = transactionlog (kafka).

Поле: opts.replication_factor
Режим: in
Тип: int
По умолчанию: 2

How many replicas does topic have (1-4).
Only for storage_mode = transactionlog (kafka).

Поле: opts.notify_transactions
Режим: in
Тип: bool
По умолчанию: false

If should forcely notify. Note, than storage_mode = transactionlog is not notified by default.
Only for storage_mode = transactionlog.

Поле: opts.replace_without_read
Режим: in
Тип: bool
По умолчанию: false

Отменяет операцию чтения сущности перед заменой. Та в свою очередь производится для нужд а) проверки прав на замену, б) генерации уведомления с операцией update или create в зависимости от наличия сущности перед заменой.

В режиме хранения 'transactionlog' без использования хранилища clickhouse не используется, поскольку операция replace недоступна.

Поле: opts.cache_sec
Режим: in
Тип: int
По умолчанию: 600

How long temporarily cache holds modified items.
Only for cache_mode = temp.
Допускаются значения от 5 до 1800.
Интервал применяется и для обнаружения устаревших значений, и для определения периодичности проверки.

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

Поле: opts.cache_limit
Режим: in
Тип: int
По умолчанию: 1000

How many modified items are holded in temporarily cache.
Only fo cache_mode = temp.
Допускаются значения от 100 до 100000.
Если в момент периодической проверки в кеше остается актуальных записей больше установленного значения, то те из них, к которым наиболее давно происходило обращение, принудительно удаляются из кеша.

Чем больше значений в кеше, тем более ресурсоемка операция очистки устаревших записей.
Операции replace, update, read_entity преимущественно берут значение из кеша.
Предельный размер кеша следует определять исходя из профиля ожидаемой нагрузки на класс.

Поле: opts.security_filter_read
Режим: in
Тип: array
По умолчанию: []

Фильтр для пользовательских запросов на выборку данных из коллекции, чтение конкретного элемента коллекции, а также поиск по ключевым полям.

Формат значения соответствует формату параметра 'filter' при выборке из коллекции (подробнее).
Дополнительно в выражениях могут использоваться расширенные функции.

Не применяется к запросам пользователей, имеющих роль 'admin'.
Не применяется к запросам из сценариев.
Не применяется к запросам из Token-API, если каналу интеграции не назначен пользователь (opts.userid), от имени которого осуществляются запросы и подписки, либо если этому пользователю или самому каналу назначена роль 'admin'.

Применяется в HTTP REST API, Websocket REST API, подписках на изменениях и уведомлениях.

Поле: opts.security_filter_write
Режим: in
Тип: array
По умолчанию: []

Фильтр для пользовательских запросов на создание, замену, изменение, удаление элемента коллекции.
Перемножается на фильтр для чтения из поля 'opts.security_filter_read'.

Формат значения соответствует формату параметра 'filter' при выборке из коллекции (подробнее).
Дополнительно может использоваться функция '$USER', предоставляющая доступ к данным авторизованного пользователя, от имени которого осуществляется запрос на чтение.
См. примеры в 'opts.security_filter_read'.

Не применяется к запросам на чтение.
Не применяется к запросам пользователей, имеющих роль 'admin'.
Не применяется к запросам из сценариев.
Не применяется к запросам из Token-API, если каналу интеграции не назначен пользователь (opts.userid), от имени которого осуществляются запросы и подписки, либо если этому пользователю или самому каналу назначена роль 'admin'.

Применяется в HTTP REST API, Websocket REST API.

Поле: ext
Режим: inout
Тип: object
Составное поле

Позволяет расширять состав произвольными ключами и значениями

Поле: ext.ct
Режим: out
Тип: date
По умолчанию: generated

Время создания объекта

Поле: ext.lwt
Режим: out
Тип: date
По умолчанию: generated

Время последней модификации объекта

Специальные функции фильтра

Table 2. Специальные функции фильтра
Функция Описание и примеры

$USER

Предоставляет доступ к данным авторизованного пользователя, от имени которого осуществляется запрос на чтение.

Примеры:

  • ["$USER"] - идентификатор пользователя.

  • ["$USER", "id"] - идентификатор пользователя.

  • ["$USER", "login"] - логин пользователя.

  • ["$USER", "ext", "a", "b"] - значение поля 'ext.a.b' учетной записи пользователя.

  • ["$USER", "security", "mandate"] - значение поля 'security.mandate' учетной записи пользователя.

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

  • ["$USER", "ROLES"] - список ролей пользователя (элементы - строки - имена ролей). Заменяется на ["list","role1","role2",…​].

  • ["$USER", "ROLES::array"] - список ролей пользователя (элементы - строки - имена ролей). Заменяется на ["array","role1","role2",…​]. Используется для применения в функциях 'hasAny', 'hasAll'.

Позволяет обратиться к списку групп пользователя на всю глубину:

  • ["$USER", "GROUPS"] - список групп пользователя (элементы - строки - идентификаторы групп). Заменяется на ["list","uuid1","uuid2",…​].

  • ["$USER", "GROUPS::array"] - список групп пользователя (элементы - строки - идентификаторы групп). Заменяется на ["array","uuid1","uuid2",…​]. Используется для применения в функциях 'hasAny', 'hasAll'.

Позволяет обратиться к списку подчиненных. В самом простом случае полного взаимного доступа все подчинены всем. Это отражается единственным элементом "all" вместо нескльких идентификаторов в списке.

  • ["$USER", "SUBORDINATES"] - список идентификаторов подчиненных пользователей (элементы - строки - идентификаторы пользователей). Заменяется на ["list","uuid1","uuid2",…​] или ["list","all"].

  • ["$USER", "SUBORDINATES::array"] - список идентификаторов подчиненных пользователей (элементы - строки - идентификаторы пользователей). Заменяется на ["array","uuid1","uuid2",…​] или ["array","all"]. Используется для применения в функциях 'hasAny', 'hasAll'.

Позволяет выбрать агрегированное значение из совокупности всех сущностей: пользователя, всех его ролей и групп. Используется функция второго порядка "DEEP".
Поддерживаются функции третьего порядка MAX, MIN, ANY. По умолчанию ANY - значение берется из учетной записи пользователя, если там нет то из одной из его ролей, если там нет, то из одной из его групп. Если нигде нет, тогда undefined.
Функция DEEP имеет смысл для обращения к полям ext и security, которые существуют во всех трех классах и заполняются произвольным образом (ext доступен для изменения самим пользователем через API, а security нет).
Например, для поиска максимально доступного мандата.

Примеры:

  • ["$USER", "DEEP", "MAX", "security", "mandate"] - максимальное значение поля 'security.mandate' из учетной записи пользователя, всех его групп и ролей.

  • ["$USER", "DEEP", "MIN", "ext", "priority"] - минимальное значение поля 'ext.priority' из учетной записи пользователя, всех его групп и ролей.

  • ["$USER", "DEEP", "ANY", "ext", "priority"] - значение поля 'ext.a.b' из учетной записи пользователя, если отсутствует, то из любой из ролей, если отсутствует, то из любой из групп.

  • ["$USER", "DEEP", "ext", "a", "b"] - эквивалент предыдущего - значение поля 'ext.a.b' из учетной записи пользователя, если отсутствует, то из любой из ролей, если отсутствует, то из любой из групп.

Путь к полю может быть произвольной глубины - через запятую список вложенных ключей.
При указании очередным ключом строки текущее значение рассматривается как объект, при указании ключом натурального числа текущее значение рассматривается как массив.

Если указанное поле или путь не найдены, то подставляется значение undefined, которое может быть обработано функциями 'isnull', 'isnotnull' и корректно преобразуется в значение 'NULL' при осуществлении запросов к конкретным типам СУБД.

В зависимости от типа обнаруженного значения производится преобразование к конечному результату: числа остаются числами, строки остаются строками, булевы значения остаются булевыми значениями, массивы заменяются на ["list","elt1","elt2",…​], объекты заменяются на undefined.

Комплексный пример выражения:

["or",
  ["in",
     "master",
     ["$USER","ROLES"]
  ],
  ["and",
    ["in",
      ["property","status"],
      ["list","in_work","in_review"]
    ],
    ["==",
      ["property","responsibleUserId"],
      ["$USER", "id"]
    ]
  ]
]

См. также