Citeck Artifacts

Artifacts are the basic units of extension and configuration of the ECOS platform. Any system element — data type, form, journal, process, notification template — is an artifact. Artifacts are stored in the ecos-apps microservice, which manages their versioning and delivery to target microservices.

This page describes:

  • what an artifact is and how its identification is structured;

  • how to manage artifacts through the “ECOS Artifacts” journal;

  • artifact sources and update policies;

  • artifact location in the project file structure;

  • full list of artifact types by microservice;

  • artifact overriding and patches;

  • YAML format for artifact descriptions;

  • creating a new artifact type.

Definitions

Artifact - an extension unit in Citeck. Artifacts include forms, journals, types, permission matrices, actions, process descriptions, and many other entities in the system.

Microservice ecos-apps manages artifacts, maintaining their versioning and delivering them to the target microservice. Artifact content in the system is immutable, and any change to an artifact always creates a new version, while the old one is preserved in the version list.

Examples of artifacts: Type, Form, Journal.

  • Data Type - the primary ECM artifact describing an object. The data type defines the metadata the object will contain, lifecycle statuses, and roles that can work with the object. The data type is linked to a form and a journal.

  • Form - a graphical representation of an object as a set of interface elements for manipulating the object’s data. Interface elements reference attributes defined in the data type.

  • Journal - a tabular form of representing objects with the ability to configure column display, filtering, and object manipulation. Columns correspond to object data or can be calculated based on it.

The artifact type typically consists of two parts separated by the / symbol.

  • The first part is the system area to which the artifact belongs. Usually, one microservice is responsible for one area.

  • The second part is the local type identifier

For example, in the type ui/form, ui is the area, and form is the local identifier.

Note

If the artifacts configured in the designer cover the required functionality, they can be exported as an application.

If the functionality is insufficient, you can create a separate microservice that will contain both artifacts configured in the designer and the necessary additional logic.

Journal “ECOS Artifacts”

A journal ECOS Artifacts is provided for managing artifacts. This journal includes all artifacts that have reached the ecos-apps microservice.

Located in Workspace “Admin Section” - System Management:

Available Actions

1. Download Artifact History

  • When clicking the action, you can select the date from which to download the artifact’s history.

  • Upon form submission, a zip archive is downloaded containing all versions of the artifact from the specified date.

  • If the last artifact was uploaded earlier than the selected date, only it will be downloaded (i.e., there will always be at least 1 artifact).

  • The folder name format for the artifact version: creation_dateTcreation_timeZ-[USER | APPLICATION | ECOS_APP]. The creation date is specified in UTC timezone.

../_images/artifact-history.png

2. Download Artifact

Always downloads a zip archive with the selected artifact.

3. Redeploy Artifact Manually

Send the artifact from ecos-apps to the microservice. Can be useful during development or after a failure in the target microservice’s database, i.e., ecos-apps does not pass the artifact if it was previously successfully deployed.

4. Reset User Version of Artifact

The reset reverts to the version that was installed from the application (APPLICATION or ECOS_APP). Only artifacts that have USER in the Source Type column can be reset.

Artifact Sources

There are 3 possible artifact sources:

  1. USER - the artifact is added or modified by a user;

  2. APPLICATION - the artifact is loaded from applications connected to the command interface;

  3. ECOS_APP - the artifact is loaded from the Citeck application;

Artifact Updates

All 3 sources have their own policy for updating artifacts:

  • USER - The artifact is updated unconditionally. Any change to the artifact leads to its change in the ecos-apps microservice database.

  • APPLICATION - The artifact is updated if it does not belong to any Citeck application and a version of the artifact has been loaded that differs from the previous one loaded from APPLICATION. Example: If we have the following artifact revisions:

    • rev2 USER

    • rev1 USER

    • rev0 APPLICATION

Then rev0 is the very first version of the artifact, and rev2 is the latest version. We see that the first version came from an application and the other two from a user.

If in this situation version rev0 from APPLICATION arrives at the microservice, nothing will change even though rev2 != rev0.

