brief-rags-bench/DB_API_CONTRACT_V2.md

710 lines
18 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

```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-инъекций
---