sequenceDiagram
autonumber
actor User as Mobile Client (App)
participant GW as FastAPI Gateway (backend-api)
participant K as Apache Kafka Cluster
participant Promtail as Collector: Promtail
User->>GW: POST /api/v1/fridge/items/upload-text (raw_text_input, app_lang)
alt Step 1: Contract Structure Validation
Note over GW: Check constraints: len(raw_text_input) <= 120 chars.<br/>Parse Authorization token.
else Business Error: String Length Exceeded or Empty Input
GW-->>User: HTTP 422 Unprocessable Entity
Note over GW: Step 1.1: Log failure metric to stdout
GW->>Promtail: Send log payload with code IAD-VAL-422
end
critical Step 2: Publish to Message Broker
GW->>K: Push to topic bpds.inventory.in.receipt.upload
GW-->>User: HTTP 202 Accepted (Request Accepted)
option Infrastructure Failure (Kafka Unavailable)
GW-->>User: HTTP 503 Service Unavailable
end
POST /api/v1/purchase/upload-text
Метод текстового ввода добавления продуктов в цифровой холодильник
- INV Backlog — Краткое Описание задачи 1.
В открытом доступе представлена демонстрационная версия метода. В настоящей публичной документации отображены не все шаги, технические сценарии и приватные эндпоинты для системы цифровых симуляторов бизнес-процессов.
- Полная спецификация метода: Будет доступна только во внутреннем контуре разработки (Confluence / Swagger Enterprise).
Функциональное назначение
The POST /api/v1/fridge/items/upload-text method is a synchronous REST API entry point used for manual product entry into the smart refrigerator ecosystem. This method is triggered when a user manually types a product description into the mobile application’s search bar.
Core Tasks Handled by the Method (Gateway Level)
- Contract Validation (Pydantic / DTO): Verifies the JSON payload structure and enforces a strict string length constraint (maximum 120 characters).
- Request Tracing (Observability): Generates or propagates the
X-Request-ID(trace_id) header to seamlessly link the HTTP session with the downstream asynchronous pipeline. - Asynchronous Delegation (Event Production): Instantly publishes the raw event to the Apache Kafka broker topic and yields an HTTP
202 Acceptedstatus to the client, isolating the end-user from LLM processing latencies (Ollama Inference).
Interaction Protocol (HTTP Contract)
- Method:
POST - Route:
/api/v1/fridge/items/upload-text - Data Format:
application/json
Headers Specification (HTTP Headers)
| Header | Required | Description | Example Value |
|---|---|---|---|
Content-Type |
Yes | Specifies a strictly typed JSON payload. | application/json |
Authorization |
Yes | Access Token. The gateway extracts user_id and home_group_id from this token. |
Bearer eyJhbGciOiJIUzI1Ni... |
X-Request-ID |
Yes | End-to-end request ID to trace manual input logs within the NLP subsystem. | req-manual-text-99aa |
Request Body Specification (Request Body)
| Field | Type | Required | Description | Example Value |
|---|---|---|---|---|
raw_text_input |
String | Yes | The raw text string entered manually by the user (length: 1 to 120 chars). | Молоко Юрта в ауле 3.2% 1.5 л |
app_lang |
String | Yes | Two-letter application language code used to pick the correct censorship dictionary. | ru |
Request Payload Example:
{
"raw_text_input": "Молоко Юрта в ауле 3.2% 1.5 л 1029 тенге",
"app_lang": "ru"
}Kafka Egress Event Contract
Upon successful validation, the gateway wraps the data into a DTO and sends it to the bpds.inventory.in.receipt.upload topic.
- Topic:
bpds.inventory.in.receipt.upload - Partition Key:
user_id(ensures sequential order of requests for each unique user)
{
"trace_id": "req-manual-text-99aa",
"user_id": "usr_9876",
"home_group_id": "group_abc123",
"source_type": "MANUAL_TEXT",
"raw_text_input": "Молоко Юрта в ауле 3.2% 1.5 л 1029 тенге",
"app_lang": "ru",
"timestamp": "2026-08-07T10:23:00Z"
}Метод POST /api/v1/fridge/items/upload-text является синхронной входной точкой (HTTP REST API) для ручного добавления продуктов в систему умного холодильника. Метод используется, когда пользователь самостоятельно вбивает наименование товара текстом в поисковую строку мобильного приложения.
Критические задачи метода (Gateway Level)
- Валидация контракта (Pydantic / DTO): Проверка структуры JSON-пакета и жесткое ограничение длины строки (не более 120 символов).
- Трассировка запроса (Observability): Генерация или сквозной проброс заголовка
X-Request-ID(trace_id) для логирования и связывания HTTP-сессии с асинхронным пайплайном воркеров. - Асинхронный делегат (Event Produce): Немедленная публикация сырого события в топик брокера сообщений Apache Kafka и возврат клиенту статуса
202 Accepted. Метод изолирует пользователя от задержек нейросети (Ollama Inference).
Протокол взаимодействия (HTTP Контракт)
- Метод:
POST - Маршрут:
/api/v1/fridge/items/upload-text - Формат данных:
application/json
Спецификация заголовков (HTTP Headers)
| Заголовок | Обязательный | Описание | Пример значения |
|---|---|---|---|
Content-Type |
Да | Указывает на передачу строго типизированного JSON-пакета | application/json |
Authorization |
Да | Токен доступа (Access Token). Шлюз извлекает из него user_id и home_group_id. |
Bearer eyJhbGciOiJIUzI1Ni... |
X-Request-ID |
Да | Сквозной ID запроса для связывания HTTP-лога с NLP-подсистемой. | req-manual-text-99aa |
Спецификация тела запроса (Request Body)
| Поле | Тип | Обязательный | Описание | Пример значения |
|---|---|---|---|---|
raw_text_input |
String | Да | Текстовая строка, введенная пользователем вручную (длина от 1 до 120 символов). | Молоко Юрта в ауле 3.2% 1.5 л |
app_lang |
String | Да | Двухбуквенный код языка приложения для выбора словаря цензуры. | ru |
Пример JSON-запроса (Payload):
{
"raw_text_input": "Молоко Юрта в ауле 3.2% 1.5 л 1029 тенге",
"app_lang": "ru"
}Контракт события на выходе (Kafka Egress Event)
После успешной валидации шлюз упаковывает данные в DTO и отправляет в топик bpds.inventory.in.receipt.upload.
- Topic:
bpds.inventory.in.receipt.upload - Partition Key:
user_id(для сохранения порядка обработки запросов одного пользователя)
{
"trace_id": "req-manual-text-99aa",
"user_id": "usr_9876",
"home_group_id": "group_abc123",
"source_type": "MANUAL_TEXT",
"raw_text_input": "Молоко Юрта в ауле 3.2% 1.5 л 1029 тенге",
"app_lang": "ru",
"timestamp": "2026-08-07T10:23:00Z"
}Диаграмма последовательности (Mermaid)
sequenceDiagram
autonumber
actor User as Мобильный клиент (App)
participant GW as FastAPI Gateway (backend-api)
participant K as Apache Kafka Cluster
participant Promtail as Collector: Promtail
User->>GW: POST /api/v1/fridge/items/upload-text (raw_text_input, app_lang)
alt Шаг 1: Валидация структуры контракта
Note over GW: Проверка длины: len(raw_text_input) <= 120 символов.<br/>Парсинг токена Authorization.
else Бизнес-ошибка: Нарушение длины строки или пустой ввод
GW-->>User: HTTP 422 Unprocessable Entity
Note over GW: Шаг 1.1: Фиксация метрики сбоя в stdout
GW->>Promtail: Отправка лога с кодом IAD-VAL-422
end
critical Шаг 2: Публикация в брокер сообщений
GW->>K: Пуш в топик bpds.inventory.in.receipt.upload
GW-->>User: HTTP 202 Accepted (Запрос принят)
option Инфраструктурный сбой (Kafka Unavailable)
GW-->>User: HTTP 503 Service Unavailable
end
Расшифровка шагов метода
| Step | Action | Parameters / Requests / DTO | Business Errors (Codes / Descriptions) |
|---|---|---|---|
| Step 1 | The API Gateway captures the request, then generates or forwards the X-Request-ID. It passes the data through a Pydantic model to enforce the 120-character limit on raw_text_input. |
HTTP Request Payload: The JSON request payload and headers specified above. |
IAD-VAL-422: The input text string is empty or exceeds the allowed limit of 120 characters. |
| Step 1.1 | If the request fails input validation, the gateway constructs a structured JSON log containing the error context and writes it to the stdout stream for collection. |
Structured JSON Log:{ "trace_id": "...", "domain": "INVENTORY", "error_code": "IAD-VAL-422", "user_id": "..." } |
|
| Step 2 | If validation succeeds, the gateway extracts the user_id and home_group_id from the JWT, packages the properties into the Kafka Egress Event contract, and sends it to the broker. |
Kafka Message: The egress event contract shown above, partitioned by user_id. |
| Шаг | Действие | Параметры / Запросы / DTO | Бизнес-ошибки (Коды / Описания) |
|---|---|---|---|
| Шаг 1 | API-шлюз перехватывает запрос, генерирует или пробрасывает X-Request-ID. С помощью Pydantic-модели проверяется лимит на длину raw_text_input (до 120 символов). |
HTTP Request Payload: Специфицированный выше JSON с телом запроса и заголовками. |
IAD-VAL-422: Длина введенного текста пустая или превышает лимит в 120 символов. |
| Шаг 1.1 | В случае провала валидации, шлюз формирует структурированный JSON-лог с контекстом ошибки и пишет его в stdout stream для сборщика метрик. |
Structured JSON Log:{ "trace_id": "...", "domain": "INVENTORY", "error_code": "IAD-VAL-422", "user_id": "..." } |
|
| Шаг 2 | При успешной валидации шлюз извлекает user_id и home_group_id из JWT-токена, упаковывает в контракт Kafka Egress Event и публикует в брокер. |
Kafka Message: Описанный выше контракт события с ключом партиционирования по user_id. |
Спецификация ответов (HTTP Responses)
202 Accepted (Успешный прием)
Возвращается, когда данные успешно прошли первичную валидацию структуры и были записаны в Kafka. Клиент не ждет окончания цензуры.
{
"success": true,
"message": "Request accepted for processing",
"trace_id": "req-manual-text-99aa"
}422 Unprocessable Entity (Ошибка валидации)
Возвращается, если строка raw_text_input превышает 120 символов или передана пустой. В лог (Promtail) уходит бизнес-метрика сбоя.
{
"error": "Unprocessable Entity",
"code": "IAD-VAL-422",
"message": "The raw text input length must be between 1 and 120 characters."
}