Темный режим

API Employees Workflow

1. Обзор workflow

CRUD API для управления сотрудниками компании с авторизацией по токену и расширенными возможностями фильтрации.

Названиеapi-employees
База данныхPostgreSQL (employees, companies, departments)
Методы6 webhook-узлов для разных операций
ОсобенностиДинамическая генерация SQL, проверка email, импорт из файла

2. POST /employees/get

Получение списка сотрудников с возможностью фильтрации по различным параметрам.

Цепочка выполнения:

  1. Webhook (employees/get)

    Принимает POST-запрос с параметрами:

    • headers.authorization - токен компании
    • Опциональные параметры фильтрации в теле запроса:
      • departmentId - ID отдела ("none" для сотрудников без отдела)
      • status - статус сотрудника
      • hireDate - дата приема на работу (фильтр "после")
      • searchTerm - поиск по ФИО и email
      • userId - конкретный сотрудник
      • city - город
  2. Edit Fields1

    Извлекает параметры из запроса:

    token = $json.headers.authorization
    departmentId = $json.body.departmentId
    status = $json.body.status
    hireDate = $json.body.hireDate
    searchTerm = $json.body.searchTerm
    userId = $json.body.userId
  3. Postgres4

    Проверяет валидность токена:

    SELECT "companyId" FROM companies WHERE "token" = $1;

    Возвращает companyId для дальнейших запросов.

  4. Merge

    Объединяет данные из Edit Fields1 и Postgres4.

  5. Code

    Генерирует динамический SQL-запрос на основе параметров:

    Логика работы:

    1. Базовый запрос выбирает все поля сотрудника
    2. Добавляет условия WHERE только для переданных параметров
    3. Особые обработки:
      • departmentId="none""departmentId" IS NULL
      • searchTerm → поиск по ФИО и email (ILIKE)
      • Проверка на пустые значения параметров

    Пример сгенерированного SQL:

    SELECT
        "departmentId", "userId", "firstName", "lastName", "middleName",
        "email", "phone", "telegram", "gender", "role",
        "birthDate", "hireDate", "city", "status"
    FROM employees
    WHERE "companyId" = 68
    AND "status" = 'active'
    AND "departmentId" IS NULL
    AND ("firstName" ILIKE '%иван%' OR "lastName" ILIKE '%иван%')
  6. Postgres

    Выполняет сгенерированный запрос.

  7. Postgres11

    Получает названия отделов для объединения:

    SELECT "departmentId", "name" as department_name
    FROM departments
    WHERE "companyId" = $1;
  8. Merge6

    Объединяет данные сотрудников с названиями отделов.

  9. Respond to departments/get

    Возвращает полные данные о сотрудниках.

Пример ответа:

[
  {
    "departmentId": null,
    "userId": 101,
    "firstName": "Иван",
    "lastName": "Иванов",
    "email": "ivan@example.com",
    "status": "active",
    "department_name": null
  },
  {
    "departmentId": 16,
    "userId": 102,
    "firstName": "Петр",
    "lastName": "Петров",
    "email": "petr@example.com",
    "status": "active",
    "department_name": "Разработка"
  }
]

3. POST /employees/count

Получение количества сотрудников по отделам для компании.

Цепочка выполнения:

  1. Webhook (employees/count)

    Принимает POST-запрос с заголовком:

    • headers.authorization - токен компании
  2. Edit Fields2

    Извлекает токен:

    headers.authorization = $json.headers.authorization
  3. Postgres5

    Проверяет валидность токена:

    SELECT "companyId" FROM companies WHERE "token" = $1;
  4. Edit Fields3

    Добавляет companyId в данные.

  5. Postgres1

    Выполняет запрос подсчета сотрудников:

    SELECT
        "departmentId",
        COUNT(*)::integer AS employee_count
    FROM employees
    WHERE "companyId" = $1
    GROUP BY "departmentId";
  6. Respond to departments/get1

    Возвращает статистику по отделам:

    [
      {
        "departmentId": 8,
        "employee_count": 5
      },
      {
        "departmentId": null,
        "employee_count": 3
      }
    ]

4. POST /employees/create

Создание нового сотрудника с проверкой уникальности email и лимитами для бесплатных аккаунтов.

Цепочка выполнения:

  1. Webhook (employees/create)

    Принимает POST-запрос с параметрами:

    • headers.authorization - токен компании
    • body.email - email сотрудника (обязательное)
    • Другие опциональные данные сотрудника
  2. Edit Fields

    Извлекает параметры из запроса:

    token = $json.headers.authorization
    firstName = $json.body.firstName
    lastName = $json.body.lastName
    ... (все поля сотрудника)
  3. Postgres6

    Проверяет валидность токена и получает companyId и тип аккаунта:

    SELECT "companyId", "accountType" FROM companies WHERE "token" = $1;
  4. Merge1

    Объединяет данные из Edit Fields и Postgres6.

  5. check email1

    Проверяет уникальность email в компании:

    SELECT EXISTS (
        SELECT 1 FROM employees
        WHERE email = $1 AND "companyId" = $2
    ) AS check;
  6. Merge4

    Объединяет результаты проверки.

  7. If1

    Определяет тип аккаунта (paid/free):

    Условие: $json.accountType == "paid"
  8. Ветка 1 (paid аккаунт):

    1. Switch

      Проверяет результат проверки email:

      • Если email существует → возвращает ошибку
      • Иначе → продолжает создание
    2. Code1

      Генерирует INSERT-запрос:

      Логика работы:

      1. Проверяет обязательные поля (companyId, email)
      2. Обрабатывает departmentId="none" как NULL
      3. Формирует параметризованный запрос только для переданных полей
      4. Устанавливает статус "active" по умолчанию

      Пример сгенерированного SQL:

      INSERT INTO employees (
          "companyId", "email", "firstName", "lastName", "departmentId", "status"
      ) VALUES ($1, $2, $3, $4, $5, $6);
    3. Postgres2

      Выполняет запрос создания.

    4. Respond to departments/get2

      Возвращает результат создания.

  9. Ветка 2 (free аккаунт):

    1. check email2

      Проверяет лимит сотрудников (не более 10):

      SELECT 
          CASE WHEN COUNT(*) >= 10 THEN false ELSE true END AS limit
      FROM employees
      WHERE "companyId" = $2;
    2. Merge7

      Объединяет результаты проверок.

    3. If2

      Проверяет лимит:

      Условие: $json.limit == true
      • Если лимит исчерпан → возвращает ошибку 413
      • Иначе → проверяет email и создает сотрудника

