Метод POST /api/v2/purchase/add-by-voice

Документация API: Текстовое добавление номенклатур с автоматической gRPC ИИ-модерацией

Published

June 11, 2026

1 Функциональное назначение

Эндпоинт реализует логику быстрого добавления продуктов питания в «цифровой холодильник» посредством ввода неструктурированного текста (например, через строку АРМ или интерфейс быстрого подбора мобильного приложения).

2 Протокол взаимодействия (HTTP Контракт)

  • Метод: POST
  • Маршрут: /api/v1/fridge/add-by-text
  • Формат данных: application/json

2.1 Спецификация тела запроса (Request Body)

Поле Тип Обязательный Описание
raw_text_input String Да Неструктурированная текстовая строка ввода (например: "Груши 2.5")

3 Схема обработки запроса пользователя (Mermaid)

WarningВажное примечание

В настоящей публичной документации отображены не все шаги и сценарии для приложения в частности и для системы цифровых симуляторов бизнес-процессов в общем.

sequenceDiagram
    autonumber
    actor User as Пользователь (Микрофон)
    participant APP as Мобильное приложение (Stream Буфер)
    participant NGINX as Прокси-сервер (Nginx c сокетами)
    participant API as Бэкенд-шлюз (FastAPI WebSockets)
    participant GRPC as ИИ-сервис (Whisper Stream Инференс)
    participant DB as Реляционная СУБД (PostgreSQL)

    %% ЭТАП 1: ОТКРЫТИЕ СТРИМ-КАНАЛА
    User->>APP: Нажимает "VOICE v2" (Старт записи)
    APP->>NGINX: Инициализирует сокет ws://10.0.2.2:8080/api/v1/ws/voice-stream
    NGINX->>API: Upgrade: websocket (Соединение открыто)
    
    %% ЭТАП 2: ПОТОКОВАЯ ПЕРЕДАЧА ЧАНКОВ (БЕЗ S3 И БЕЗ ДИСКОВ)
    loop Каждые 100мс записи звука
        APP->>API: Шлёт сырые бинарные чанки (PCM 16-bit 16kHz Bytes)
        API->>GRPC: Перенаправляет чанки байт в gRPC-стрим асинхронно
        Note over GRPC: Whisper декодирует входящий аудио-буфер "на лету"
    end

    %% ЭТАП 3: ЗАКРЫТИЕ СТРИМА И ФИКСАЦИЯ
    User->>APP: Нажимает Кнопку "Стоп"
    APP->>API: Шлёт маркер конца потока [EOF]
    API->>GRPC: Закрывает gRPC-канал инференса
    
    activate GRPC
    Note over GRPC: Финальный скоринг текста: "КОФЕ РАСТВОРИМЫЙ 2 шт"
    GRPC-->>API: Возвращает итоговую строку транскрипции
    deactivate GRPC

    activate API
    API->>API: clean_and_parse_ocr_line_dynamic() -> Вызов Левенштейна
    Note over API: Распаковка List в String -> Устранение DataError
    
    Note over API, DB: Старт атомарной SQL-транзакции
    API->>DB: INSERT INTO bupar_event_log (activity='PURCHASE') -> Лог для R
    API->>DB: INSERT INTO fridge_inventory ON CONFLICT DO NOTHING -> Новая запись
    
    API-->>APP: Отправляет в WebSocket финальный JSON с успехом
    deactivate API
    APP->>APP: Закрывает сокет соединения (connection close)
    APP->>DB: Авто-запрос GET /fridge/stock -> Обновляет балансы на экране

4 Сквозная бизнес-логика и ИИ-модерация

Процесс обработки запроса живого пользователя разделен на три этапа:

4.1 Этап 1: gRPC Цензурирование (ИИ-контур модерации)

Строка raw_text_input асинхронно перенаправляется во внутренний gRPC-сервер аналитики на метод CheckProduct для проверки на спам и ненормативную лексику.

  • Если ИИ-модератор возвращает статус REJECTED, бэкенд прерывает транзакцию и выбрасывает ошибку цензуры ERR-CENSOR (HTTP 400).
  • Стратегия Fail-Safe: Если gRPC-сервер оффлайн, система пишет предупреждение [Moderation Warning] в системный лог и пропускает запрос по сценарию ограниченного доверия, чтобы не блокировать действия реального человека.

4.2 Этап 2: Парсинг строки

Чистый текст разбивается по разделителям (пробелам). Первое слово интерпретируется как наименование продукта, второе — преобразуется в тип float как количество (дефолтное значение = 1.0).

4.3 Этап 3: Фиксация в PostgreSQL

Запись вносится в базу данных. В случае коллизии (если такой продукт уже добавлен в рамках этой семьи), логика инкремента остатков перенесена в метод ItemsMerge, другми словами добавляется еще один новый продукт. Если у вас в “холодильнике” были яблоки, то добавятся еще одна строка с яблоками.

5 Спецификация ответов сервера

5.1 Успешное добавление (201 Created)

{
  "status": "SUCCESS",
  "message": "Продукт 'Яблоки' успешно отмодерирован и добавлен текстовым контуром."
}

5.2 Ошибка модерации (400 Bad Request)

Возвращается, если ИИ-контур зафиксировал мат или спам в текстовом вводе реального пользователя.

{
  "code": "ERR-BUPAR-CENSOR",
  "detail": "Текст не прошел модерацию: обнаружена ненормативная лексика или спам."
}