Как добавить сотрудника через API?
POST /v1/employees создаёт сотрудника. Обязательные поля body: email, name, surname, gender и active. Для доступа нужен
scope employees.write.
Endpoint
| Параметр | Значение | | -------------- | ---------------------------------------------------- | | Method | POST | |
Path | /v1/employees | | Base URL | https://smartway.pro/api | | Auth | Bearer token | | Required scope |
employees.write |
Назначение
Endpoint используется для создания нового сотрудника в рамках компании из Bearer token.
Значение active управляет не только бизнес-флагом, но и созданием или отсутствием связанного пользователя в Keycloak.
Предусловия
- Клиент должен передать валидный Bearer token.
- Token должен содержать company context.
- Token должен содержать scope employees.write.
- idCompany не передаётся в body или query string.
- hrEmail не передаётся внешним клиентом; BFF берёт его из Bearer token.
- В текущей реализации Idempotency-Key не используется.
Запрос
Body parameters
| Поле | Тип | Обязательное | Описание | | ----------- | -------- | ---------------- |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| | email | string | да | Email сотрудника. | | name | string | да | Имя сотрудника. Это source of truth для
формирования fullName при создании. | | surname | string | да | Фамилия сотрудника. Это source of truth для
формирования fullName при создании. | | gender | string | да | Допустимы только значения Male или Female. | | active |
boolean | да | Допустимы только JSON-boolean значения true или false. true создаёт или синхронизирует доступ к личному
кабинету через Keycloak; false создаёт сотрудника без такого доступа. | | department | string | нет | Основной
департамент. Если не передать, сохраняется null. | | departments | string[] | нет | Набор департаментов. Если не
передать, коллекция остаётся пустой. | | jobTitle | string | нет | Основная должность. Если не передать, сохраняется
null. | | jobTitles | string[] | нет | Набор должностей. Если не передать, коллекция остаётся пустой. | | phone | string
| нет | Телефон. Если не передать, сохраняется null. | | notes | string | нет | Примечания. Если не передать,
сохраняется null. |
curl пример
Создать сотрудника с primary-полями и массивами
curl -X POST 'https://smartway.pro/api/v1/employees' \
-H 'Authorization: Bearer <access_token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
--data-binary @- <<'JSON'
{
"email": "employee@example.com",
"name": "Иван",
"surname": "Петренко",
"gender": "Female",
"active": false,
"department": "Управление",
"departments": ["КЛ"],
"jobTitle": "Менеджер",
"jobTitles": ["Координатор"],
"phone": "+380000000000",
"notes": "Новый сотрудник public API"
}
JSON
Создать сотрудника только с массивами departments/jobTitles
curl -X POST 'https://smartway.pro/api/v1/employees' \
-H 'Authorization: Bearer <access_token>' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
--data-binary @- <<'JSON'
{
"email": "employee@example.com",
"name": "Иван",
"surname": "Петренко",
"gender": "Male",
"active": true,
"departments": ["Управление", "КЛ"],
"jobTitles": ["Менеджер", "Координатор"],
"phone": "+380000000000",
"notes": "Новый сотрудник public API"
}
JSON
Ответ
Успешный ответ: 201 Created. Возвращает созданный Employee.
{
"employeeId": 4432,
"candidateId": 10748,
"email": "employee@example.com",
"fullName": "Иван Петренко",
"name": "Иван",
"surname": "Петренко",
"gender": "Female",
"department": "Управление",
"departments": [
"КЛ",
"Управление"
],
"jobTitle": "Менеджер",
"jobTitles": [
"Координатор",
"Менеджер"
],
"phone": "+380000000000",
"active": false
}
Поля ответа
Employee
| Поле | Тип | Описание | | ----------- | -------- | ------------------------------------------------------- | |
employeeId | int64 | ID сотрудника. | | candidateId | int64 | ID связанного кандидата. | | email | string | Email
сотрудника. | | fullName | string | Полное имя, которое сервер формирует из name + surname. | | name | string |
Имя. | | surname | string | Фамилия. | | gender | string | Пол. | | department | string | Основной департамент. | |
departments | string[] | Набор департаментов. | | jobTitle | string | Основная должность. | | jobTitles | string[] |
Набор должностей. | | phone | string | Телефон. | | active | boolean | Признак активности. |
Бизнес-логика
- BFF определяет companyId только из Bearer token.
- BFF берёт hrEmail из Bearer token. hrEmail равен email пользователя с ролью HRADMIN, который создал или ротировал
активный API key компании.
- Если активный API key будет ротирован другим HRADMIN, следующие create-операции автоматически начнут использовать
его hrEmail.
- Повторный одинаковый POST не создаёт дубль, если уже существует employee с таким же email; API возвращает 409
Conflict.
- gender принимает только Male или Female.
- active принимает только JSON-boolean true или false.
- active = true создаёт или синхронизирует связанный пользовательский аккаунт в Keycloak и открывает доступ к личному
кабинету.
- active = false создаёт сотрудника без доступа к личному кабинету, то есть без пользователя в Keycloak.
- fullName в ответе формируется сервером из name + surname.
- Если передан только departments или jobTitles, первый элемент массива становится primary-значением в department или
jobTitle.
- Если передано и одиночное поле, и массив, одиночное поле имеет приоритет как primary, а массив дополняется
уникальными значениями.
- Если department, jobTitle, phone или notes не переданы, в соответствующих одиночных полях сохраняется null.
- Если departments или jobTitles не переданы, соответствующие коллекции остаются пустыми.
- В ответе departments и jobTitles возвращаются в стабильно отсортированном виде.
Edge cases
Edge cases
| Сценарий | Поведение API | | ----------------------------------------- |
--------------------------------------------------------------------------------------- | | Отсутствует required-поле |
API возвращает 400 Bad Request. | | gender имеет значение не Male и не Female | API возвращает 400 Bad Request с
пояснением. | | active передан строкой или числом | API возвращает 400 Bad Request, потому что active должен
быть JSON-boolean. | | email уже существует | API возвращает 409 Conflict. | | Передан только departments | Первый
элемент массива становится department. | | Переданы department и departments | department остаётся primary, а
departments дополняется уникальными значениями. | | Не передан department или jobTitle | В соответствующем одиночном
поле сохраняется null. | | Не передан departments или jobTitles | Соответствующая коллекция остаётся пустой. | |
Клиент передаёт fullName | В create request поле fullName не описано. Сервер формирует fullName из name + surname. |
Ошибки
Error responses
| HTTP status | Когда возникает | | ------------------------- |
----------------------------------------------------------------------------------- | | 400 Bad Request | Отсутствует
хотя бы один required-параметр email, name, surname, gender или active. | | 400 Bad Request | gender не равен Male
или Female. | | 400 Bad Request | active не является JSON-boolean значением true или false. | | 401 Unauthorized |
Bearer token отсутствует или невалиден. | | 403 Forbidden | Недостаточно прав или token без company context. | | 409
Conflict | Employee с таким email уже существует. | | 500 Internal Server Error | Неожиданная ошибка BFF. | | 503
Service Unavailable | Сбой внутренней интеграции BFF -> back2. |
Использование
- Создать активного сотрудника с доступом к личному кабинету: active = true.
- Создать сотрудника без доступа к личному кабинету: active = false.
- Передать несколько департаментов или должностей с определением primary-значения.
- Синхронизировать сотрудников из внешней HR-системы.
Типичные ошибки
Typical integration mistakes
| Типичная ошибка | Как правильно | | ----------------------------------------------------- |
---------------------------------------------------------- | | Передавать active как строку "true" или "false" |
Передавайте true или false как JSON-boolean. | | Передавать gender в значении, отличном от Male/Female |
Используйте только Male или Female. | | Передавать idCompany или hrEmail | Не передавайте эти значения; BFF
берёт их из Bearer token. | | Ожидать идемпотентность через Idempotency-Key | В текущей реализации Idempotency-Key
не используется. | | Передавать fullName вместо name и surname | Передавайте name и surname; fullName формирует сервер.
|
FAQ
Какие поля обязательны для создания сотрудника?
email, name, surname, gender и active.
Что делает active = true?
Сервер создаёт или синхронизирует связанный пользовательский аккаунт в Keycloak и открывает доступ к личному кабинету.
Что делает active = false?
Сотрудник создаётся без доступа к личному кабинету, то есть без пользователя в Keycloak.
Что будет, если email уже существует?
API вернёт 409 Conflict.
Нужно ли передавать hrEmail?
Нет. BFF берёт hrEmail из Bearer token.