REST API модуля «Корпоративный университет» (ithive.ipr)

Справочник REST-методов модуля ithive.ipr для интеграций, входящих вебхуков и AI-агентов.

Базовый URL

https://{портал}/rest/{user_id}/{webhook_code}/{method}.json
        

Пример:

https://portal.company.ru/rest/1/xxxxxxxx/ipr.ipr.list.json
        

Все методы имеют префикс ipr. (например, ipr.ipr.list, ipr.competency.get). Исключение — два служебных метода без вложенной сущности: ipr.currentUser и ipr.schema.

Scope и аутентификация

  • Scope: ipr
  • Аутентификация: входящий вебхук Bitrix24 или OAuth/сессия авторизованного пользователя с доступом к scope ipr
  • Все методы ipr.* требуют авторизованного пользователя REST. Без авторизации — ошибка UNAUTHORIZED. Часть методов дополнительно проверяет права на конкретную операцию и/или сущность (иначе PERMISSION_DENIED).

Авторизация ≠ право на операцию: доступ к модулю / наличие вебхука сами по себе не дают, например, право редактировать чужой ИПР или писать в справочники.

Для вызовов через сессию с cookie (без OAuth/app-токена) дополнительно требуется CSRF-токен (sessid) — это поведение стандартного REST-движка Bitrix (Bitrix\Main\Engine\ActionFilter\Csrf), а не самого модуля.

Роли и права доступа

Модуль не хранит отдельную REST-модель прав — используются существующие роли и группы модуля ithive.ipr (IPR\Rest\Support\AccessService).

Роли пользователя

Роль (role) Условие
admin Администратор портала
hr Участник группы HR-отдела
manager Не admin/HR, но имеет хотя бы одного подчинённого
employee Все остальные (по умолчанию)

Роль вычисляется по первому совпадению сверху вниз (AccessService::resolveRole). Узнать роль и доступные текущему пользователю флаги можно через GET ipr.currentUser.

Проверки доступа в коде

Проверка Кто проходит Используется в
isPrivileged() admin или hr Общий флаг «расширенного» доступа — обход большинства ограничений видимости и владения
canManageEmployee(actor, employeeId) Руководитель сотрудника (по оргструктуре) либо привилегированный Создание/апрув/реджект/реопен ИПР, запуск теста за сотрудника, mass-launch шаблонов
canManageCourse(courseId) Привилегированный или ACL курса (IPR\API\Course\Course::canManageCourse) CRUD курсов, уроков, тестов, вопросов
canManageCatalog() Привилегированный или группа «может управлять ИПР» (IPR\Action::checkUserIPRGroupOrAdmin) Запись компетенций, должностей, шаблонов программ, запуск/масс-запуск шаблонов
canAssignCourse() Привилегированный или группа «может назначать курсы» Не используется REST-методами напрямую (зарезервировано)
canAccessAnalytics() Привилегированный или отдельный доступ к аналитике ipr.analytics.course.list

Сводка по группам методов

