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