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
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| 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 связанного кандидата. |
| 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.