Группа методов Кто может (как в коде)
Служебные (currentUser, schema) Любой авторизованный пользователь REST
ipr.ipr.list Авторизованный; выборка режется списком доступных ИПР (IPR\API\Ipr::getAllAvailableIprIds), кроме привилегированных
ipr.ipr.get Авторизованный; доступ проверяется на уровне элемента инфоблока (иначе NOT_FOUND)
ipr.ipr.add Актор создаёт себе (userId == actor) либо canManageEmployee(actor, userId) — руководитель по оргструктуре, группа ИПР/HR, администратор
ipr.ipr.draft.add Как ipr.ipr.add (черновик проходит те же проверки, карточка не создаётся)
ipr.ipr.draft.get Автор черновика либо привилегированный (admin/hr)
ipr.ipr.update Владелец с CAN_EDIT либо привилегированный; свободная смена status — только привилегированным (переходы статуса — через complete/approve/reject/reopen); startFact / finishFact — только администратор портала
ipr.ipr.delete Владелец с CAN_DELETE либо привилегированный; карточка в статусе FINISHED не удаляется никем
ipr.ipr.complete Сотрудник (сам), руководитель сотрудника или привилегированный
ipr.ipr.approve / reject Руководитель сотрудника (не сам сотрудник) или привилегированный; approve продвигает (NEW/SOGL → WORK) или останавливает (SOGL_RES → FINISHED) бизнес-процесс карточки
ipr.ipr.reopen Руководитель или привилегированный; реопен FINISHED — только привилегированным
ipr.ipr.status.list / ipr.ipr.type.list Любой авторизованный
ipr.action.list / get Доступ через родительский ИПР (как ipr.ipr.get)
ipr.action.add / update / delete Родительский ИПР должен быть editable (владелец или привилегированный); delete с force=true — только привилегированным. В update поля dateClosed, resourceId/actId, resourceType/type может менять только привилегированный или руководитель сотрудника — не владелец ИПР
ipr.action.type.list Любой авторизованный
ipr.event.section.list Любой авторизованный
ipr.event.list / get Авторизованный; видимость по правам инфоблока каталога (администратор и HR — всё); предложения (active=false) — только canEdit
ipr.event.add / update / date.add / date.delete canEdit каталога (администратор, HR или право element_edit на инфоблок); создание прошедшей даты проведения и notify=false в date.add — только администратор
ipr.event.delete canDelete каталога (администратор, HR или право section_delete на инфоблок)
ipr.competency.list / get / section.list Видимость по стандартным правам чтения инфоблока Bitrix; привилегированные видят без ограничений
ipr.competency.add / update / delete canManageCatalog()
ipr.competency.status.list Любой авторизованный (статический справочник active/inactive)
ipr.position.list / get Любой авторизованный
ipr.position.add / update / delete canManageCatalog()
ipr.programtemplate.list / get Любой авторизованный
ipr.programtemplate.add / update / delete canManageCatalog()
ipr.programtemplate.launch / masslaunch canManageCatalog() и canManageEmployee(actor, userId) на каждого целевого сотрудника
ipr.programtemplate.type.list Любой авторизованный
ipr.course.list / get По ACL обучения (CHECK_PERMISSIONS); привилегированные — без ограничений
ipr.course.review.list Любой авторизованный
ipr.course.review.add / delete Авторизованный — за себя; userId другого пользователя и date — только администратор портала
ipr.course.add canManageCourse(0) (общее право заводить курсы) или привилегированный
ipr.course.update / delete canManageCourse(courseId) или привилегированный
ipr.lesson.list / get По ACL обучения; привилегированные — без ограничений
ipr.lesson.add / update / delete / relation.update canManageCourse(courseId) или привилегированный
ipr.lesson.children.check Любой авторизованный (только чтение)
ipr.question.list По ACL обучения
ipr.question.get / add / update / delete canManageCourse курса, к которому относится урок вопроса (одного права на урок в модуле обучения недостаточно); привилегированные — без ограничений. Урок должен принадлежать дереву курса
ipr.test.list / get По ACL обучения (get — без дополнительной проверки владения)
ipr.test.add / update / delete canManageCourse(courseId) или привилегированный
ipr.test.attempt.start Только сам студент (userId == actor); руководитель или привилегированный запустить попытку за другого не может
ipr.test.attempt.answer / finish Сам пользователь (userId == actor) либо canManageEmployee(actor, userId); dateStart, dateEnd и notify=false — только администратор портала
ipr.test.attempt.list Привилегированный видит все; иначе — только свои попытки (или попытки управляемых сотрудников при явном filter.userId)
ipr.test.result.get Сам пользователь, canManageEmployee, либо привилегированный
ipr.employee.get Сам сотрудник либо canManageEmployee(actor, userId)
ipr.employee.update Только администратор портала
ipr.point.list Право просмотра карточки (как ipr.ipr.get)
ipr.point.set Руководитель карточки (CUR_MANAGER) — оценка руководителя; владелец в статусе WORK — самооценка; администратор — любая роль (обязателен role); date и notify=false — только администратор
ipr.history.list / get Привилегированный — все записи; иначе — только записи по доступным ИПР
ipr.analytics.course.list canAccessAnalytics()

Параметры «только администратор»

