H-3657: задокументировал user-list-cache (источник usersListKey)
Без этого интегратор не понимает откуда взять usersListKey для
POST /admin/wallet-transaction/create.
- Тег user-list-cache (Methods for caching ad-hoc employee selections...).
- POST /user-list-cache/set-user-list: тело {key, userList:{usersId,...}}.
В описании явно прописал что Content-Type обязательно application/json —
через form-urlencoded вложенный JsonModel не парсится, и сервер
молча сохраняет пустую выборку (грабли которые я сам и наступил
во время smoke-теста).
- GET /user-list-cache/user-list-data?key=<key>: возвращает развёрнутую
выборку (users, departments, userGroups, ...). Схема ответа проверена
живьём на denis.hrbox.io — все ключи совпадают.
- Схемы UserListForm, UserListCacheSetBody, UserListData.
- В описании POST /admin/wallet-transaction/create добавил секцию
«Как получить usersListKey» с пошаговым флоу и ссылкой.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+210
-5
@@ -69,6 +69,8 @@ tags:
|
|||||||
description: Methods for admin wallet transactions — manual and excel-based credit/debit.
|
description: Methods for admin wallet transactions — manual and excel-based credit/debit.
|
||||||
- name: file-processing
|
- name: file-processing
|
||||||
description: Methods for polling async file processing (excel import/export, archives). Scoped to current user's files.
|
description: Methods for polling async file processing (excel import/export, archives). Scoped to current user's files.
|
||||||
|
- name: user-list-cache
|
||||||
|
description: Methods for caching ad-hoc employee selections to pass to mass operations (e.g. wallet credit/debit).
|
||||||
- name: user-api-token
|
- name: user-api-token
|
||||||
description: Methods for managing personal API tokens (PATs) for server-to-server access. Requires "api-tokens-manage" permission.
|
description: Methods for managing personal API tokens (PATs) for server-to-server access. Requires "api-tokens-manage" permission.
|
||||||
- name: admin-user-api-token
|
- name: admin-user-api-token
|
||||||
@@ -7114,12 +7116,27 @@ paths:
|
|||||||
tags: [admin-wallet-transaction]
|
tags: [admin-wallet-transaction]
|
||||||
summary: Провести начисление/списание по форме
|
summary: Провести начисление/списание по форме
|
||||||
description: |
|
description: |
|
||||||
Массовая операция через `usersListKey` (ключ закэшированной выборки сотрудников).
|
Массовая операция по выборке сотрудников. Запускается асинхронно
|
||||||
Запускается асинхронно через launcher.
|
через launcher — баланс и история транзакций обновятся в течение
|
||||||
|
нескольких секунд.
|
||||||
|
|
||||||
Soft-error состояния возвращаются в `message.type=warning`:
|
### Как получить `usersListKey`
|
||||||
- "Укажите сотрудников" — выборка пустая
|
|
||||||
- "Невозможно провести транзакцию, у некоторых сотрудников недостаточно средств..." — debit, не хватает баланса (имена в тексте)
|
1. `POST /api/v2/user-list-cache/set-user-list` с телом
|
||||||
|
`{key, userList:{usersId:[...]}}` — кэширует выборку под вашим
|
||||||
|
ключом (TTL 24 часа).
|
||||||
|
2. Этот же `key` отдаёте здесь как `usersListKey`.
|
||||||
|
|
||||||
|
Подробности и пример — в описании метода `set-user-list`.
|
||||||
|
|
||||||
|
### Soft-error состояния (`200 OK` + `message.type=warning`)
|
||||||
|
|
||||||
|
- `"Укажите сотрудников"` — выборка по `usersListKey` пустая
|
||||||
|
(ключ протух, не существует или userList отдали через form-urlencoded —
|
||||||
|
см. `set-user-list`).
|
||||||
|
- `"Невозможно провести транзакцию, у некоторых сотрудников
|
||||||
|
недостаточно средств на балансе: <имена>"` — debit, не хватает
|
||||||
|
баланса хотя бы у одного юзера; вся операция отменяется.
|
||||||
operationId: adminWalletTransactionCreate
|
operationId: adminWalletTransactionCreate
|
||||||
requestBody:
|
requestBody:
|
||||||
required: true
|
required: true
|
||||||
@@ -7271,6 +7288,93 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/FileProcessing'
|
$ref: '#/components/schemas/FileProcessing'
|
||||||
|
|
||||||
|
/user-list-cache/set-user-list:
|
||||||
|
post:
|
||||||
|
tags: [user-list-cache]
|
||||||
|
summary: Закэшировать выборку сотрудников и получить ключ
|
||||||
|
description: |
|
||||||
|
Кэширует произвольную выборку сотрудников (по `usersId`,
|
||||||
|
`departmentsId`, `userGroupsId`, динамическим условиям и т.д.)
|
||||||
|
и связывает её с переданным `key`. Дальше этот `key` можно
|
||||||
|
отдавать в массовые операции — например в
|
||||||
|
`POST /api/v2/admin/wallet-transaction/create` как `usersListKey`.
|
||||||
|
|
||||||
|
Ключ хранится в кеше **сутки** (60 × 1440 секунд). Повторный
|
||||||
|
вызов с тем же `key` перетирает выборку.
|
||||||
|
|
||||||
|
### ⚠️ Content-Type обязательно `application/json`
|
||||||
|
|
||||||
|
Поле `userList` — это вложенный JSON-объект (см. схему
|
||||||
|
`UserListForm`). Через `application/x-www-form-urlencoded`
|
||||||
|
кастомный `Model::setAttributes` не парсит вложенные JSON-модели,
|
||||||
|
и сервер сохранит **пустую** выборку. Внешне ответ будет
|
||||||
|
`{success:true}`, но при попытке провести транзакцию вы получите
|
||||||
|
`{type:"warning", text:"Укажите сотрудников"}`. Только JSON.
|
||||||
|
|
||||||
|
### Пример
|
||||||
|
|
||||||
|
```json
|
||||||
|
POST /api/v2/user-list-cache/set-user-list
|
||||||
|
Content-Type: application/json
|
||||||
|
Authorization: Bearer hrb_...
|
||||||
|
|
||||||
|
{
|
||||||
|
"key": "my-integration-key-2026-05-22",
|
||||||
|
"userList": {
|
||||||
|
"usersId": ["25840ad3-a07f-4893-aa70-3a696b79a6f1"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`key` придумываете сами (до 50 символов).
|
||||||
|
operationId: userListCacheSet
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/UserListCacheSetBody'
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: |
|
||||||
|
Успех (`data: true`) или ошибки валидации в стандартном формате
|
||||||
|
`httpJsonResponse`.
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/httpJsonResponse'
|
||||||
|
|
||||||
|
/user-list-cache/user-list-data:
|
||||||
|
get:
|
||||||
|
tags: [user-list-cache]
|
||||||
|
summary: Получить состав закэшированной выборки сотрудников
|
||||||
|
description: |
|
||||||
|
Возвращает развёрнутый состав выборки по ключу: список пользователей
|
||||||
|
(`users`), список подразделений (`departments`), список групп
|
||||||
|
(`userGroups`), исходную форму (`userList`), нормализованные
|
||||||
|
условия групп и т.д. Полезно для preview перед массовой операцией.
|
||||||
|
|
||||||
|
Если ключ протух (24 ч) или не существует — `userList` будет
|
||||||
|
пустым, остальные коллекции — пустыми массивами.
|
||||||
|
operationId: userListCacheData
|
||||||
|
parameters:
|
||||||
|
- name: key
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
schema: { type: string, maxLength: 50 }
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Данные выборки
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/httpJsonResponse'
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
$ref: '#/components/schemas/UserListData'
|
||||||
|
|
||||||
/user-api-token:
|
/user-api-token:
|
||||||
get:
|
get:
|
||||||
tags: [user-api-token]
|
tags: [user-api-token]
|
||||||
@@ -12521,6 +12625,107 @@ components:
|
|||||||
_meta:
|
_meta:
|
||||||
$ref: '#/components/schemas/_meta'
|
$ref: '#/components/schemas/_meta'
|
||||||
|
|
||||||
|
UserListForm:
|
||||||
|
type: object
|
||||||
|
description: |
|
||||||
|
Описание выборки сотрудников. Все поля опциональны — указывайте те,
|
||||||
|
которыми хотите задать состав. Условия объединяются через OR
|
||||||
|
(любой из критериев включает юзера).
|
||||||
|
properties:
|
||||||
|
usersId:
|
||||||
|
type: array
|
||||||
|
description: Явный список UUID сотрудников.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
departmentsId:
|
||||||
|
type: array
|
||||||
|
description: UUID подразделений. Включает всех сотрудников этих подразделений.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
isDepartmentRecursive:
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
description: Если `true` — захватывает сотрудников вложенных подразделений тоже.
|
||||||
|
userGroupsId:
|
||||||
|
type: array
|
||||||
|
description: UUID статических групп сотрудников.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
userGroupConditions:
|
||||||
|
type: array
|
||||||
|
description: |
|
||||||
|
Динамические условия выборки (как в админке UserGroup). Каждый
|
||||||
|
элемент — объект `{condition, operator, values}`.
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
employmentStatuses:
|
||||||
|
type: array
|
||||||
|
description: Фильтр по статусам трудоустройства.
|
||||||
|
items:
|
||||||
|
type: integer
|
||||||
|
fileProcessingId:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
nullable: true
|
||||||
|
description: UUID `FileProcessing` с распарсенным xlsx — выборка возьмётся оттуда.
|
||||||
|
|
||||||
|
UserListCacheSetBody:
|
||||||
|
type: object
|
||||||
|
required: [key, userList]
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
type: string
|
||||||
|
maxLength: 50
|
||||||
|
description: |
|
||||||
|
Произвольный идентификатор выборки. Этот же ключ потом передаётся
|
||||||
|
как `usersListKey` в массовые операции.
|
||||||
|
example: "my-integration-2026-05-22"
|
||||||
|
userList:
|
||||||
|
$ref: '#/components/schemas/UserListForm'
|
||||||
|
|
||||||
|
UserListData:
|
||||||
|
type: object
|
||||||
|
description: |
|
||||||
|
Развёрнутый состав выборки. Возвращается `GET /user-list-cache/user-list-data`.
|
||||||
|
properties:
|
||||||
|
userList:
|
||||||
|
$ref: '#/components/schemas/UserListForm'
|
||||||
|
users:
|
||||||
|
type: array
|
||||||
|
description: Развёрнутые юзеры из выборки (с `faceUrl`).
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
departments:
|
||||||
|
type: array
|
||||||
|
description: Развёрнутые подразделения.
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
userGroups:
|
||||||
|
type: array
|
||||||
|
description: Развёрнутые группы.
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
userGroupConditions:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
userGroupConditionsReadable:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
userGroupConditionValues:
|
||||||
|
type: array
|
||||||
|
nullable: true
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
fileProcessing:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/FileProcessing'
|
||||||
|
nullable: true
|
||||||
|
|
||||||
UserApiTokenStatus:
|
UserApiTokenStatus:
|
||||||
type: integer
|
type: integer
|
||||||
description: |
|
description: |
|
||||||
|
|||||||
Reference in New Issue
Block a user