Метод POST /api/v1/purchase/upload-voice

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

Author

Application & Simulation Services Framework Documentation

Published

June 11, 2026

WarningОграничение публичной документации

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

  • Полная спецификация метода: Будет доступна только во внутреннем контуре разработки (Confluence / Swagger Enterprise).

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

ImportantDocumentation Under Development

This documentation section is currently under development and may contain incomplete data. Some technical descriptions, parameters, and system operation scenarios for the digital business process simulator are subject to change.

  • Stable documentation version: Will be published upon final completion and validation of the method code.

This method is designed for the asynchronous processing of user voice notes, their automatic transcription into text using a speech recognition neural network (Whisper Tiny), and the subsequent addition of products to the refrigerator.

Within the updated architecture, this method acts as an Audio Context Provider:

  1. Media Stream Isolation: The binary audio file is saved by the FastAPI gateway into the MinIO S3 bucket.
  2. Asynchronous Transcription (Speech-to-Text): Heavy AI inference is offloaded from the API tier to an isolated grpc-analytics worker, which transcribes the audio recording into a text string.
  3. Filtering Perimeter Reuse: The worker routes the extracted string into the common bpds.inventory.in.receipt.upload topic. The censorship worker (censorship-control-worker) checks the recognized text for profanity and monitors the repeated use of profanity during any subsequent text editing.

Interaction Protocol (HTTP Contract)

  • Method: POST
  • Route: /api/v1/purchase/upload-voice
  • Data Format: multipart/form-data

Headers Specification (HTTP Headers)

Header Required Description Example Value
Content-Type Yes Indicates the transmission of composite form data (multipart). multipart/form-data; boundary=----WebKitFormBoundary...
Authorization Yes Access token used to extract the user_id and the multi-tenancy home_group_id stamp. Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
X-Request-ID Yes End-to-end request ID for tracing (FastAPI () MinIO () Kafka () Workers). req-voice-77bb-99aa

Query Parameters Specification

Parameter Type Required Description Example Value
app_lang String Yes Target application language used to adapt the system prompt at the downstream censorship phase. ru

Request Body Specification (Request Body — Multipart FormData)

Field Type Required Description Example Value
file Binary (File) Yes Raw binary data of the voice note audio file (audio/mpeg, audio/ogg). Constraint: up to 5 MB. voice_note.ogg

Raw HTTP Request Example (Payload):

POST /api/v1/purchase/upload-voice?app_lang=ru HTTP/1.1
Host: foodlifecycle.com
Authorization: Bearer eyJhbGciOiJIUzI1Ni...
X-Request-ID: req-voice-77bb-99aa
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="voice_note.ogg"
Content-Type: audio/ogg

[BINARY_AUDIO_STREAM_DATA]
------WebKitFormBoundary7MA4YWxkTrZu0gW--

Метод предназначен для асинхронной обработки голосовых заметок пользователя, их автоматического перевода в текст с помощью нейросети распознавания речи (Whisper Tiny) и последующего добавления продуктов в холодильник.

В рамках новой архитектуры этот метод выполняет роль поставщика аудио-контекста (Audio Context Provider):

  1. Изоляция медиа-потока: Бинарный аудио-файл сохраняется шлюзом FastAPI в S3-бакет MinIO.
  2. Асинхронная транскрибация (Speech-to-Text): Тяжелый ИИ-инференс вынесен из API-слоя в изолированный воркер grpc-analytics, который транслирует аудиозапись в текстовую строку.
  3. Переиспользование контура фильтрации: Воркер отправляет извлеченную строку в общий топик bpds.inventory.in.receipt.upload. Воркер цензуры проверяет распознанный текст на обсценную лексику (censorship-control-worker) и повторное использование обсценной лексики при редактуре текста.

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

  • Метод: POST
  • Маршрут: /api/v1/purchase/upload-voice
  • Формат данных: multipart/form-data

Спецификация заголовков (HTTP Headers)