If rev3 comes from the application, the new revision will be loaded and become current:

  • rev3 APPLICATION

  • rev2 USER

  • rev1 USER

  • rev0 APPLICATION

ECOS_APP - updated similarly to APPLICATION, but upon loading, the artifact is marked as belonging to an application. If an artifact belongs to an application, it is not updated from APPLICATION.

Artifact Location

All artifacts are located in directories corresponding to their type.

The root folder for artifacts is configured in the application, and subfolders like ui/form, model/type, etc., can be created within it.

By default, the root artifact folder for the Citeck application is src/main/resources/app/artifacts, and for a microservice it is src/main/resources/eapps/artifacts

Citeck Application

Citeck Microservice

../_images/ecos_app1.png ../_images/ecos_mks1.png

For example, for the ECOS Assignments application, the folder structure is as follows:

Artifact Types

Type

Microservice

Note

model/aspect

ecos-model

Aspect

model/authorities-sync

ecos-model

User and Group Synchronization

model/endpoint

ecos-model

Endpoint

model/num-template

ecos-model

Numbering Templates

model/permission-def

ecos-model

Permission Description

model/Permission settings

ecos-model

Permission Settings

model/permissions

ecos-model

Access Rights

model/secret

ecos-model

Secret

model/type

ecos-model

Data Types

model/working-calendar

ecos-model

Working Calendar

model/working-schedule

ecos-model

Work Schedule

model/workspace

ecos-model

Workspace

model/workspace-template

ecos-model

Workspace Template

model/workspace-member

ecos-model

Workspace Member

ui/action

ecos-uiserv

Actions

ui/admin-sections-group

ecos-uiserv

Admin Sections Group

ui/board

ecos-uiserv

Kanban Board

ui/dashboard

ecos-uiserv

Dashboards

ui/form

ecos-uiserv

Forms

ui/i18n

ecos-uiserv

Localization

ui/icon

ecos-uiserv

Icon Set

ui/journal-settings

ecos-uiserv

Journal Settings

ui/journal

ecos-uiserv

Journals

ui/menu

ecos-uiserv

Menu

ui/theme

ecos-uiserv

Custom Themes

app/artifact-patch

ecos-apps

Artifact Patch

app/config

ecos-apps

Configuration

app/dev-module

ecos-apps

Development Module

app/ecosapp

ecos-apps

ECOS Application

app/license

ecos-apps

ECOS License

app/patch

ecos-apps

Patch

app/system-info

ecos-apps

System Information

integration/camel-dsl

ecos-integrations

Camel DSL Configurations

integration/credentials

ecos-integrations

Credentials

integration/datasource

ecos-integrations

Data Source

integration/ext-portal

ecos-integrations

External Portal

integration/file-import-config

ecos-integrations

File Import Configuration

integration/in-webhook

ecos-integrations

Webhook

integration/osgi-bundles

ecos-integrations

OSGi Bundle

integration/recsrc

ecos-integrations

External Database Settings

integration/sync

ecos-integrations

Synchronizations

transformation/template

ecos-transformations

Document Template

process/bpmn-kpi-settings

ecos-process

BPMN KPI Settings

process/bpmn-section

ecos-process

BPMN Section

process/bpmn-task-atts-sync

ecos-process

BPMN Task Attributes Synchronization

process/bpmn

ecos-process

BPMN Process

process/dmn-section

ecos-process

DMN Section

process/dmn

ecos-process

DMN

notification/file

ecos-notifications

Notification Files

notification/template

ecos-notifications

Notification Templates

notification/sender

ecos-notifications

Senders

notification/reminder

ecos-notifications

Reminder

Artifact Override

To override artifacts, you can create a folder named override in the root directory of the artifacts.

Example folder structure:

eapps:
  - artifacts:
      - ui:
          - form:
              - some-form.json
          - journal:
              - some-journal.yml
      - override:
          - ui:
              - form:
                  - some-form.json

For the form some-form.json, a patch with type override and order -100 (by default) will be created.

If you need to configure the order, you should create a meta.yml file in the root of the override folder. The following settings are possible:

List of possible settings in override/meta.yml

Name

Data Type

Description

order

