Сбор события
Сбор аналитического события#
Приём события funnel_step от Frontend и Backend. Спецификация полей — spec.md, запись в БД — database.md.
Сервис принимает одиночное событие, сохраняет через sync.analytics_events_import_impl (JSON-массив).
Ручка#
POST /v1/events/collect
Полный адрес в сети#
| Среда | URL |
|---|---|
| 🧪 Dev | http://terra-user-analytics-service.devterra.ru/v1/events/collect |
| 🚀 Prod | http://terra-user-analytics-service.prodterra.ru/srv/terra-user-analytics/v1/events/collect |
Авторизация#
Обязательна. Basic Auth в заголовке:
Authorization: Basic base64(username:password)
Content-Type: application/json
Пример:
Authorization: Basic dXNlcm5hbWUxOnBhc3N3b3JkMQ==
| Заголовок | Обязательный | Описание |
|---|---|---|
Authorization |
✅ | Basic base64(username:password) |
Content-Type |
✅ | application/json |
Без заголовка или с неверными данными — 401 Unauthorized.
Пример тела запроса#
[
{
"event": "funnel_step",
"funnel": "auth",
"action": "login",
"step": "verification",
"status": "success",
"method": "phone",
"provider": "call_robot",
"platform": "android",
"error_code": null,
"user_uuid": "123e4567-e89b-12d3-a456-426614174000",
"session_uuid": null,
"created_at": "2026-08-05T12:00:00Z"
}
]
Поля запроса#
| Поле | Тип | Описание | Обязательное | Пример |
|---|---|---|---|---|
event |
string | Тип события | ✅ | "funnel_step" |
funnel |
string | Воронка | ✅ | "auth" |
action |
string | Сценарий | ✅ | "login" |
step |
string | Этап | ✅ | "verification" |
status |
string | Результат шага | ✅ | "success" |
method |
string | Способ взаимодействия | ✅ | "phone" |
provider |
string | Внешний провайдер | ❌ | "call_robot" |
platform |
string | Источник события | ✅ | "android" |
error_code |
string | Код ошибки; обязателен при status = failed |
⚠️ | "verification_invalid" |
user_uuid |
string | UUID пользователя | ❌ | "123e4567-e89b-12d3-a456-426614174000" |
session_uuid |
string | UUID попытки регистрации (до account_creation) |
❌ | "987fcdeb-51a2-43f1-b9c4-123456789abc" |
created_at |
string | Время события, ISO 8601 (UTC) | ✅ | "2026-08-05T12:00:00Z" |
Допустимые значения enum — в enums.md.
Формат ответа#
Все ответы сервиса — единый JSON-объект:
| Поле | Тип | Описание |
|---|---|---|
showError |
bool | false — успех, true — ошибка |
message |
string | Краткое сообщение |
statusCode |
int | HTTP-код ответа |
traceID |
string | ID трассировки запроса |
description |
string | Детали: UUID события или код/текст ошибки |
Валидация#
| Правило | HTTP | statusCode |
|---|---|---|
Отсутствует Authorization |
401 |
401 |
| Неверный Basic Auth | 401 |
401 |
| Нет обязательного поля | 400 |
400 |
| Недопустимое enum-значение | 400 |
400 |
status = failed, но нет error_code |
400 |
400 |
created_at не ISO 8601 |
400 |
400 |
| Дубликат события | 409 |
409 |
| Внутренняя ошибка | 500 |
500 |
Дедупликация#
Сервис отклоняет повторную отправку одного и того же события.
Ключ дедупликации:
event + funnel + action + step + status + platform + user_uuid + session_uuid + created_at
При совпадении — 409 Conflict, тело не сохраняется повторно.
Пример тела ответа#
201 Created
{
"showError": false,
"message": "OK",
"statusCode": 201,
"traceID": "96c7327642e91b00ddb4262fa4afb546",
"description": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
| Поле | Тип | Описание | Пример |
|---|---|---|---|
showError |
bool | Успешный ответ | false |
message |
string | Статус операции | "OK" |
statusCode |
int | HTTP-код | 201 |
traceID |
string | ID трассировки | "96c7327642e91b00ddb4262fa4afb546" |
description |
string | UUID сохранённого события | "a1b2c3d4-..." |
Примеры ответов с ошибкой#
400 Bad Request
{
"showError": true,
"message": "error_code is required when status is failed",
"statusCode": 400,
"traceID": "96c7327642e91b00ddb4262fa4afb546",
"description": "VALIDATION_ERROR"
}
401 Unauthorized
{
"showError": true,
"message": "invalid or missing Basic Auth credentials",
"statusCode": 401,
"traceID": "96c7327642e91b00ddb4262fa4afb546",
"description": "UNAUTHORIZED"
}
409 Conflict
{
"showError": true,
"message": "event already exists",
"statusCode": 409,
"traceID": "96c7327642e91b00ddb4262fa4afb546",
"description": "DUPLICATE_EVENT"
}
404 Not Found
{
"showError": false,
"message": "Cannot GET /admin",
"statusCode": 404,
"traceID": "96c7327642e91b00ddb4262fa4afb546",
"description": "Cannot GET /admin"
}
Поведение клиента#
- Отправка асинхронная — не блокирует основной сценарий (вход, регистрация).
- Ошибки
4xx/5xxлогируются на стороне клиента, пользователю не показываются. - При сетевой ошибке — retry с экспоненциальной задержкой (1–3 попытки).
session_uuidпередаётся только в сценарии незавершённой регистрации (см. spec.md).
Пример curl#
curl -X POST \
'http://terra-user-analytics-service.devterra.ru/v1/events/collect' \
-H 'Authorization: Basic dXNlcm5hbWUxOnBhc3N3b3JkMQ==' \
-H 'Content-Type: application/json' \
-d '{
"event": "funnel_step",
"funnel": "auth",
"action": "registration",
"step": "identification",
"status": "success",
"method": "phone",
"platform": "android",
"session_uuid": "987fcdeb-51a2-43f1-b9c4-123456789abc",
"created_at": "2026-08-05T12:00:00Z"
}'