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) |
ipr.ipr.update |
Владелец с CAN_EDIT либо привилегированный; свободная смена status — только привилегированным (переходы статуса — через complete/approve/reject/reopen) |
ipr.ipr.delete |
Владелец с CAN_DELETE либо привилегированный; карточка в статусе FINISHED не удаляется никем |
ipr.ipr.complete |
Сотрудник (сам), руководитель сотрудника или привилегированный |
ipr.ipr.approve / reject |
Руководитель сотрудника (не сам сотрудник) или привилегированный |
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 — только привилегированным |
ipr.action.type.list |
Любой авторизованный |
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.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 / answer / finish |
Сам пользователь (userId == actor) либо canManageEmployee(actor, userId) |
ipr.test.attempt.list |
Привилегированный видит все; иначе — только свои попытки (или попытки управляемых сотрудников при явном filter.userId) |
ipr.test.result.get |
Сам пользователь, canManageEmployee, либо привилегированный |
ipr.history.list / get |
Привилегированный — все записи; иначе — только записи по доступным ИПР |
ipr.analytics.course.list |
canAccessAnalytics() |
В шапках отдельных методов формулировка «Кто может вызывать» даёт краткий итог; детали — в этом разделе.
Формат ответа
Единый конверт модуля (Vibe API, IPR\Rest\ApiResponse) — вложен в стандартную обёртку Bitrix REST (result, time):
| Поле | Описание |
|---|---|
result |
Данные метода или null при ошибке |
total |
Количество записей (для list-методов), иначе null |
next |
Смещение следующей страницы, иначе null |
error |
null или { code, message, details } |
Пагинация
Для 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[status][$eq]=WORK, filter[userId][$in][]=8&filter[userId][$in][]=14.
Список доступных полей фильтра указан на странице каждого *.list-метода.
Разделы REST-справочника
| Раздел | Описание |
|---|---|
| Служебные endpoint'ы | ipr.currentUser, ipr.schema |
| ИПР | Карточки ИПР/ПИС: список, создание, жизненный цикл, справочники статусов и типов |
| Мероприятия | Мероприятия по компетенциям внутри ИПР |
| Компетенции | Каталог компетенций, разделы, статусы |
| Должности | Каталог должностей |
| Шаблоны программ | Шаблоны ИПР/ПИС, запуск и масс-запуск на сотрудников |
| Курсы | Курсы обучения |
| Уроки | Уроки курса, дерево уроков |
| Вопросы | Вопросы и варианты ответов для тестов |
| Тесты | Тесты, попытки прохождения, результаты |
| История | История изменений по карточкам ИПР |
| Аналитика | Агрегаты по прохождению курсов |