brief-rags-bench/DB_API_CONTRACT_V2.md

18 KiB
Raw Permalink Blame History

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

---