diff --git a/v2/swagger.yaml b/v2/swagger.yaml index c29476c..f4353f0 100644 --- a/v2/swagger.yaml +++ b/v2/swagger.yaml @@ -73,6 +73,8 @@ tags: description: Methods for managing personal API tokens (PATs) for server-to-server access. Requires "api-tokens-manage" permission. - name: admin-user-api-token description: Methods for admin oversight of personal API tokens. Requires "api-tokens-admin" permission. + - name: admin-employment + description: Methods for admin read-only access to employee employments — primary source of origin_id ↔ user_id mapping for integrations. Requires "user-edit" permission. paths: /mobile/bind/{id}/{token}: @@ -7529,6 +7531,177 @@ paths: 404: description: Токен не найден. + /admin/employment: + get: + tags: [admin-employment] + summary: Список трудоустройств — admin read-only + description: | + Постраничный список трудоустройств всего тенанта с фильтрами + `EmploymentSearch`. Поведением и набором полей идентичен + legacy-эндпоинту `/api/employment` (v1) — перенесён в v2 как + основа для интеграций (web-zaim, sokolove и др.) и будущей + Vue3-админки. + + ### Главный кейс — маппинг (origin_id, origin_organization_id) → user_id + + ``` + GET /api/v2/admin/employment + ?origin_id=12345 + &origin_organization_id=default + ``` + + В ответе `data[].user_id` — это родной HRBox UUIDv4 пользователя, + который дальше можно передавать в любые v2-эндпоинты, ожидающие + `user_id`. Поддерживается батч: `?origin_id[]=...&origin_id[]=...`. + + ### Совместительства + + Один пользователь может иметь несколько трудоустройств с разными + `origin_id`. Поле `is_main` отличает основное от дополнительных. + + ### Уволенные + + Записи с `fired_date != null` включены по умолчанию — нужны для + синхронизации увольнений. Если нужны только активные — + фильтруйте `status_id=1`. + operationId: adminEmploymentIndex + parameters: + - name: page + in: query + schema: { type: integer, minimum: 1, default: 1 } + - name: per-page + in: query + schema: { type: integer, minimum: 1, default: 20 } + - name: sort + in: query + schema: { type: string } + description: 'Префикс `-` для DESC. Атрибуты — `created_at`, `employment_date`, `fired_date`, и др. (по `EmploymentSearch::sort`).' + - name: id + in: query + schema: { type: string, format: uuid } + - name: user_id + in: query + schema: + oneOf: + - type: string + format: uuid + - type: array + items: { type: string, format: uuid } + description: 'UUID юзера. Массив через `?user_id[]=...&user_id[]=...` или comma-separated.' + - name: chief_id + in: query + schema: { type: string, format: uuid } + description: UUID employment'а руководителя. + - name: department_id + in: query + schema: { type: string, format: uuid } + description: UUID подразделения (с автоматическим учётом поддерева). + - name: origin_id + in: query + schema: + oneOf: + - type: string + - type: array + items: { type: string } + description: Внешний ID (например из 1С). Comma-separated или массив. + - name: origin_organization_id + in: query + schema: { type: string } + description: Идентификатор организации во внешней системе (для мульти-org тенантов). + - name: org_num + in: query + schema: { type: string } + description: Comma-separated табельные номера. + - name: first_name + in: query + schema: { type: string } + description: ilike-поиск. + - name: last_name + in: query + schema: { type: string } + description: ilike-поиск. + - name: name + in: query + schema: { type: string } + description: ilike по `first_name` + `last_name` через JOIN User. + - name: position + in: query + schema: { type: string } + description: ilike-поиск по должности. + - name: is_main + in: query + schema: { type: boolean } + description: Только основные трудоустройства. + - name: status_id + in: query + schema: { type: integer } + description: 'Стандартный enum `Status` (1=Active, 2=Disabled).' + - name: reg_status_id + in: query + schema: { type: string } + description: Comma-separated `RegStatus` (1=NO_ACCOUNT, 2=INVITED, 3=ACTIVE, 4=BLOCKED) — фильтр по статусу владельца. + - name: created_at + in: query + schema: { type: string } + description: 'Диапазон `from|to` (ISO).' + - name: employment_date + in: query + schema: { type: string } + description: 'Диапазон даты приёма `from|to`.' + - name: fired_date + in: query + schema: { type: string } + description: 'Диапазон даты увольнения `from|to`.' + - name: user_list_key + in: query + schema: { type: string, format: uuid } + description: 'Ключ закэшированной выборки сотрудников (см. `/user-list-cache/set-user-list`).' + - name: chief_only + in: query + schema: { type: boolean } + description: Только прямые подчинённые текущего юзера. + - name: chief_only_all + in: query + schema: { type: boolean } + description: Все подчинённые рекурсивно. + - name: multipleEmployment + in: query + schema: { type: boolean } + description: Только записи юзеров с несколькими трудоустройствами. + responses: + 200: + description: Список трудоустройств + content: + application/json: + schema: + $ref: '#/components/schemas/AdminEmploymentList' + 403: + description: Нет права `user-edit`. + + /admin/employment/view: + get: + tags: [admin-employment] + summary: Одно трудоустройство — admin read-only + operationId: adminEmploymentView + parameters: + - name: id + in: query + required: true + schema: { type: string, format: uuid } + responses: + 200: + description: Трудоустройство + content: + application/json: + schema: + $ref: '#/components/schemas/AdminEmployment' + 400: + description: Невалидный UUID. + 403: + description: Нет права `user-edit`. + 404: + description: Запись не найдена (включая cross-tenant). + components: securitySchemes: SessionAuth: @@ -12647,6 +12820,147 @@ components: _meta: $ref: '#/components/schemas/_meta' + AdminEmploymentUserShort: + type: object + properties: + id: { type: string, format: uuid } + name: { type: string, nullable: true } + faceUrl: { type: string, format: uri, nullable: true } + + AdminEmploymentChiefUserShort: + type: object + properties: + id: { type: string, format: uuid } + name: { type: string, nullable: true } + + AdminEmploymentDepartmentShort: + type: object + properties: + id: { type: string, format: uuid } + name: { type: string, nullable: true } + departmentPath: + type: string + nullable: true + description: 'Полный путь от корня структуры через `/`.' + + AdminEmployment: + type: object + description: | + Запись трудоустройства в admin-выдаче. Содержит как сырые поля + Employment, так и связанные `user` / `chiefUser` / `department`. + properties: + id: + type: string + format: uuid + description: UUID трудоустройства (родной HRBox). + is_main: + type: boolean + description: Основное трудоустройство (одно на юзера). Несколько `false` — совместительства. + user_id: + type: string + format: uuid + description: UUID владельца (`hr_user.id`) — **то самое значение для маппинга origin → user**. + chief_id: + type: string + format: uuid + nullable: true + description: UUID employment'а руководителя (не User'а). + department_id: + type: string + format: uuid + nullable: true + position: + type: string + nullable: true + employment_date: + type: string + nullable: true + description: Дата приёма (ISO). + fired_date: + type: string + nullable: true + description: Дата увольнения (ISO). `null` для действующих. + status_id: + type: integer + nullable: true + description: 'Стандартный `Status` (1=Active, 2=Disabled).' + origin_id: + type: string + nullable: true + description: Внешний идентификатор должности из системы-источника (1С и т.п.). + origin_organization_id: + type: string + nullable: true + description: Идентификатор внешней организации. Маппинг — это **пара** `(origin_id, origin_organization_id)`. + org_num: + type: string + nullable: true + description: Табельный номер. + first_name: { type: string, nullable: true } + last_name: { type: string, nullable: true } + photo: + type: string + nullable: true + description: Имя файла фото из источника (если приходит из интеграции). + created_at: { type: string, nullable: true } + updated_at: { type: string, nullable: true } + experience: + type: string + nullable: true + description: 'Стаж в человекочитаемом виде (например `15 years 3 months 19 days`).' + name: + type: string + nullable: true + description: Готовая строка ФИО юзера-владельца. + nameDetails: + type: string + nullable: true + iconUrl: + type: string + format: uri + nullable: true + profilePosition: + type: string + nullable: true + user: + $ref: '#/components/schemas/AdminEmploymentUserShort' + chiefUser: + allOf: + - $ref: '#/components/schemas/AdminEmploymentChiefUserShort' + nullable: true + department: + allOf: + - $ref: '#/components/schemas/AdminEmploymentDepartmentShort' + nullable: true + createdAt: + type: string + nullable: true + description: 'Локализованная `created_at`.' + employmentDate: + type: string + nullable: true + description: 'Локализованная `employment_date`.' + firedDate: + type: string + nullable: true + description: 'Локализованная `fired_date`.' + statusName: + type: string + nullable: true + description: 'Локализованное имя статуса.' + + AdminEmploymentList: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/AdminEmployment' + _links: + $ref: '#/components/schemas/_links' + _meta: + $ref: '#/components/schemas/_meta' + parameters: boardDateTypeParam: in: query