float

Patch order for overriding the artifact. Patches with a lower order are applied first.

scope

string

The parameter is used to prevent identifier collisions for override patches.
The patch identifier is formed according to the following pattern: override[_{{scope}}]$ui/form$some-form
../_images/artifact_type_override.png

Features

  1. Artifact overriding works regardless of where the main artifact is deployed from

Creating a New Artifact Type

  1. Determine which microservice the artifact should go to after deployment.

  2. In the target application, find the eapps folder in the resources and create subfolders with the following content:

    • first level - the section to which the artifact belongs (usually 1 section == 1 microservice. For example, ui → ecos-uiserv, integration → ecos-integrations, model → ecos-model, etc.)

    • second level - local type identifier (action, form, menu, dashboard, type, section, etc.)

It is not necessary to create exactly 2 levels, but it is desirable. The mechanism supports levels of any nesting from 1 to file system limitations).

Note

Keep in mind that the created directory hierarchy will be used as the artifact type identifier. Therefore, it should be treated carefully.

  1. Create a type.yml file in the resulting directory with approximately the following content:

modelVersion: "1.0"

source-id: "eform"

controller:
    type: json

modelVersion - model type. In the future, it will be used for migrating old artifacts.

sourceId - ID of the data source (RecordsDAO) through which access to the artifact data will be provided. This field is necessary if a dependency resolution mechanism is required on the ECOS Apps side. If the artifact has no dependencies, an empty string can be used.

controller.type - controller type for the artifact type. Defines the logic for loading artifacts from the directory and writing to the directory. json is the simplest and most understandable controller, which should be used when adding simple artifact types. For complex cases, there is a script controller that supports describing the logic for reading and writing artifacts in Groovy (other languages like Kotlin will be added in the future).

  1. Describe the handler for our artifact:

@Slf4j
//все реализации интерфейса EcosModuleHandler в контексте будут зарегистрированы автоматически
@Component
@RequiredArgsConstructor
public class FormModuleHandler implements EcosModuleHandler<EcosFormModel> {

    private final EcosFormService formService;

    //При деплое артефакта он попадает в этот метод
    @Override
    public void deployModule(@NotNull EcosFormModel formModel) {
        log.info("Form module received: " + formModel.getId() + " " + formModel.getFormKey());
        formService.save(formModel);
    }

    // callback для отправки изменённого артефакта в ECOS Apps. Нужен для ведения истории всех ревизий
    @Override
    public void listenChanges(@NotNull Consumer<EcosFormModel> consumer) {
        formService.addChangeListener(consumer);
    }

    // метод, который вызывается перед деплоем. Если он вернет null, то деплой артефакта не произойдет
    @Nullable
    @Override
    public ModuleWithMeta<EcosFormModel> prepareToDeploy(@NotNull EcosFormModel formModule) {
        return getModuleMeta(formModule);
    }

    // Получение метаданных по артефакту (его ID и зависимости)
    @NotNull
    @Override
    public ModuleWithMeta<EcosFormModel> getModuleMeta(@NotNull EcosFormModel formModule) {
        return new ModuleWithMeta<>(formModule, new ModuleMeta(formModule.getId(), Collections.emptyList()));
    }

    // ID типа артефакта, для которого мы описали Handler. Должен соответствовать иерархии папок из п.2
    @NotNull
    @Override
    public String getModuleType() {
        return "ui/form";
    }
}

This completes the description of the artifact type. You can place .json files in eapps/artifacts/ui/form.

When adding a new type, only the microservice where we describe this type requires a restart.

YAML Artifact Format

Since version 3.25.0 of the community core, support for the yaml format for describing artifacts has been added. YAML format version 1.2

Any artifacts that are loaded in json format (types, journals, forms, etc.) can be described in yaml.

After reading, the yaml file will be converted to json and then delivered to the target microservice in that form.

When downloading an artifact from the journal, we will still receive json regardless of how the original configuration was described.

Example of a forms journal description:

id: ecos-forms
label: { ru: Формы, en: Forms }

typeRef: emodel/type@form
sourceId: uiserv/eform