Пример ошибки:

{
  "response": "email already exists"
}

5. POST /employees/update

Обновление данных сотрудника с проверкой уникальности email.

Цепочка выполнения:

  1. Webhook (employees/update)

    Принимает POST-запрос с параметрами:

    • headers.authorization - токен компании
    • body.userId - ID обновляемого сотрудника (обязательное)
    • Другие обновляемые поля
  2. Edit Fields5

    Извлекает параметры из запроса:

    token = $json.headers.authorization
    userId = $json.body.userId
    ... (все обновляемые поля)
  3. Postgres8

    Проверяет валидность токена:

    SELECT "companyId" FROM companies WHERE "token" = $1;
  4. Merge3

    Объединяет данные из Edit Fields5 и Postgres8.

  5. check email

    Проверяет уникальность email (исключая текущего сотрудника):

    SELECT EXISTS (
        SELECT 1 FROM employees
        WHERE email = $1 AND "companyId" = $2 AND "userId" <> $3
    ) AS check;
  6. Merge5

    Объединяет результаты проверки.

  7. Switch1

    Проверяет результат проверки email:

    • Если email существует → возвращает ошибку
    • Иначе → продолжает обновление
  8. Code2

    Генерирует динамический UPDATE-запрос:

    Логика работы:

    1. Проверяет наличие userId
    2. Добавляет в запрос только переданные поля
    3. Особые обработки:
      • departmentId="none"NULL
      • Пустые даты → NULL

    Пример сгенерированного SQL:

    UPDATE employees
    SET "lastName" = $1, "firstName" = $2, "departmentId" = NULL
    WHERE "userId" = $3;
  9. Postgres9

    Выполняет запрос обновления.

  10. Respond to departments/get4

    Возвращает результат обновления.

6. POST /employees/delete

Удаление сотрудника по ID с проверкой принадлежности к компании.

Цепочка выполнения:

  1. Webhook (employees/delete)

    Принимает POST-запрос с параметрами:

    • headers.authorization - токен компании
    • body.userId - ID удаляемого сотрудника
  2. Edit Fields4

    Извлекает параметры:

    token = $json.headers.authorization
    userId = $json.body.userId
  3. Postgres7

    Проверяет валидность токена:

    SELECT "companyId" FROM companies WHERE "token" = $1;
  4. Merge2

    Объединяет данные из Edit Fields4 и Postgres7.

  5. Postgres3

    Выполняет удаление с проверкой companyId:

    DELETE FROM employees
    WHERE "userId" = $1 AND "companyId" = $2;
  6. Respond to departments/get3

    Возвращает статус успешного выполнения:

    {"status": "success"}

7. POST /employees/import

Импорт сотрудников из файла (CSV/Excel).

Цепочка выполнения:

  1. Webhook (employees/import)

    Принимает POST-запрос с файлом:

    • headers.authorization - токен компании
    • Файл с данными сотрудников
  2. get companyId

    Проверяет валидность токена:

    SELECT "companyId", "token" FROM companies WHERE "token" = $1;
  3. Read File

    Читает данные из файла (поддерживает CSV/Excel).

  4. Merge9

    Объединяет companyId с данными из файла.

  5. Execute Workflow

    Запускает подпроцесс для каждого сотрудника (аналогично employees/create).

  6. Edit Fields8

    Формирует итоговый ответ.

  7. Respond to Webhook

    Возвращает статус импорта:

    {"result": "success"}

8. Общие компоненты

Авторизация

Все запросы требуют валидного токена компании в заголовке Authorization.

Проверка токена выполняется запросом:

SELECT "companyId" FROM companies WHERE "token" = $1;

Структура БД

Таблица employees

  • userId - первичный ключ
  • companyId - ссылка на компанию
  • departmentId - ссылка на отдел (может быть NULL)
  • firstName, lastName, middleName - ФИО
  • email - уникальный в рамках компании
  • status - статус сотрудника (active/inactive)
  • Другие персональные данные

Таблица companies

  • companyId - первичный ключ
  • token - токен для авторизации
  • accountType - тип аккаунта (paid/free)

Обработка ошибок

Общие сценарии ошибок:

  • Неверный токен - 401 Unauthorized
  • Дубликат email - 409 Conflict
  • Превышение лимита сотрудников (free) - 413 Payload Too Large
  • Отсутствуют обязательные поля - 400 Bad Request