API Survey Send Workflow
1. Обзор workflow
API для обработки и сохранения данных опроса с проверкой валидности токенов пользователя и опроса.
| Название | api-survey-send |
|---|---|
| База данных | PostgreSQL (surveys, employees, raw_survey_data) |
| Методы | 1 webhook-узел для отправки данных опроса |
2. POST /survey/data/send
Прием и обработка данных опроса с валидацией пользователя и обновлением статистики опроса.
Цепочка выполнения:
-
Webhook (survey/data/send)
Принимает POST-запрос с параметрами:
query.surveyId- токен опросаquery.userId- токен пользователяquery.surveyData- массив ответов на вопросы опроса
-
Параллельные проверки:
-
check user token
Проверяет валидность токена пользователя:
SELECT "userId" FROM employees WHERE "token" = $1;Параметр:
$1 = $json.query.userId -
check survey respondents
Проверяет, что пользователь в списке респондентов и обновляет счетчик:
UPDATE "surveys" SET "current_respondents_count" = "current_respondents_count" + 1, "respondents" = ARRAY_REMOVE("respondents", $2) WHERE "token" = $1 AND $2 = ANY("respondents") RETURNING "surveyId";Параметры:
$1 = $json.query.surveyId,$2 = $json.userIdОсобенности:
- Увеличивает счетчик респондентов только если пользователь был в списке
- Удаляет пользователя из списка респондентов
- Возвращает surveyId при успешном обновлении
-
check user token
-
Merge2
Объединяет результаты проверок и исходные данные запроса.
-
Edit Fields
Подготавливает данные для дальнейшей обработки:
query.surveyData = $json.query.surveyData query.surveyId = $json.query.surveyId query.userId = $json.query.userId -
Параллельная обработка:
-
Code
Преобразует и очищает данные surveyData:
Логика работы:
- Обрабатывает каждый элемент массива surveyData
- Для поля value сохраняет 0 как 0, null как null
- Для comment:
- Заменяет null/undefined на null
- Экранирует обратные слэши и кавычки
- Ограничивает длину до 4000 символов
- Удаляет лишние символы (\n, \r, \t)
Пример преобразования:
{ "questionId": 123, "paramNameMetric": null, "paramNameSubmetric": null, "value": null, "comment": "Выдать рабочие компьютеры" } -
Postgres2
Получает дополнительные данные о пользователе и опросе:
SELECT s."surveyId", s."companyId", e."userId", e."hireDate", e."gender", e."departmentId" FROM surveys s JOIN employees e ON e."token" = $2 WHERE s."token" = $1;Параметры:
$1 = $json.query.surveyData[0].surveyId,$2 = $json.query.surveyData[0].userIdВозвращает:
- ID опроса, компании
- Данные пользователя (ID, дата найма, пол, отдел)
-
Code
-
Merge
Объединяет очищенные данные опроса с информацией о пользователе.
-
Postgres
Сохраняет данные в таблицу raw_survey_data:
INSERT INTO public.raw_survey_data ( questionId, value, departmentId, userId, companyId, surveyId, paramNameSubmetric, paramNameMetric, comment, hireDate, gender ) VALUES (...);Особенности преобразования данных:
- value: преобразует в число или null (если 'null', 'NaN' или не число)
- comment: сохраняет как null если пустое или 'null'
-
Respond to Webhook
Возвращает статус успешного выполнения:
{"success": true}
Пример запроса:
{
"surveyId": "5810b6d6-7545-49ff-b71d-ea39bee9835c",
"userId": "3098c8c8-b17b-45c4-90ba-29da3eba4a29",
"surveyData": [
{
"questionId": 3,
"paramNameMetric": "recognition",
"paramNameSubmetric": "recognition_quality",
"value": 0,
"comment": null
},
{
"questionId": 123,
"paramNameMetric": null,
"paramNameSubmetric": null,
"value": null,
"comment": "Выдать рабочие компьютеры"
}
]
}
Структура БД:
Таблица raw_survey_data
- responseId - первичный ключ (автоинкремент)
- userId - ID пользователя
- departmentId - ID отдела
- companyId - ID компании
- surveyId - ID опроса
- questionId - ID вопроса
- paramNameMetric - название метрики
- paramNameSubmetric - название подметрики
- value - числовое значение ответа
- comment - текстовый комментарий
- hireDate - дата найма пользователя
- gender - пол пользователя
Таблица surveys
- surveyId - первичный ключ
- token - токен опроса
- current_respondents_count - счетчик респондентов
- respondents - массив ID ожидаемых респондентов
Таблица employees
- userId - первичный ключ
- token - токен пользователя
- hireDate - дата найма
- gender - пол
- departmentId - ID отдела