attributes:
  actionFormatter: '' #include include/legacy-actions.js

actions:
  - uiserv/action@ecos-module-download
  - uiserv/action@delete
  - uiserv/action@edit

columns:

  - name: moduleId
    label: { ru: Идентификатор, en: Id }

  - name: formKey
    label: { ru: Ключ формы, en: Form key }

  - name: title
    label: { ru: Название, en: Name }

  - name: description
    label: { ru: Описание, en: Description }

Capabilities and features of the format (ст - standard capabilities, нм - our modification):

  1. (ст) YAML 1.2 is a superset of the JSON format. This means that you can simply change the artifact extension from .json to .yaml and everything will work as before without additional changes.

  2. (нм) Support for #include, which allows including the contents of external files into the current configuration.

General usage: somekey: '' #include filename

На месте ‘’ могут быть следующие значения: ‘’, ““ (для импорта содержимого файла как текста) и {} (для импорта внешней yaml конфигурации).

filename - relative path to the included file.

When reading the configuration, all places with #include will be replaced with the contents of the specified file (if there are two includes of the same file, it will be added twice to the config)

  1. (ст) Support for reusing parts of the config ( https://confluence.atlassian.com/bitbucket/yaml-anchors-960154027.html ):

some-reusable-value: &my-anchor
  aa: bb
  cc: dd

other-key: *my-anchor
other2-key: *my-anchor
  1. (нм) Support for reusing parts of the config with value overriding (a semi-standard mechanism, but the library used did not support it):

some-reusable-value: &my-anchor
  aa: bb
  cc: dd

other-key:
  <<: *my-anchor
  cc: ee

В other-key мы получим {“aa”: “bb“, “cc“: “ee“}

Patches for Artifacts

Since version ecos-apps 1.9.0, support for patches for artifacts has been added. Patches themselves are artifacts and can also be patched.

Patches serve as a replacement for the override mechanism, where we completely overwrote configuration files in the customer’s artifact. As practice has shown, this approach leads to many bugs when upgrading to a new version of the box because base configurations change over time.

Patches update the target artifact “on the fly” with every change to the artifact or the patch itself. For example, by deleting a patch in the journal, we will see within 3-7 seconds that the changes it applied have been rolled back and the artifact has acquired the standard configuration.

The list of patches in the system can be viewed in System Journals → Artifact Patches.

The capabilities described in the “YAML Artifact Format” section also apply to them.

If you change the record affected by the patch through the interface, the patch will not reapply itself. If you load a new version of the artifact through ecos-apps (by placing it in target or when restarting the server), the patch will be applied.

Patch format:

Field

Type

Mandatory

Default Value

Description

order

Float

No

0

Patch order.
If there are several patches for one artifact in the system, they are applied in this order from smallest to largest.

id

String

Yes

-

Identifier.
Unique among all patches for artifacts in the system.

target

ModuleRef

Yes

-

Target artifact that will be patched.
Written as artifact_type$local_id. Example: ui/journal$ecos-journals
Идентификатор рабочего пространства в target не указывается — он задаётся отдельным полем workspace.

workspace

String

No

“”

Идентификатор рабочего пространства, в котором находится целевой артефакт.
Заполняется, если цель патча — артефакт внутри рабочего пространства. Пустая строка означает глобальный артефакт.
Один и тот же target в разных рабочих пространствах патчится независимо — на каждое сочетание target + workspace нужен отдельный патч.
Для обратной совместимости патчи к ui/menu$admin-workspace-menu без указания workspace при сохранении автоматически привязываются к рабочему пространству admin$workspace.

type

String

Yes

-

Patch type.
Currently, only the json type is supported.

config

ObjectData

Yes

-

Patch configuration

Patches are described in the eapps/artifacts/artifact-patch directory.

Journal “Artifact Patches”

Located in Workspace “Admin Section” - System Management - Artifact Patches:

Available actions:

  • Download;

  • Delete;

  • View;

  • Edit properties;

  • JSON Editor.

Patch Types

Patch type “json”

The configuration specifies 1 parameter - operations with the type array of objects.

All operations from the operations array are applied sequentially to the result of the previous operation’s changes.

The operation type is determined by the op key and can be as follows:

op

Description

Parameters

add

Add an element or an array of elements to the array at the specified path.

path - JsonPath to the array where the element should be added
value - value or array of values to be added
idx - index at which the value should be added. By default, the value is added to the end. Values outside the range of the existing array can be specified. In this case, elements will be added either to the beginning or to the end.

set

Set an explicit value to any field.

path - JsonPath to the element where the value should be placed
key - optional field that defines the key under which the value should be placed
value - value or array of values to be set

remove

Remove an element from the configuration

path - JsonPath to the element to be removed

rename-key

Rename a key in an object within the configuration.

path - JsonPath to the object in which the key should be renamed.
oldKey - old key name
newKey - new key name

Examples

Change an attribute for a form:

id: change-label-for-form-field

name:
  ru: Изменить название кнопки на форме
  en: Change button label on form

target: ui/form$ECOS_FORM

type: json
config:
  operations:
    - { op: set, path: '$..[?(@.key == "localization")].label', value: 'Свое название для кнопки локализации' }

Add an action for a type:

id: add-some-action-for-case

name:
  ru: Добавить действия для кейса
  en: Add actions for case

target: model/type$cat-doc-type-general-case

type: json
config:
  operations:
    - { op: add, path: 'actions', value: 'uiserv/action@pdf-content-with-barcode' }

Change localized text by key:

id: change-ui-admin-localization

name:
  ru: Изменить локализацию для раздела администратора
  en: Change localization for admin section

target: ui/i18n$menu-messages

type: json
config:
  operations:
    - { op: set, path: '$["messages"]["menu.header.admin-tools"][1]', value: 'Опциональный заголовок для меню администратора' }

Remove an action:

id: delete-action

name:
  ru: Удалить действие из типа
  en: Delete action from type

target: model/type$contracts-cat-doctype-contract

type: json
config:
  operations:
    - { op: remove, path: '$.actions[?(@==\"uiserv/action@edit-in-onlyoffice\")]'}

Change the value of the ECOS configuration parameter some-config-id to 123:

id: some-patch-id

name:
  ru: Изменение значения параметра конфигурации some-config-id
  en: Change some-config-id config value

target: app/config$app/notifications$some-config-id

type: json
config:
  operations:
    - { op: set, path: '$.value', value: [ 123 ] }
    - { op: set, path: '$.version', value: 1 }

Example patch for adding a menu section:

id: menu-change-test
name: {ru: Добавить раздел, en: Add section }
target: 'ui/menu$default-menu-v1'
type: json
config:
  operations:
    - op: add
      path: '$..[?(@.id == "sections")].items'
      value: {
        "id": "custom-meetings-section",
        "label": {
          "ru": "Совещания"
        },
        "icon": "ui/icon@i-leftmenu-meetings",
        "type": "SECTION",
        "items": [
          {
            "id": "123-123-123-123-123",
            "label": {
              "en": "Совещания"
            },
            "type": "JOURNAL",
            "config": {
              "recordRef": "uiserv/journal@meetings"
            },
            "items": [],
            "allowedFor": []
          }
        ]
      }

Пример патча для артефакта в рабочем пространстве:

id: hide-field-in-team-workspace-form

name:
  ru: Скрыть поле на форме в рабочем пространстве team-a
  en: Hide field on form in workspace team-a

target: ui/form$some-form
workspace: team-a

type: json
config:
  operations:
    - { op: set, path: '$..[?(@.key == "internalNote")]', key: hidden, value: true }

Example patch for boolean attributes of a form component:

{
  "operations": [
    {
      "op": "set",
      "path": "$..[?(@.key==\"meetDateTime\")]",
      "key": "hidden",
      "value": true
    }
  ]
}

Displaying artifacts of different categories

In the Data Types, Forms, and Journals journals, in the table settings filters, you can choose which artifact category to display — business data or system.

By default, the filter is set to System type (form|journal) = NO.

If set to YES, non-system records will be displayed in the list.

If set to Select, all records will be displayed.