710 lines
18 KiB
Markdown
710 lines
18 KiB
Markdown
```markdown
|
||
# SBS Bench RAG API Contract
|
||
|
||
API для управления пользователями, настройками окружений и сессиями анализа в системе Brief Bench.
|
||
|
||
## Содержание
|
||
|
||
- [Общая информация](#общая-информация)
|
||
- [Аутентификация и пользователи](#аутентификация-и-пользователи)
|
||
- [Настройки пользователя](#настройки-пользователя)
|
||
- [Сессии анализа](#сессии-анализа)
|
||
- [Форматы данных](#форматы-данных)
|
||
- [Обработка ошибок](#обработка-ошибок)
|
||
|
||
---
|
||
|
||
## Общая информация
|
||
|
||
### Base URL
|
||
|
||
```
|
||
/api/v1
|
||
```
|
||
|
||
### Форматы данных
|
||
|
||
- **Content-Type**: `application/json; charset=utf-8`
|
||
- **Даты**: ISO 8601 с таймзоной UTC (`YYYY-MM-DDTHH:MM:SSZ`)
|
||
- **UUID**: строка в формате `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
|
||
|
||
### Окружения
|
||
|
||
API поддерживает три окружения (enum `environment`):
|
||
- `ift` — IFT окружение
|
||
- `psi` — PSI окружение
|
||
- `prod` — Production окружение
|
||
|
||
### Режимы API
|
||
|
||
Два режима работы (enum `api_mode`):
|
||
- `bench` — режим тестирования
|
||
- `backend` — backend режим
|
||
|
||
---
|
||
|
||
## Аутентификация и пользователи
|
||
|
||
### POST /users/login
|
||
|
||
Авторизация пользователя и запись информации о логине.
|
||
|
||
#### Request
|
||
|
||
```
|
||
{
|
||
"login": "12345678",
|
||
"client_ip": "MTkyLjE2OC4xLjEwMA=="
|
||
}
|
||
```
|
||
|
||
**Параметры:**
|
||
- `login` (string, required): 8-значный логин (строка из цифр)
|
||
- `client_ip` (string, required): IP-адрес в кодировке base64
|
||
|
||
#### Response 200
|
||
|
||
```
|
||
{
|
||
"user_id": "550e8400-e29b-41d4-a716-446655440000",
|
||
"login": "12345678",
|
||
"last_login_at": "2025-12-24T12:00:00Z",
|
||
"created_at": "2025-12-01T10:00:00Z"
|
||
}
|
||
```
|
||
|
||
#### Errors
|
||
|
||
- **400 Bad Request**: Неверный формат логина или client_ip
|
||
- **500 Internal Server Error**: Ошибка сервера
|
||
|
||
---
|
||
|
||
## Настройки пользователя
|
||
|
||
### GET /users/{user_id}/settings
|
||
|
||
Получить настройки пользователя для всех окружений.
|
||
|
||
#### Path Parameters
|
||
|
||
- `user_id` (UUID, required): UUID пользователя
|
||
|
||
#### Response 200
|
||
|
||
```
|
||
{
|
||
"user_id": "550e8400-e29b-41d4-a716-446655440000",
|
||
"settings": {
|
||
"ift": {
|
||
"apiMode": "bench",
|
||
"bearerToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
||
"systemPlatform": "platform-ift",
|
||
"systemPlatformUser": "user-123",
|
||
"platformUserId": "p-user-456",
|
||
"platformId": "platform-789",
|
||
"withClassify": false,
|
||
"resetSessionMode": true
|
||
},
|
||
"psi": {
|
||
"apiMode": "bench",
|
||
"bearerToken": null,
|
||
"systemPlatform": null,
|
||
"systemPlatformUser": null,
|
||
"platformUserId": null,
|
||
"platformId": null,
|
||
"withClassify": false,
|
||
"resetSessionMode": true
|
||
},
|
||
"prod": {
|
||
"apiMode": "backend",
|
||
"bearerToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
||
"systemPlatform": "platform-prod",
|
||
"systemPlatformUser": "user-prod",
|
||
"platformUserId": "p-user-prod",
|
||
"platformId": "platform-prod-id",
|
||
"withClassify": true,
|
||
"resetSessionMode": false
|
||
}
|
||
},
|
||
"updated_at": "2025-12-24T12:30:00Z"
|
||
}
|
||
```
|
||
|
||
#### Errors
|
||
|
||
- **404 Not Found**: Пользователь не найден
|
||
- **500 Internal Server Error**: Ошибка сервера
|
||
|
||
---
|
||
|
||
### PATCH /users/{user_id}/settings
|
||
|
||
Частично обновить настройки пользователя. Обновляются только переданные поля.
|
||
|
||
#### Path Parameters
|
||
|
||
- `user_id` (UUID, required): UUID пользователя
|
||
|
||
#### Request
|
||
|
||
```
|
||
{
|
||
"settings": {
|
||
"ift": {
|
||
"bearerToken": "new-token-value",
|
||
"withClassify": true
|
||
},
|
||
"prod": {
|
||
"apiMode": "bench"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
**Примечания:**
|
||
- Передавайте только те окружения и поля, которые нужно изменить
|
||
- Непереданные поля остаются без изменений
|
||
- Для сброса значения в `null` явно передайте `null`
|
||
|
||
#### Response 200
|
||
|
||
```
|
||
{
|
||
"user_id": "550e8400-e29b-41d4-a716-446655440000",
|
||
"settings": {
|
||
"ift": {
|
||
"apiMode": "bench",
|
||
"bearerToken": "new-token-value",
|
||
"systemPlatform": "platform-ift",
|
||
"systemPlatformUser": "user-123",
|
||
"platformUserId": "p-user-456",
|
||
"platformId": "platform-789",
|
||
"withClassify": true,
|
||
"resetSessionMode": true
|
||
},
|
||
"psi": {
|
||
"apiMode": "bench",
|
||
"bearerToken": null,
|
||
"systemPlatform": null,
|
||
"systemPlatformUser": null,
|
||
"platformUserId": null,
|
||
"platformId": null,
|
||
"withClassify": false,
|
||
"resetSessionMode": true
|
||
},
|
||
"prod": {
|
||
"apiMode": "bench",
|
||
"bearerToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
||
"systemPlatform": "platform-prod",
|
||
"systemPlatformUser": "user-prod",
|
||
"platformUserId": "p-user-prod",
|
||
"platformId": "platform-prod-id",
|
||
"withClassify": true,
|
||
"resetSessionMode": false
|
||
}
|
||
},
|
||
"updated_at": "2025-12-24T13:00:00Z"
|
||
}
|
||
```
|
||
|
||
#### Errors
|
||
|
||
- **400 Bad Request**: Неверный формат настроек
|
||
- **404 Not Found**: Пользователь не найден
|
||
- **500 Internal Server Error**: Ошибка сервера
|
||
|
||
---
|
||
|
||
## Сессии анализа
|
||
|
||
### POST /users/{user_id}/sessions
|
||
|
||
Создать новую сессию анализа.
|
||
|
||
#### Path Parameters
|
||
|
||
- `user_id` (UUID, required): UUID пользователя
|
||
|
||
#### Request
|
||
|
||
```
|
||
{
|
||
"environment": "ift",
|
||
"api_mode": "bench",
|
||
"request": [
|
||
{
|
||
"body": "Как получить кредит на недвижимость?",
|
||
"with_docs": true
|
||
},
|
||
{
|
||
"body": "Какие документы нужны?",
|
||
"with_docs": true
|
||
}
|
||
],
|
||
"response": {
|
||
"answers": [
|
||
{
|
||
"question": "Как получить кредит на недвижимость?",
|
||
"answer": "Для получения кредита...",
|
||
"sources": ["doc1.pdf", "doc2.pdf"]
|
||
}
|
||
],
|
||
"metadata": {
|
||
"processing_time_ms": 1250
|
||
}
|
||
},
|
||
"annotations": {
|
||
"0": {
|
||
"overall": {
|
||
"rating": "correct",
|
||
"comment": "Ответ корректный и полный"
|
||
},
|
||
"body_research": {
|
||
"issues": [],
|
||
"comment": ""
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
**Параметры:**
|
||
- `environment` (string, required): Окружение (`ift`, `psi`, `prod`)
|
||
- `api_mode` (string, required): Режим API (`bench`, `backend`)
|
||
- `request` (array, required): Массив запросов
|
||
- `body` (string, required): Текст вопроса
|
||
- `with_docs` (boolean, optional): Использовать документы (default: `true`)
|
||
- `response` (object, required): Ответ системы (произвольная структура)
|
||
- `annotations` (object, optional): Аннотации по индексам вопросов
|
||
- Ключи должны быть числовыми строками (`"0"`, `"1"`, ...)
|
||
|
||
#### Response 201
|
||
|
||
```
|
||
{
|
||
"session_id": "660e8400-e29b-41d4-a716-446655440000",
|
||
"user_id": "550e8400-e29b-41d4-a716-446655440000",
|
||
"environment": "ift",
|
||
"api_mode": "bench",
|
||
"request": [
|
||
{
|
||
"body": "Как получить кредит на недвижимость?",
|
||
"with_docs": true
|
||
},
|
||
{
|
||
"body": "Какие документы нужны?",
|
||
"with_docs": true
|
||
}
|
||
],
|
||
"response": {
|
||
"answers": [
|
||
{
|
||
"question": "Как получить кредит на недвижимость?",
|
||
"answer": "Для получения кредита...",
|
||
"sources": ["doc1.pdf", "doc2.pdf"]
|
||
}
|
||
],
|
||
"metadata": {
|
||
"processing_time_ms": 1250
|
||
}
|
||
},
|
||
"annotations": {
|
||
"0": {
|
||
"overall": {
|
||
"rating": "correct",
|
||
"comment": "Ответ корректный и полный"
|
||
},
|
||
"body_research": {
|
||
"issues": [],
|
||
"comment": ""
|
||
}
|
||
}
|
||
},
|
||
"created_at": "2025-12-24T14:00:00Z",
|
||
"updated_at": "2025-12-24T14:00:00Z"
|
||
}
|
||
```
|
||
|
||
#### Errors
|
||
|
||
- **400 Bad Request**: Неверный формат данных
|
||
- **404 Not Found**: Пользователь не найден
|
||
- **500 Internal Server Error**: Ошибка сервера
|
||
|
||
---
|
||
|
||
### GET /users/{user_id}/sessions
|
||
|
||
Получить список сессий пользователя с пагинацией.
|
||
|
||
#### Path Parameters
|
||
|
||
- `user_id` (UUID, required): UUID пользователя
|
||
|
||
#### Query Parameters
|
||
|
||
- `environment` (string, optional): Фильтр по окружению (`ift`, `psi`, `prod`)
|
||
- `limit` (integer, optional): Лимит результатов (1-200, default: 50)
|
||
- `offset` (integer, optional): Смещение для пагинации (default: 0)
|
||
|
||
#### Response 200
|
||
|
||
```
|
||
{
|
||
"sessions": [
|
||
{
|
||
"session_id": "660e8400-e29b-41d4-a716-446655440000",
|
||
"environment": "ift",
|
||
"created_at": "2025-12-24T14:00:00Z"
|
||
},
|
||
{
|
||
"session_id": "770e8400-e29b-41d4-a716-446655440000",
|
||
"environment": "ift",
|
||
"created_at": "2025-12-23T10:30:00Z"
|
||
}
|
||
],
|
||
"total": 123
|
||
}
|
||
```
|
||
|
||
**Сортировка:** По дате создания (от новых к старым)
|
||
|
||
#### Errors
|
||
|
||
- **404 Not Found**: Пользователь не найден
|
||
- **500 Internal Server Error**: Ошибка сервера
|
||
|
||
---
|
||
|
||
### GET /users/{user_id}/sessions/{session_id}
|
||
|
||
Получить детальную информацию о сессии.
|
||
|
||
#### Path Parameters
|
||
|
||
- `user_id` (UUID, required): UUID пользователя
|
||
- `session_id` (UUID, required): UUID сессии
|
||
|
||
#### Response 200
|
||
|
||
```
|
||
{
|
||
"session_id": "660e8400-e29b-41d4-a716-446655440000",
|
||
"user_id": "550e8400-e29b-41d4-a716-446655440000",
|
||
"environment": "ift",
|
||
"api_mode": "bench",
|
||
"request": [
|
||
{
|
||
"body": "Как получить кредит на недвижимость?",
|
||
"with_docs": true
|
||
}
|
||
],
|
||
"response": {
|
||
"answers": [
|
||
{
|
||
"question": "Как получить кредит на недвижимость?",
|
||
"answer": "Для получения кредита...",
|
||
"sources": ["doc1.pdf"]
|
||
}
|
||
]
|
||
},
|
||
"annotations": {
|
||
"0": {
|
||
"overall": {
|
||
"rating": "correct",
|
||
"comment": "Ответ корректный"
|
||
}
|
||
}
|
||
},
|
||
"created_at": "2025-12-24T14:00:00Z",
|
||
"updated_at": "2025-12-24T14:00:00Z"
|
||
}
|
||
```
|
||
|
||
#### Errors
|
||
|
||
- **404 Not Found**: Сессия или пользователь не найдены
|
||
- **500 Internal Server Error**: Ошибка сервера
|
||
|
||
---
|
||
|
||
### PATCH /users/{user_id}/sessions/{session_id}
|
||
|
||
Обновить аннотации сессии (например, после ревью).
|
||
|
||
#### Path Parameters
|
||
|
||
- `user_id` (UUID, required): UUID пользователя
|
||
- `session_id` (UUID, required): UUID сессии
|
||
|
||
#### Request
|
||
|
||
```
|
||
{
|
||
"annotations": {
|
||
"0": {
|
||
"overall": {
|
||
"rating": "incorrect",
|
||
"comment": "Ответ неполный, не хватает информации о процентах"
|
||
},
|
||
"body_research": {
|
||
"issues": ["missing_info"],
|
||
"comment": "Не указаны процентные ставки"
|
||
}
|
||
},
|
||
"1": {
|
||
"overall": {
|
||
"rating": "correct",
|
||
"comment": "Ответ корректный"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
**Примечания:**
|
||
- Ключи `annotations` должны быть числовыми строками (`"0"`, `"1"`, ...)
|
||
- Полностью заменяет существующие аннотации
|
||
|
||
#### Response 200
|
||
|
||
```
|
||
{
|
||
"session_id": "660e8400-e29b-41d4-a716-446655440000",
|
||
"user_id": "550e8400-e29b-41d4-a716-446655440000",
|
||
"environment": "ift",
|
||
"api_mode": "bench",
|
||
"request": [...],
|
||
"response": {...},
|
||
"annotations": {
|
||
"0": {
|
||
"overall": {
|
||
"rating": "incorrect",
|
||
"comment": "Ответ неполный, не хватает информации о процентах"
|
||
},
|
||
"body_research": {
|
||
"issues": ["missing_info"],
|
||
"comment": "Не указаны процентные ставки"
|
||
}
|
||
},
|
||
"1": {
|
||
"overall": {
|
||
"rating": "correct",
|
||
"comment": "Ответ корректный"
|
||
}
|
||
}
|
||
},
|
||
"created_at": "2025-12-24T14:00:00Z",
|
||
"updated_at": "2025-12-24T14:30:00Z"
|
||
}
|
||
```
|
||
|
||
#### Errors
|
||
|
||
- **400 Bad Request**: Неверный формат данных
|
||
- **404 Not Found**: Сессия или пользователь не найдены
|
||
- **500 Internal Server Error**: Ошибка сервера
|
||
|
||
---
|
||
|
||
### DELETE /users/{user_id}/sessions/{session_id}
|
||
|
||
Удалить сессию.
|
||
|
||
#### Path Parameters
|
||
|
||
- `user_id` (UUID, required): UUID пользователя
|
||
- `session_id` (UUID, required): UUID сессии
|
||
|
||
#### Response 204
|
||
|
||
Нет тела ответа при успешном удалении.
|
||
|
||
#### Errors
|
||
|
||
- **404 Not Found**: Сессия или пользователь не найдены
|
||
- **500 Internal Server Error**: Ошибка сервера
|
||
|
||
---
|
||
|
||
## Форматы данных
|
||
|
||
### Environment Settings Object
|
||
|
||
```
|
||
{
|
||
"apiMode": "bench",
|
||
"bearerToken": "token-value",
|
||
"systemPlatform": "platform-name",
|
||
"systemPlatformUser": "user-name",
|
||
"platformUserId": "user-id",
|
||
"platformId": "platform-id",
|
||
"withClassify": false,
|
||
"resetSessionMode": true
|
||
}
|
||
```
|
||
|
||
**Поля:**
|
||
- `apiMode` (string): `bench` или `backend`
|
||
- `bearerToken` (string, nullable): Bearer токен для API
|
||
- `systemPlatform` (string, nullable): Название платформы
|
||
- `systemPlatformUser` (string, nullable): Пользователь платформы
|
||
- `platformUserId` (string, nullable): ID пользователя в платформе
|
||
- `platformId` (string, nullable): ID платформы
|
||
- `withClassify` (boolean): Использовать классификацию
|
||
- `resetSessionMode` (boolean): Режим сброса сессии
|
||
|
||
**Default значения:**
|
||
- `apiMode`: `"bench"`
|
||
- `withClassify`: `false`
|
||
- `resetSessionMode`: `true`
|
||
- Все остальные: `null`
|
||
|
||
---
|
||
|
||
## Обработка ошибок
|
||
|
||
Все ошибки возвращаются в едином формате:
|
||
|
||
```
|
||
{
|
||
"detail": "Описание ошибки",
|
||
"error_code": "OPTIONAL_ERROR_CODE"
|
||
}
|
||
```
|
||
|
||
### Коды ошибок
|
||
|
||
| HTTP Code | Описание | Когда возникает |
|
||
|-----------|----------|-----------------|
|
||
| 400 | Bad Request | Неверный формат данных в запросе |
|
||
| 404 | Not Found | Пользователь или сессия не найдены |
|
||
| 422 | Unprocessable Entity | Ошибка валидации Pydantic |
|
||
| 500 | Internal Server Error | Внутренняя ошибка сервера |
|
||
|
||
### Примеры ошибок
|
||
|
||
**400 - Неверный формат логина:**
|
||
```
|
||
{
|
||
"detail": "login: String should match pattern '^\\d{8}$'",
|
||
"error_code": null
|
||
}
|
||
```
|
||
|
||
**404 - Пользователь не найден:**
|
||
```
|
||
{
|
||
"detail": "User 550e8400-e29b-41d4-a716-446655440000 not found",
|
||
"error_code": null
|
||
}
|
||
```
|
||
|
||
**422 - Ошибка валидации annotations:**
|
||
```
|
||
{
|
||
"detail": [
|
||
{
|
||
"loc": ["body", "annotations"],
|
||
"msg": "annotations keys must be numeric strings (e.g. '0', '1')",
|
||
"type": "value_error"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Примеры использования
|
||
|
||
### Сценарий 1: Создание пользователя и сохранение настроек
|
||
|
||
```
|
||
# 1. Логин пользователя
|
||
curl -X POST /api/v1/users/login \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"login": "12345678",
|
||
"client_ip": "MTkyLjE2OC4xLjEwMA=="
|
||
}'
|
||
|
||
# Response: {"user_id": "550e8400-...", ...}
|
||
|
||
# 2. Настройка окружения IFT
|
||
curl -X PATCH /api/v1/users/550e8400-e29b-41d4-a716-446655440000/settings \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"settings": {
|
||
"ift": {
|
||
"bearerToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
||
"systemPlatform": "platform-ift",
|
||
"withClassify": true
|
||
}
|
||
}
|
||
}'
|
||
```
|
||
|
||
### Сценарий 2: Создание и аннотация сессии
|
||
|
||
```
|
||
# 1. Создание сессии анализа
|
||
curl -X POST /api/v1/users/550e8400-e29b-41d4-a716-446655440000/sessions \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"environment": "ift",
|
||
"api_mode": "bench",
|
||
"request": [
|
||
{
|
||
"body": "Как получить кредит?",
|
||
"with_docs": true
|
||
}
|
||
],
|
||
"response": {
|
||
"answers": [{
|
||
"question": "Как получить кредит?",
|
||
"answer": "Для получения кредита..."
|
||
}]
|
||
}
|
||
}'
|
||
|
||
# Response: {"session_id": "660e8400-...", ...}
|
||
|
||
# 2. Добавление аннотаций после ревью
|
||
curl -X PATCH /api/v1/users/550e8400-e29b-41d4-a716-446655440000/sessions/660e8400-e29b-41d4-a716-446655440000 \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"annotations": {
|
||
"0": {
|
||
"overall": {
|
||
"rating": "correct",
|
||
"comment": "Ответ полный и корректный"
|
||
}
|
||
}
|
||
}
|
||
}'
|
||
```
|
||
|
||
### Сценарий 3: Получение истории сессий
|
||
|
||
```
|
||
# Список всех сессий пользователя
|
||
curl -X GET /api/v1/users/550e8400-e29b-41d4-a716-446655440000/sessions?limit=10&offset=0
|
||
|
||
# Фильтр только по IFT окружению
|
||
curl -X GET /api/v1/users/550e8400-e29b-41d4-a716-446655440000/sessions?environment=ift&limit=20
|
||
|
||
# Получение конкретной сессии
|
||
curl -X GET /api/v1/users/550e8400-e29b-41d4-a716-446655440000/sessions/660e8400-e29b-41d4-a716-446655440000
|
||
```
|
||
|
||
|
||
### Особенности реализации
|
||
|
||
1. **UUID генерация**: UUID создаются на уровне приложения (Python `uuid.uuid4()`)
|
||
2. **Timestamps**: Автоматическое проставление `load_dttm` при INSERT, `updated_dttm` при UPDATE через триггеры
|
||
3. **JSONB**: Все JSON-данные хранятся в PostgreSQL JSONB для эффективного поиска
|
||
4. **Индексы**: Составные индексы на `(user_id, environment, load_dttm)` для быстрой пагинации
|
||
5. **Безопасность**: Base64-кодирование client_ip для защиты от SQL-инъекций
|
||
|
||
--- |