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"
}
Створити співробітника тільки з масивами 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"
}
Відповідь
Успішна відповідь: 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 через 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.