Заголовок Обязательный Описание Пример значения
Content-Type Да Указывает на передачу составных данных формы (мультипарт) multipart/form-data; boundary=----WebKitFormBoundary...
Authorization Да Токен авторизации для извлечения user_id и Multi-Tenancy клейма home_group_id Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
X-Request-ID Да Сквозной ID запроса для трассировки (FastAPI \(\rightarrow\) MinIO \(\rightarrow\) Kafka \(\rightarrow\) Workers) req-voice-77bb-99aa

Спецификация параметров запроса (Query Parameters)

Параметр Тип Обязательный Описание Пример значения
app_lang String Да Целевой язык приложения для адаптации системного промпта на этапе цензуры ru

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

Поле Тип Обязательный Описание Пример значения
file Binary (File) Да Бинарный аудиофайл голосовой заметки (audio/mpeg, audio/ogg). Ограничение: до 5 МБ. voice_note.ogg

Пример HTTP-запроса (Payload):

POST /api/v1/purchase/upload-voice?app_lang=ru HTTP/1.1
Host: foodlifecycle.com
Authorization: Bearer eyJhbGciOiJIUzI1Ni...
X-Request-ID: req-voice-77bb-99aa
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="voice_note.ogg"
Content-Type: audio/ogg

[БИНАРНЫЕ ДАННЫЕ АУДИОПОТОКА]
------WebKitFormBoundary7MA4YWxkTrZu0gW--

Диаграмма последовательности (Mermaid)

ImportantDocumentation Under Development

This documentation section is currently under development and may contain incomplete data. Some technical descriptions, parameters, and system operation scenarios for the digital business process simulator are subject to change.

  • Stable documentation version: Will be published upon final completion and validation of the method code.

sequenceDiagram
    autonumber
    actor User as Mobile Client (App)
    participant GW as FastAPI Gateway (backend-api)
    participant S3 as MinIO Object Storage
    participant K as Apache Kafka Cluster
    participant AudioAI as voice-speech-processor (AID)
    participant Censor as censorship-control-worker (SECURITY)

    %% STEP 1: FILE UPLOAD AND TASK DELEGATION
    User->>GW: POST /api/v1/purchase/upload-voice (Multipart Form Data)
    GW->>S3: PutObject: Save .mp3/.ogg binary stream
    S3-->>GW: Return audio_file_url
    Note over GW: Step 3: X-Request-ID (trace_id) Generation<br/>& Payload Assembly with app_lang
    GW->>K: Push to topic: bpds.inventory.in.voice.stream
    GW-->>User: HTTP 202 Accepted (File uploaded, session processing initiated)

    %% STEP 2: TRANSCRIPTION
    K->>AudioAI: Handler: ProcessVoiceStream()
    AudioAI->>S3: GetObject: Download binary audio via URL
    S3-->>AudioAI: Binary audio stream
    Note over AudioAI: Step 5: Local Whisper Tiny Inference<br/>Translate sound waves into a raw text string
    AudioAI->>K: Push to topic: bpds.inventory.in.receipt.upload

sequenceDiagram
    autonumber
    actor User as Мобильный клиент (App)
    participant GW as FastAPI Gateway (backend-api)
    participant S3 as MinIO Object Storage
    participant K as Apache Kafka Cluster
    participant AudioAI as voice-speech-processor (AID)
    participant Censor as censorship-control-worker (SECURITY)

    %% ШАГ 1: ЗАГРУЗКА ФАЙЛА И ПУШ ЗАДАЧИ
    User->>GW: POST /api/v1/purchase/upload-voice (Multipart Form Data)
    GW->>S3: PutObject: Сохранение .mp3/.ogg бинарного потока
    S3-->>GW: Возврат audio_file_url
    Note over GW: Шаг 3: Генерация X-Request-ID (trace_id)<br/>Сборка payload с app_lang
    GW->>K: Пуш в топик: bpds.inventory.in.voice.stream
    GW-->>User: HTTP 202 Accepted (Файл загружен, сессия в обработке)

    %% ШАГ 2: ТРАНСКРИБАЦИЯ
    K->>AudioAI: Handler: ProcessVoiceStream()
    AudioAI->>S3: GetObject: Скачивание бинарного аудио по URL
    S3-->>AudioAI: Бинарный аудио-поток
    Note over AudioAI: Шаг 5: Инференс локального Whisper Tiny<br/>Перевод звуковых волн в сырую строку текста
    AudioAI->>K: Пуш в топик: bpds.inventory.in.receipt.upload