Даты и режимы, нужные для переноса и демонстрационных данных (startFact, finishFact, dateStart, dateEnd, date, notify=false, а также создание даты проведения в прошлом в ipr.event.date.add и прошедшая дата проведения в eventId у ipr.action.add / update и в competenceRunOptions у ipr.ipr.add), доступны только администратору портала. Если такой параметр прислал не администратор, метод возвращает PERMISSION_DENIED — параметр не игнорируется молча. Формат дат: YYYY-MM-DD или YYYY-MM-DD HH:MM:SS (время сервера), для dateStart / dateEnd / date — не в будущем. Даты проведения мероприятий — ISO 8601 со смещением часового пояса.

В шапках отдельных методов формулировка «Кто может вызывать» даёт краткий итог; детали — в этом разделе.

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

Единый конверт модуля (Vibe API, IPR\Rest\ApiResponse) — вложен в стандартную обёртку Bitrix REST (result, time):

Поле Описание
result Данные метода или null при ошибке
total Количество записей (для list-методов), иначе null
next Смещение следующей страницы, иначе null
error null или { code, message, details }

При внутренней ошибке (INTERNAL_ERROR) message всегда равно Internal error, а причина передаётся в details.reason; подробности пишутся только в журнал сервера. Сообщения VALIDATION_ERROR, NOT_FOUND и PERMISSION_DENIED не меняются. Подробнее: Коды ошибок.

Пагинация

Для list-методов (IPR\Rest\Dto\ListParams, IPR\Rest\Pagination):

Параметр По умолчанию Описание
limit 50 Размер страницы, максимум 500
offset 0 Смещение
fetchAll false Вернуть все записи одним ответом. Максимум 5000 записей; если подходящих больше — ошибка FETCH_ALL_LIMIT_EXCEEDED
filter - Mongo-style фильтр

Булево fetchAll принимается как true / 1 / "y" / "yes" (без учёта регистра) — так же, как и другие булевы параметры методов.

Фильтрация (Mongo-style)

filter — объект { поле: значение } или { поле: { $оператор: значение } } (IPR\Rest\Filter\MongoFilter).

Поддерживаемые операторы: $eq, $ne, $gt, $gte, $lt, $lte, $in, $nin.

  • $in / $nin требуют непустой массив значений — иначе INVALID_FILTER.
  • Неизвестный оператор (не из списка выше) — INVALID_FILTER_OPERATOR.
  • Значение $in/$nin, переданное не массивом (например, через query-строку), автоматически оборачивается в массив из одного элемента.
  • filter можно передать и JSON-строкой — она будет разобрана автоматически.
  • Допустимы только поля из раздела «Поля filter» конкретного метода. Неизвестное поле — INVALID_FILTER (details.field).
  • Для методов обучения (course, lesson, test) проверка прав (CHECK_PERMISSIONS) задаётся сервером и не переопределяется через filter: N для привилегированных, Y для остальных.

Пример: filter[status][$eq]=WORK, filter[userId][$in][]=8&filter[userId][$in][]=14.

Список доступных полей фильтра указан на странице каждого *.list-метода.

Разделы REST-справочника

Раздел Описание
Служебные endpoint'ы ipr.currentUser, ipr.schema
ИПР Карточки ИПР/ПИС: список, создание, жизненный цикл, справочники статусов и типов
Действия ИПР Действия по компетенциям внутри ИПР
Каталог мероприятий Категории, мероприятия и даты проведения (события календаря)
Компетенции Каталог компетенций, разделы, статусы
Должности Каталог должностей
Шаблоны программ Шаблоны ИПР/ПИС, запуск и масс-запуск на сотрудников
Сотрудники Профиль развития сотрудника: должность, компетенции, сроки
Оценки компетенций Самооценка и оценка руководителя по компетенциям ИПР
Курсы Курсы обучения, отзывы и рейтинг
Уроки Уроки курса, дерево уроков
Вопросы Вопросы и варианты ответов для тестов
Тесты Тесты, попытки прохождения, результаты
История История изменений по карточкам ИПР
Аналитика Агрегаты по прохождению курсов

См. также