Организационная структура
Организационная структура
Работа с организационной структурой через REST API: оргюниты, должности, сотрудники и связи между ними. Общие правила (авторизация, лимиты) — в обзоре REST API.
Работа с организационной структурой
Организационная структура состоит из нескольких ключевых сущностей:
Основные сущности
OrgItem - элемент организационной структуры. Бывает двух типов:
- Должность - например "Генеральный директор"
- Группа - например "Служба финансового контроля"
Связь с Ролями
Роли - это внутренняя абстракция Stormbpmn. OrgItem могут быть назначены на роли. В этом случае удалить их из API не получится, надо выполнить перепривязку через UI.
OrgItemEdge - связь между элементами оргструктуры, отображающая подчиненность.
- Например: "Служба финансового контроля" подчиняется "Генеральному директору"
- У каждого OrgItem может быть только одна родительская связь (двойное подчинение недопустимо)
Person - сотрудник организации
OrgItemPersonEdge - назначение сотрудника на элемент организационной структуры
- Например: "Котов Д.Г." назначен на должность "Генеральный директор"
- Person может быть назначен на несколько OrgItem
- Person может быть назначен ТОЛЬКО на OrgItem с типом "Должность"
Важно
Работа с сущностями разделена на отдельные методы. Целостность с точки зрения бизнес-логики поддерживает вызывающая система. Целостность с точки зрения валидации и связей между существующими сущностями обеспечивает система.
Атрибутивный состав сущностей
OrgItem
| Атрибут | Тип | Описание |
|---|---|---|
id | UUID | Внутренний идентификатор |
externalId | string | Идентификатор во внешней системе (уникальный) |
type | ENUM | POSITION (должность) или OU (группа) |
name | string | Название |
description | string | Описание в HTML формате |
color | string | Цвет в HEX формате |
OrgItemEdge
| Атрибут | Тип | Описание |
|---|---|---|
id | UUID | Внутренний идентификатор |
sourceId | UUID | Идентификатор родительского элемента |
targetId | UUID | Идентификатор дочернего элемента |
externalSourceId | string | Внешний идентификатор родителя |
externalTargetId | string | Внешний идентификатор дочернего элемента |
Person
| Атрибут | Тип | Описание |
|---|---|---|
id | UUID | Внутренний идентификатор |
externalId | string | Идентификатор во внешней системе (уникальный) |
email | string | Электронная почта |
phone | string | Телефон |
firstName | string | Имя |
lastName | string | Фамилия |
patronymic | string | Отчество |
photoUrl | string | Ссылка на фотографию (через API загрузки файлов) |
OrgItemPersonEdge
| Атрибут | Тип | Описание |
|---|---|---|
id | UUID | Внутренний идентификатор |
sourceId | UUID | Идентификатор OrgItem |
personId | UUID | Идентификатор Person |
externalSourceId | string | Внешний идентификатор OrgItem |
externalPersonId | string | Внешний идентификатор Person |
Методы API
Создание OrgItem
Путь: POST /public-api/v1/org-items
Структура запроса:
[
{
"externalId": "CEO_POSITION_001",
"type": "POSITION",
"name": "Генеральный директор",
"description": "<p>Руководитель организации</p>",
"color": "#FF6B6B"
}
]
Параметры запроса:
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| externalId | string | ✅ | Уникальный идентификатор во внешней системе |
| type | enum | ✅ | POSITION (должность) или OU (группа) |
| name | string | ✅ | Название элемента |
| description | string | 📄 | Описание в HTML формате |
| color | string | 📄 | Цвет в HEX формате |
Структура ответа:
{
"created": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"externalId": "CEO_POSITION_001",
"type": "POSITION",
"name": "Генеральный директор",
"description": "<p>Руководитель организации</p>",
"color": "#FF6B6B"
}
],
"errors": []
}
Чтение OrgItem
Путь: GET /public-api/v1/org-items
Query-параметры:
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
| page | number | 📄 | Номер страницы (по умолчанию 0) |
| size | number | 📄 | Размер страницы (по умолчанию 20) |
Получение по ID:
Путь: GET /public-api/v1/org-items/{id}
Параметры пути:
| Параметр | Тип | Описание |
|---|---|---|
| id | UUID | Внутренний идентификатор |
Получение по внешнему ID:
Путь: GET /public-api/v1/org-items/by-external-id/{externalId}
Параметры пути:
| Параметр | Тип | Описание |
|---|---|---|
| externalId | string | Внешний идентификатор элемента |
Структура ответа:
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"externalId": "CEO_POSITION_001",
"type": "POSITION",
"name": "Генеральный директор",
"description": "<p>Руководитель организации</p>",
"color": "#FF6B6B",
"parentItems": {},
"childItems": [
{
"id": "b2c3d4e5-f6g7-8901-bcde-f23456789012",
"externalId": "b2c3d4e5-f6g7-8901-bcde-f23456789012",
"name": "Заместитель генерального директора"
}
],
"assignedPersons": [
{
"externalId": "CEO_POSITION_001",
"id": "c3d4e5f6-g7h8-9012-cdef-345678901234",
"firstName": "Дмитрий",
"lastName": "Котов",
"email": "kotov@company.com"
}
]
}
Обновление OrgItem
Путь: PUT /public-api/v1/org-items/{id}
Параметры пути:
| Параметр | Тип | Описание |
|---|---|---|
| id | UUID | Внутренний идентификатор |
Обновление по внешнему ID:
Путь: PUT /public-api/v1/org-items/by-external-id/{externalId}
Структура запроса:
{
"name": "Генеральный директор (обновлено)",
"description": "<p>Главное лицо организации</p>",
"color": "#4ECDC4"
}
Параметры запроса:
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| name | string | 📄 | Новое название |
| description | string | 📄 | Новое описание в HTML |
| color | string | 📄 | Новый цвет в HEX |
Важно
Тип элемента (type) изменить нельзя после создания. Для смены типа необходимо удалить и создать новый элемент.
Удаление OrgItem
Путь: DELETE /public-api/v1/org-items/{id}
Параметры пути:
| Параметр | Тип | Описание |
|---|---|---|
| id | UUID | Внутренний идентификатор |
Удаление по внешнему ID:
Путь: DELETE /public-api/v1/org-items/by-external-id/{externalId}
Структура ответа:
{
"deleted": true,
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"message": "OrgItem успешно удален"
}
Условия удаления:
- ✅ Элемент без связей можно удалить сразу
- ⚠️ Элемент с дочерними связями удаляется только после удаления всех связей
- ⚠️ Элемент с назначенными сотрудниками удаляется только после отзыва всех назначений
Каскадное удаление
Каскадное удаление не поддерживается.
Создание Person
Путь: POST /public-api/v1/persons
Структура запроса:
[
{
"externalId": "KOTOV_DG_001",
"email": "kotov@company.com",
"phone": "+7 (495) 123-45-67",
"firstName": "Дмитрий",
"lastName": "Котов",
"patronymic": "Георгиевич",
"photoUrl": "/userFiles/1.png"
}
]
Параметры запроса:
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| externalId | string | 📄 | Уникальный идентификатор во внешней системе |
string | 📄 | Электронная почта сотрудника | |
| phone | string | 📄 | Телефон сотрудника |
| firstName | string | ✅ | Имя сотрудника |
| lastName | string | 📄 | Фамилия сотрудника |
| patronymic | string | 📄 | Отчество сотрудника |
| photoUrl | string | 📄 | Ссылка на фотографию (через API загрузки файлов) |
Структура ответа:
{
"created": [
{
"id": "c3d4e5f6-g7h8-9012-cdef-345678901234",
"externalId": "KOTOV_DG_001",
"email": "kotov@company.com",
"phone": "+7 (495) 123-45-67",
"firstName": "Дмитрий",
"lastName": "Котов",
"patronymic": "Георгиевич",
"photoUrl": "https://company.com/photos/kotov.jpg"
}
],
"errors": []
}
Чтение Person
Путь: GET /public-api/v1/persons
Query-параметры:
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
| page | number | 📄 | Номер страницы (по умолчанию 0) |
| size | number | 📄 | Размер страницы (по умолчанию 20) |
string | 📄 | Фильтр по электронной почте |
Получение по ID:
Путь: GET /public-api/v1/persons/{id}
Параметры пути:
| Параметр | Тип | Описание |
|---|---|---|
| id | UUID | Внутренний идентификатор |
Получение по внешнему ID:
Путь: GET /public-api/v1/persons/by-external-id/{externalId}
Параметры пути:
| Параметр | Тип | Описание |
|---|---|---|
| externalId | string | Внешний идентификатор элемента |
Структура ответа:
{
"id": "c3d4e5f6-g7h8-9012-cdef-345678901234",
"externalId": "KOTOV_DG_001",
"email": "kotov@company.com",
"phone": "+7 (495) 123-45-67",
"firstName": "Дмитрий",
"lastName": "Котов",
"patronymic": "Георгиевич",
"photoUrl": "https://company.com/photos/kotov.jpg",
"assignedPositions": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"externalId": "CEO_POSITION_001",
"name": "Генеральный директор",
"type": "POSITION"
}
]
}
Обновление Person
Путь: PUT /public-api/v1/persons/{id}
Параметры пути:
| Параметр | Тип | Описание |
|---|---|---|
| id | UUID | Внутренний идентификатор |
Обновление по внешнему ID:
Путь: PUT /public-api/v1/persons/by-external-id/{externalId}
Структура запроса:
{
"email": "d.kotov@company.com",
"phone": "+7 (495) 987-65-43",
"firstName": "Дмитрий",
"lastName": "Котов",
"patronymic": "Георгиевич",
"photoUrl": "/photos/kotov_new.jpg"
}
Параметры запроса:
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
string | 📄 | Новая электронная почта | |
| phone | string | 📄 | Новый телефон |
| firstName | string | 📄 | Новое имя |
| lastName | string | 📄 | Новая фамилия |
| patronymic | string | 📄 | Новое отчество |
| photoUrl | string | 📄 | Новая ссылка на фотографию |
Удаление Person
Путь: DELETE /public-api/v1/persons/{id}
Параметры пути:
| Параметр | Тип | Описание |
|---|---|---|
| id | UUID | Внутренний идентификатор |
Удаление по внешнему ID:
Путь: DELETE /public-api/v1/persons/by-external-id/{externalId}
Структура ответа:
{
"deleted": true,
"id": "c3d4e5f6-g7h8-9012-cdef-345678901234",
"message": "Person успешно удален"
}
Условия удаления:
- ✅ Сотрудника без назначений можно удалить сразу
- ⚠️ Сотрудника с активными назначениями удаляется только после отзыва всех назначений
Важно
При удалении сотрудника не происходит автоматического удаления связанных OrgItemPersonEdge. Необходимо сначала удалить все назначения.
Создание OrgItemEdge
Путь: POST /public-api/v1/org-item-edges
Структура запроса:
[
{
"sourceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"targetId": "b2c3d4e5-f6g7-8901-bcde-f23456789012",
"externalSourceId": "CEO_POSITION_001",
"externalTargetId": "DEPUTY_CEO_001"
}
]
Параметры запроса:
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| sourceId | UUID | 📎 | Внутренний ID родительского элемента |
| targetId | UUID | 📎 | Внутренний ID дочернего элемента |
| externalSourceId | string | 📎 | Внешний ID родительского элемента |
| externalTargetId | string | 📎 | Внешний ID дочернего элемента |
Логика создания
Можно использовать либо внутренние ID (sourceId, targetId), либо внешние ID (externalSourceId, externalTargetId). При указании и внутренних, и внешних ID приоритет отдается внутренним.
Структура ответа:
{
"created": [
{
"id": "d4e5f6g7-h8i9-0123-defg-456789012345",
"sourceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"targetId": "b2c3d4e5-f6g7-8901-bcde-f23456789012",
"externalSourceId": "CEO_POSITION_001",
"externalTargetId": "DEPUTY_CEO_001",
"sourceItem": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Генеральный директор"
},
"targetItem": {
"id": "b2c3d4e5-f6g7-8901-bcde-f23456789012",
"name": "Заместитель генерального директора"
}
}
],
"errors": []
}
Чтение OrgItemEdge
Путь: GET /public-api/v1/org-item-edges
Query-параметры:
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
| page | number | 📄 | Номер страницы (по умолчанию 0) |
| size | number | 📄 | Размер страницы (по умолчанию 20) |
| sourceId | UUID | 📄 | Фильтр по родительскому элементу |
| targetId | UUID | 📄 | Фильтр по дочернему элементу |
| externalSourceId | string | 📄 | Фильтр по внешнему ID родителя |
Получение по ID:
Путь: GET /public-api/v1/org-item-edges/{id}
Параметры пути:
| Параметр | Тип | Описание |
|---|---|---|
| id | UUID | Внутренний идентификатор |
Структура ответа:
{
"id": "d4e5f6g7-h8i9-0123-defg-456789012345",
"sourceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"targetId": "b2c3d4e5-f6g7-8901-bcde-f23456789012",
"externalSourceId": "CEO_POSITION_001",
"externalTargetId": "DEPUTY_CEO_001",
"sourceItem": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"externalId": "CEO_POSITION_001",
"name": "Генеральный директор",
"type": "POSITION"
},
"targetItem": {
"id": "b2c3d4e5-f6g7-8901-bcde-f23456789012",
"externalId": "DEPUTY_CEO_001",
"name": "Заместитель генерального директора",
"type": "POSITION"
}
}
Обновление OrgItemEdge
Путь: PUT /public-api/v1/org-item-edges/{id}
Параметры пути:
| Параметр | Тип | Описание |
|---|---|---|
| id | UUID | Внутренний идентификатор |
Структура запроса:
{
"sourceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"targetId": "c3d4e5f6-g7h8-9012-cdef-345678901234",
"externalSourceId": "CEO_POSITION_001",
"externalTargetId": "HR_MANAGER_001"
}
Параметры запроса:
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| sourceId | UUID | 📎 | Новый ID родительского элемента |
| targetId | UUID | 📎 | Новый ID дочернего элемента |
| externalSourceId | string | 📎 | Новый внешний ID родителя |
| externalTargetId | string | 📎 | Новый внешний ID дочернего |
Удаление OrgItemEdge
Путь: DELETE /public-api/v1/org-item-edges/{id}
Параметры пути:
| Параметр | Тип | Описание |
|---|---|---|
| id | UUID | Внутренний идентификатор |
Удаление по связи:
Путь: DELETE /public-api/v1/org-item-edges/by-relation
Query-параметры:
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
| sourceId | UUID | 📎 | ID родительского элемента |
| targetId | UUID | 📎 | ID дочернего элемента |
| externalSourceId | string | 📎 | Внешний ID родительского |
| externalTargetId | string | 📎 | Внешний ID дочернего |
Структура ответа:
{
"deleted": true,
"id": "d4e5f6g7-h8i9-0123-defg-456789012345",
"message": "OrgItemEdge успешно удален"
}
Условия удаления:
- ✅ Связь можно удалить в любой момент
- ⚠️ При удалении связи дочерний элемент становится корневым (без родителя)
Важно
Удаление связи не удаляет сами элементы OrgItem. Удаляется только отношение подчиненности между ними.
Создание OrgItemPersonEdge
Путь: POST /public-api/v1/org-item-person-edges
Структура запроса:
[
{
"sourceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"personId": "c3d4e5f6-g7h8-9012-cdef-345678901234",
"externalSourceId": "CEO_POSITION_001",
"externalPersonId": "KOTOV_DG_001"
}
]
Параметры запроса:
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| sourceId | UUID | 📎 | Внутренний ID элемента оргструктуры |
| personId | UUID | 📎 | Внутренний ID сотрудника |
| externalSourceId | string | 📎 | Внешний ID элемента оргструктуры |
| externalPersonId | string | 📎 | Внешний ID сотрудника |
Логика создания
Можно использовать либо внутренние ID (sourceId, personId), либо внешние ID (externalSourceId, externalPersonId). При указании и внутренних, и внешних ID приоритет отдается внутренним.
Ограничения
Сотрудника можно назначить ТОЛЬКО на элемент с типом POSITION (должность). Назначение на группы (OU) не поддерживается.
Структура ответа:
{
"created": [
{
"id": "e5f6g7h8-i9j0-1234-efgh-567890123456",
"sourceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"personId": "c3d4e5f6-g7h8-9012-cdef-345678901234",
"externalSourceId": "CEO_POSITION_001",
"externalPersonId": "KOTOV_DG_001",
"orgItem": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Генеральный директор",
"type": "POSITION"
},
"person": {
"id": "c3d4e5f6-g7h8-9012-cdef-345678901234",
"firstName": "Дмитрий",
"lastName": "Котов",
"email": "kotov@company.com"
}
}
],
"errors": []
}
Чтение OrgItemPersonEdge
Путь: GET /public-api/v1/org-item-person-edges
Query-параметры:
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
| page | number | 📄 | Номер страницы (по умолчанию 0) |
| size | number | 📄 | Размер страницы (по умолчанию 20) |
| sourceId | UUID | 📄 | Фильтр по элементу оргструктуры |
| personId | UUID | 📄 | Фильтр по сотруднику |
| externalSourceId | string | 📄 | Фильтр по внешнему ID должности |
string | 📄 | Фильтр по email сотрудника |
Получение по ID:
Путь: GET /public-api/v1/org-item-person-edges/{id}
Параметры пути:
| Параметр | Тип | Описание |
|---|---|---|
| id | UUID | Внутренний идентификатор |
Структура ответа:
{
"id": "e5f6g7h8-i9j0-1234-efgh-567890123456",
"sourceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"personId": "c3d4e5f6-g7h8-9012-cdef-345678901234",
"externalSourceId": "CEO_POSITION_001",
"externalPersonId": "KOTOV_DG_001",
"orgItem": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"externalId": "CEO_POSITION_001",
"name": "Генеральный директор",
"type": "POSITION",
"description": "<p>Руководитель организации</p>",
"color": "#FF6B6B"
},
"person": {
"id": "c3d4e5f6-g7h8-9012-cdef-345678901234",
"externalId": "KOTOV_DG_001",
"firstName": "Дмитрий",
"lastName": "Котов",
"patronymic": "Георгиевич",
"email": "kotov@company.com",
"phone": "+7 (495) 123-45-67"
}
}
Обновление OrgItemPersonEdge
Путь: PUT /public-api/v1/org-item-person-edges/{id}
Параметры пути:
| Параметр | Тип | Описание |
|---|---|---|
| id | UUID | Внутренний идентификатор |
Структура запроса:
{
"sourceId": "b2c3d4e5-f6g7-8901-bcde-f23456789012",
"personId": "c3d4e5f6-g7h8-9012-cdef-345678901234",
"externalSourceId": "DEPUTY_CEO_001",
"externalPersonId": "KOTOV_DG_001"
}
Параметры запроса:
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| sourceId | UUID | 📎 | Новый ID элемента оргструктуры |
| personId | UUID | 📎 | Новый ID сотрудника |
| externalSourceId | string | 📎 | Новый внешний ID должности |
| externalPersonId | string | 📎 | Новый внешний ID сотрудника |
Удаление OrgItemPersonEdge
Путь: DELETE /public-api/v1/org-item-person-edges/{id}
Параметры пути:
| Параметр | Тип | Описание |
|---|---|---|
| id | UUID | Внутренний идентификатор |
Удаление по назначению:
Путь: DELETE /public-api/v1/org-item-person-edges/by-assignment
Query-параметры:
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
| sourceId | UUID | 📎 | ID элемента оргструктуры |
| personId | UUID | 📎 | ID сотрудника |
| externalSourceId | string | 📎 | Внешний ID должности |
| externalPersonId | string | 📎 | Внешний ID сотрудника |
Удаление всех назначений сотрудника:
Путь: DELETE /public-api/v1/org-item-person-edges/by-person
Query-параметры:
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
| personId | UUID | 📎 | ID сотрудника |
| externalPersonId | string | 📎 | Внешний ID сотрудника |
Структура ответа:
{
"deleted": true,
"id": "e5f6g7h8-i9j0-1234-efgh-567890123456",
"message": "OrgItemPersonEdge успешно удален"
}
Условия удаления:
- ✅ Назначение можно отозвать в любой момент
- ✅ При удалении всех назначений сотрудника он становится неназначенным
- ✅ При удалении назначения должность остается свободной
Важно
Удаление назначения не удаляет ни сотрудника, ни должность. Удаляется только связь между ними.
Рекомендуемые сценарии работы
Первичное создание организационной структуры
- Создать OrgItems (должности и группы)
- Создать OrgItemEdges (связи подчиненности)
- Создать Person (сотрудников)
- Создать OrgItemPersonEdge (назначения на должности)
Обновление атрибутов (без изменения связей)
- OrgItem/Person: обновление через соответствующий метод с
externalId
Обновление связей (OrgItemEdges, OrgItemPersonEdge)
- Убедиться, что необходимые
sourceId,targetId,personIdсозданы и актуальны - Обновить соответствующие связи
Удаление элементов структуры (OrgItem, Person)
- Удалить все связанные привязки
- Удалить OrgItem/Person
Удаление связей (OrgItemEdges, OrgItemPersonEdge)
- Удалить/изменить все зависимые привязки через
sourceId,targetId,personId - Удалить OrgItemEdges/OrgItemPersonEdge