Расшифровка шагов

ImportantDocumentation Under Development

This documentation section is currently under development and may contain incomplete data. Some technical descriptions, parameters, and system operation scenarios for the digital business process simulator are subject to change.

  • Stable documentation version: Will be published upon final completion and validation of the method code.
Step Action Parameters / Requests / DTO Errors (Exceptions / Statuses)
1 (Gateway -> MinIO) The API Gateway captures the raw binary voice note stream (.mp3 or .ogg) from the user’s mobile client, validates its file headers, and streams it to the S3 bucket storage. S3 API PUT Object Request:
Bucket: "user-voice-streams", Key: "uploads/2026/07/voice_audio_99.ogg"
Headers: Content-Type: audio/ogg, Content-Length: 1048576
IAD-VOICE-422: Unsupported audio MIME type or corrupted codec audio signature.
IAD-VOICE-413: Binary audio stream size exceeds the established limit of 5 MB.
2 (MinIO -> Gateway) The block object storage successfully commits the media asset to disk arrays and returns a permanent or temporary (presigned) URL reference to the API Gateway. S3 API PUT Object Response:
HTTP Status: 200 OK
ETag: "68b329da9893e34099c7d8ad5cb9c940", URL: https://minio.internal
No business errors
3 (Gateway -> T_Voice) The gateway constructs the initial transcription task DTO, embeds the target application language metadata with the end-to-end trace ID, and pushes the event message to the broker. Kafka Message (Topic: bpds.inventory.in.voice.stream):
Payload: { "audio_file_url": "https://minio.internal", "app_lang": "ru-RU", "x_request_id": "trace-stt-censor-uuid" }
IAD-VAL-400: Mandatory session metadata properties are missing or invalid URL schema layout provided.
4 (T_Voice -> AudioAI) The specialized speech analysis microservice voice-speech-processor, acting as a listener on the voice task queue partition, polls the event transaction block. Kafka Consumer Poll Request:
Group_ID: "voice-speech-processors", Payload from Step 3 received.
Partition: 0, Offset: 12054
No business errors
5 (AudioAI -> MinIO) The transcription service executes a network read request on the direct storage link to fetch the target multi-media asset bytes into the isolated audio thread allocation memory. HTTP GET /user-voice-streams/uploads/2026/07/voice_audio_99.ogg:
Headers: Internal Auth Tokens. Output: raw binary audio stream byte buffer.
IAD-VOICE-404: Target source multi-media voice note file asset was not found or deleted from storage before processing.
6 (AudioAI -> T_Results) The local hardware-accelerated Whisper Tiny core decodes audio waves and maps them to text. The compiled raw string data is forwarded to the main upload channel. Kafka Message (Topic: bpds.inventory.in.receipt.upload):
Payload: { "raw_text_input": "Текст, который распознал Whisper из аудиозаписи с матом", "app_lang": "ru-RU", "x_request_id": "trace-stt-censor-uuid" }
IAD-WHISPER-422: Audio encoding is unreadable, corrupted due to extreme ambient noise, or inference core crashed.
Шаг Действие Параметры / Запросы / DTO Ошибки (Исключения / Статусы)
Шаг 1 (Gateway -> MinIO) API-шлюз принимает от клиента бинарный поток аудиосообщения (.mp3 или .ogg), валидирует заголовки и загружает файл в бакет объектного хранилища S3. S3 API PUT Object Request:
Bucket: "user-voice-streams", Key: "uploads/2026/07/voice_audio_99.ogg"
Headers: Content-Type: audio/ogg, Content-Length: 1048576
MinIOException: BucketNotFound
MinIOException: AccessDenied (истекли или неверны секретные ключи доступа шлюза)
StorageFullException
Шаг 2 (MinIO -> Gateway) Объектное хранилище успешно сохраняет медиафайл на дисковом массиве и возвращает шлюзу постоянную или временную (presigned) URL-ссылку на объект. S3 API PUT Object Response:
HTTP Статус: 200 OK
ETag: "68b329da9893e34099c7d8ad5cb9c940", URL: https://minio.internal
MinIOException: ConnectionTimeout (сетевой сбой во время финализации записи блока данных)
DiskWriteError
Шаг 3 (Gateway -> T_Voice) Шлюз формирует стартовый DTO задачи на транскрибацию, внедряет метаданные языка интерфейса, сквозной трассировочный ID и отправляет событие в шину. Kafka Message (Topic: bpds.inventory.in.voice.stream):
Payload: { "audio_file_url": "https://minio.internal", "app_lang": "ru-RU", "x_request_id": "trace-stt-censor-uuid" }
FastAPI.ValidationError (невалидный формат URL)
KafkaException: QueueFullException (буфер отправки брокера переполнен)
MessageTimedOut
Шаг 4 (T_Voice -> AudioAI) Специализированный микросервис анализа речи grpc-analytics, подписанный на топик аудиозадач, вычитывает событие из очереди для обработки. Kafka Consumer Poll Request:
Group_ID: "voice-stt-processors", Получен payload шага 3.
Partition: 0, Offset: 12054
KafkaException: CommitFailedException (сервис завис на предобработке, консьюмер выпал из группы)
SerializationException
Шаг 5 (AudioAI -> MinIO) Сервис транскрибации инициирует внутреннее скачивание файла по полученной ссылке из бакета S3 для его последующей загрузки в память модели. HTTP GET /user-voice-streams/uploads/2026/07/voice_audio_99.ogg:
Headers: Internal Auth Tokens. На выходе: бинарный поток байт аудиофайла во временный буфер.
HTTP 404 Not Found (файл был удален или ссылка сформирована некорректно)
HTTP 403 Forbidden
ConnectTimeout: MinIO endpoint dead
Шаг 6 (AudioAI -> T_Results) Локальная нейросеть Whisper Tiny переводит голос в текст. Полученная строка вместе с контекстом публикуется в общий топик распознанных чеков. Kafka Message (Topic: bpds.inventory.in.receipt.upload):
Payload: { "raw_text_input": "Текст, который распознал Whisper из аудиозаписи с матом", "app_lang": "ru-RU", "x_request_id": "trace-stt-censor-uuid" }
WhisperInferenceError (сбой декодирования кодека или сильный шум)
KafkaException: DeliveryTimeout
KafkaException: RecordTooLargeException
Шаг Действие Параметры / Запросы / DTO Ошибки (Исключения / Статусы)
1 (Gateway -> MinIO) API-шлюз принимает от клиента бинарный поток аудиосообщения (.mp3 или .ogg), валидирует заголовки и загружает файл в бакет объектного хранилища S3. S3 API PUT Object Request:
Bucket: "user-voice-streams", Key: "uploads/2026/07/voice_audio_99.ogg"
Headers: Content-Type: audio/ogg, Content-Length: 1048576
IAD-VOICE-422: Неподдерживаемый MIME-тип аудиофайла или нарушена сигнатура кодека.
IAD-VOICE-413: Размер бинарного аудиопотока превысил установленный лимит в 5 МБ.
2 (MinIO -> Gateway) Объектное хранилище успешно сохраняет медиафайл на дисковом массиве и возвращает шлюзу постоянную или временную (presigned) URL-ссылку на объект. S3 API PUT Object Response:
HTTP Статус: 200 OK
ETag: "68b329da9893e34099c7d8ad5cb9c940", URL: https://minio.internal
Бизнес-ошибки отсутствуют
3 (Gateway -> T_Voice) Шлюз формирует стартовый DTO задачи на транскрибацию, внедряет метаданные языка интерфейса, сквозной трассировочный ID и отправляет событие в шину. Kafka Message (Topic: bpds.inventory.in.voice.stream):
Payload: { "audio_file_url": "https://minio.internal", "app_lang": "ru-RU", "x_request_id": "trace-stt-censor-uuid" }
IAD-VAL-400: Отсутствуют обязательные метаданные сессии или передан некорректный формат схемы URL.
4 (T_Voice -> AudioAI) Специализированный микросервис анализа речи voice-speech-processor, подписанный на топик аудиозадач, вычитывает событие из очереди для обработки. Kafka Consumer Poll Request:
Group_ID: "voice-speech-processors", Получен payload шага 3.
Partition: 0, Offset: 12054
Бизнес-ошибки отсутствуют
5 (AudioAI -> MinIO) Сервис транскрибации инициирует внутреннее скачивание файла по полученной ссылке из бакета S3 для его последующей загрузки в память модели. HTTP GET /user-voice-streams/uploads/2026/07/voice_audio_99.ogg:
Headers: Internal Auth Tokens. На выходе: бинарный поток байт аудиофайла во временный буфер.
IAD-VOICE-404: Целевой аудиоресурс голосовой заметки не найден или был удален из S3 до начала чтения воркером.
6 (AudioAI -> T_Results) Локальная нейросеть Whisper Tiny переводит голос в текст. Полученная строка вместе с контекстом публикуется в общий топик распознанных чеков. Kafka Message (Topic: bpds.inventory.in.receipt.upload):
Payload: { "raw_text_input": "Текст, который распознал Whisper из аудиозаписи с матом", "app_lang": "ru-RU", "x_request_id": "trace-stt-censor-uuid" }
IAD-WHISPER-422: Не удалось декодировать аудиопоток из-за критического уровня шума или сбоя ядра инференса.

Спецификация ответов сервера, вилок исключений и таймаутов

ImportantDocumentation Under Development

This documentation section is currently under development and may contain incomplete data. Some technical descriptions, parameters, and system operation scenarios for the digital business process simulator are subject to change.

  • Stable documentation version: Will be published upon final completion and validation of the method code.

Успешный асинхронный ответ (HTTP 202 Accepted)

{
  "status": "PROCESSING",
  "data": {
    "trace_id": "req-voice-77bb-99aa",
    "message": "Аудиофайл успешно загружен. Запущен асинхронный контур ИИ-транскрибации Whisper Tiny.",
    "processed_at": "2026-07-21T02:30:00Z"
  }
}

Исключение: Неразборчивая речь / Сбой транскрибации (Асинхронный Исход 10б)

Формируется воркером, если коэффициент уверенности распознавания аудиомодели Whisper упал ниже 0.85.

{
  "error_code": "ERR-LOW-AUDIO-CONFIDENCE",
  "message": "Не удалось четко распознать голосовую заметку. Требуется ручное подтверждение.",
  "details": {
    "whisper_score": 0.58,
    "audio_snapshot_url": "s3://voice-streams/uuid-88.ogg",
    "action": "Render interactive draft card on UI with voice transcript placeholder field."
  }
}

Исключение: Ошибка ИИ-цензурирования (Асинхронный Исход 10в)

{
  "error_code": "ERR-BUPAR-CENSOR",
  "message": "Текст не прошел модерацию: обнаружена ненормативная лексика или спам.",
  "details": {
    "reason": "Spam or explicit content detected by Ollama Container within audio transcript."
  }
}

Политика распределенных таймаутов (Deadlines)

  • Таймаут инференса Whisper Tiny (Audio Worker): timeout = 3.0s (3000 миллисекунд). Выделяется на скачивание и транскрибацию 5-секундного аудиофайла. При превышении лимита — автоматический Fallback в MDM-топик.