Метод POST /api/v1/gateway/upload-receipt

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

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 extraction of printed text from a receipt photo using Optical Character Recognition (OCR).

Within the architecture, this method acts as a Receipt Text Context Provider (OCR Context Provider):

  1. Network Thread Offloading: The binary multipart image stream is flushed by the gateway directly into the MinIO S3 bucket, preventing the UI subsystem from hanging.
  2. Line-by-Line Text Reading: Heavy graphical inference is offloaded to an asynchronous image-processor worker. Its task is to locate characters, normalize strings, and transform the pixel matrix into the raw text of the receipt.
  3. Filtering Perimeter Reuse: At Step 11, the worker routes the extracted text into the exact same bpds.inventory.in.receipt.upload topic that we designed for manual text entry. This allows the reuse of the existing censorship-control-worker without code duplication.

Interaction Protocol (HTTP Contract)

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

Headers Specification (HTTP Headers)

Header Required Description Example Value
Content-Type Yes Format for transmitting composite form data (multipart). multipart/form-data; boundary=----WebKitFormBoundary...
Authorization Yes User token for Multi-Tenancy isolation (user_id, home_group_id). Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
X-Request-ID Yes End-to-end request ID for tracing (FastAPI () MinIO () Kafka () OCR). req-8c2a-4b9d-99ef

Query Parameters Specification

Parameter Type Required Description Example Value
app_lang String Yes Application language used to adapt censorship dictionaries and prompts down the pipeline. ru

Request Body Specification (Request Body — Multipart FormData)

Field Type Required Description Example Value
file Binary (File) Yes Raw binary data of the paper receipt photo (image/jpeg, image/png). Limit: up to 10 MB. receipt_photo.jpg

HTTP Request Example (Payload):

POST /api/v1/purchase/upload-receipt?app_lang=ru HTTP/1.1
Host: foodlifecycle.com
Authorization: Bearer eyJhbGciOiJIUzI1Ni...
X-Request-ID: req-8c2a-4b9d-99ef
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary9XzR2YwkTrZu0gW

------WebKitFormBoundary9XzR2YwkTrZu0gW
Content-Disposition: form-data; name="file"; filename="receipt_photo.jpg"
Content-Type: image/jpeg

[BINARY_RECEIPT_IMAGE_DATA]
------WebKitFormBoundary9XzR2YwkTrZu0gW--

Метод предназначен для асинхронного извлечения печатного текста с фотографии чека с помощью оптического распознавания символов (OCR).

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

  1. Разгрузка сетевых потоков: Бинарный multipart-поток фотографии сбрасывается шлюзом в S3-бакет MinIO, избавляя подсистему от зависания UI.
  2. Построчное чтение текста: Тяжелый графический инференс вынесен в асинхронный воркер image-processor. Его задача — отыскать символы, нормализовать строки и превратить массив пикселей в сырой текст чека.
  3. Переиспользование контура фильтрации: На Шаге 11 воркер отправляет извлеченный текст в тот же самый топик bpds.inventory.in.receipt.upload, который мы спроектировали для ручного ввода текста. Это позволяет повторно использовать воркер цензуры (censorship-control-worker) без дублирования кода.

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

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

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

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

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

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

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

Поле Тип Обязательный Описание Пример значения
file Binary (File) Да Бинарный файл фотографии бумажного чека (image/jpeg, image/png). Лимит: до 10 МБ. receipt_photo.jpg

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

POST /api/v1/purchase/upload-receipt?app_lang=ru HTTP/1.1
Host: foodlifecycle.com
Authorization: Bearer eyJhbGciOiJIUzI1Ni...
X-Request-ID: req-8c2a-4b9d-99ef
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary9XzR2YwkTrZu0gW

------WebKitFormBoundary9XzR2YwkTrZu0gW
Content-Disposition: form-data; name="file"; filename="receipt_photo.jpg"
Content-Type: image/jpeg

[БИНАРНЫЕ ДАННЫЕ ИЗОБРАЖЕНИЯ ЧЕКА]
------WebKitFormBoundary9XzR2YwkTrZu0gW--

Диаграмма последовательности (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 App as APP (📱 Mobile Client)
    participant GW as GATEWAY (backend-api)
    participant S3 as MinIO Object Storage
    participant K as Broker: Apache Kafka
    participant OCR as image-processor (OCR)
    participant Censor as censorship-control-worker

    %% STEP 1: IMAGE UPLOAD AND TASK DELEGATION
    App->>GW: Step 1: POST /api/v1/purchase/upload-receipt (Multipart Photo, app_lang)
    activate GW
    GW->>S3: Step 2: PutObject: Save binary receipt photo
    activate S3
    S3-->>GW: Step 3: Return image_file_url
    deactivate S3
    
    note over GW: Step 4: X-Request-ID (trace_id) Generation<br/>& Payload Assembly with app_lang
    
    GW->>K: Step 5: Push to topic: bpds.inventory.in.receipt.image
    GW-->>App: Step 6: HTTP 202 Accepted (Gateway released)
    deactivate GW

    %% STEP 2: OCR PROCESSING
    K->>OCR: Step 7: Handler: ProcessReceiptImage()
    activate OCR
    OCR->>S3: Step 8: GetObject: Download binary file via URL
    activate S3
    S3-->>OCR: Step 9: Binary graphic stream
    deactivate S3
    
    note over OCR: Step 10: OCR Engine Inference<br/>Line-by-line text extraction from receipt photo
    
    OCR->>K: Step 11: Push to topic: bpds.inventory.in.receipt.upload
    deactivate OCR

Receipt Image Upload, Line-by-Line OCR Recognition, and Asynchronous Censorship Pipeline

sequenceDiagram
    autonumber
    
    actor App as APP (📱 Мобильный клиент)
    participant GW as GATEWAY (backend-api)
    participant S3 as MinIO Object Storage
    participant K as Брокер: Apache Kafka
    participant OCR as image-processor (OCR)
    participant Censor as censorship-control-worker

    %% ШАГ 1: ЗАГРУЗКА ИЗОБРАЖЕНИЯ И ПУШ ЗАДАЧИ
    App->>GW: Шаг 1: POST /api/v1/purchase/upload-receipt (Multipart Photo, app_lang)
    activate GW
    GW->>S3: Шаг 2: PutObject: Сохранение бинарного фото чека
    activate S3
    S3-->>GW: Шаг 3: Возврат image_file_url
    deactivate S3
    
    note over GW: Шаг 4: Генерация X-Request-ID (trace_id)<br/>Сборка payload с app_lang
    
    GW->>K: Шаг 5: Пуш в топик: bpds.inventory.in.receipt.image
    GW-->>App: Шаг 6: HTTP 202 Accepted (Шлюз свободен)
    deactivate GW

    %% ШАГ 2: OCR ОБРАБОТКА
    K->>OCR: Шаг 7: Handler: ProcessReceiptImage()
    activate OCR
    OCR->>S3: Шаг 8: GetObject: Скачивание бинарного файла по URL
    activate S3
    S3-->>OCR: Шаг 9: Бинарный графический поток
    deactivate S3
    
    note over OCR: Шаг 10: Инференс OCR-движка<br/>Построчное извлечение текста с фото чека
    
    OCR->>K: Шаг 11: Пуш в топик: bpds.inventory.in.receipt.upload
    deactivate OCR

Процесс загрузки фотографии чека, построчного OCR-распознавания и асинхронного цензурирования

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

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 receipt photo (.jpg or .png) from the user’s mobile client, validates its MIME type, and uploads the asset to the S3 bucket. S3 API PUT Object Request:
Bucket: "receipt-images", Key: "uploads/2026/07/receipt_photo_101.png"
Headers: Content-Type: image/png, Content-Length: 2097152
IAD-VISION-422: Unsupported mime-type format or invalid file signature layout.
IAD-VISION-400: The file payload was corrupted or damaged during data transmission.
2 (MinIO -> Gateway) The block object storage commits the incoming receipt image stream to disk and returns an internal direct URL reference of the asset to the API Gateway. S3 API PUT Object Response:
HTTP Status: 200 OK
ETag: "9b71d224bd62f3322d8d8a7c5cb9c111", URL: https://minio.internal
No business errors
3 (Gateway -> T_Receipt) The gateway generates a new OCR recognition task, embeds the target application language metadata with the end-to-end trace ID, and pushes the event message to the Kafka broker. Kafka Message (Topic: bpds.inventory.in.receipt.image):
Payload: { "image_file_url": "https://minio.internal", "app_lang": "ru-RU", "x_request_id": "trace-ocr-censor-uuid" }
IAD-VAL-400: Mandatory payload properties or technical tracing attributes are missing.
4 (T_Receipt -> ReceiptAI) The specialized image-processor microservice, subscribed to the receipt image topic, polls the next task event from the queue to run character extraction. Kafka Consumer Poll Request:
Group_ID: "receipt-ocr-processors", Payload from Step 3 received.
Partition: 1, Offset: 55410
No business errors
5 (ReceiptAI -> MinIO) The OCR service calls the object storage endpoint via the obtained URL address to fetch the image matrix binary stream into the local GPU/CPU execution memory allocation. HTTP GET /receipt-images/uploads/2026/07/receipt_photo_101.png:
Headers: Internal Auth Tokens. Output: raw binary graphics byte stream.
IAD-VISION-404: Target source image asset was not found or deleted from storage before processing.
6 (ReceiptAI -> T_Results) The local OCR engine reads text lines from the receipt photo. The entire extracted text dataset array is pushed to the unified upload topic along with the trace ID. Kafka Message (Topic: bpds.inventory.in.receipt.upload):
Payload: { "raw_text_input": "ФН 9999 ИНН 12345 ТОВАР С КОРРЕКТНЫМ ИЛИ С ПРОВОКАЦИОННЫМ НАЗВАНИЕМ", "app_lang": "ru-RU", "x_request_id": "trace-ocr-censor-uuid" }
IAD-OCR-422: Image is unreadable, blurred, or text segmentation rules failed to match characters.
Шаг Действие Параметры / Запросы / DTO Ошибки (Исключения / Статусы)
Шаг 1 (Gateway -> MinIO) API-шлюз принимает бинарный файл фотографии чека (.jpg или .png) со смартфона пользователя, проводит валидацию MIME-типа и загружает объект в S3. S3 API PUT Object Request:
Bucket: "receipt-images", Key: "uploads/2026/07/receipt_photo_101.png"
Headers: Content-Type: image/png, Content-Length: 2097152
MinIOException: BucketNotFound
MinIOException: InvalidDigest (повреждение файла при передаче)
StorageFullException
Шаг 2 (MinIO -> Gateway) Блочное объектное хранилище сохраняет изображение чека и возвращает API-шлюзу прямую внутреннюю URL-ссылку на объект. S3 API PUT Object Response:
HTTP Статус: 200 OK
ETag: "9b71d224bd62f3322d8d8a7c5cb9c111", URL: https://minio.internal
MinIOException: ConnectionTimeout
DiskWriteError (критический сбой RAID-массива хранилища)
Шаг 3 (Gateway -> T_Receipt) Шлюз генерирует задачу на OCR-распознавание, добавляет метаданные языка локали приложения, сквозной trace-id и отправляет сообщение в брокер Кафки. Kafka Message (Topic: bpds.inventory.in.receipt.image):
Payload: { "image_file_url": "https://minio.internal", "app_lang": "ru-RU", "x_request_id": "trace-ocr-censor-uuid" }
FastAPI.ValidationError (передан некорректный URL схемы)
KafkaException: QueueFullException
MessageTimedOut
Шаг 4 (T_Receipt -> ReceiptAI) Специализированный микросервис image-processor, подписанный на топик изображений чеков, вычитывает очередную задачу для извлечения символов. Kafka Consumer Poll Request:
Group_ID: "receipt-ocr-processors", Получен payload шага 3.
Partition: 1, Offset: 55410
KafkaException: CommitFailedException (зависание обработчика изображений чеков)
SerializationException
Шаг 5 (ReceiptAI -> MinIO) OCR-сервис обращается к объектному хранилищу по полученному URL-адресу для загрузки бинарной матрицы картинки в локальную память видеокарты/процессора. HTTP GET /receipt-images/uploads/2026/07/receipt_photo_101.png:
Headers: Internal Auth Tokens. На выходе: бинарный поток байт графического файла.
HTTP 404 Not Found (файл был удален из S3 до начала чтения воркером)
HTTP 403 Forbidden
ConnectTimeout
Шаг 6 (ReceiptAI -> T_Results) Локальный OCR-движок считывает текстовые строки с фото чека. Весь распознанный массив данных вместе с trace-id отправляется в общий топик загрузок. Kafka Message (Topic: bpds.inventory.in.receipt.upload):
Payload: { "raw_text_input": "ФН 9999 ИНН 12345 ТОВАР С КОРРЕКТНЫМ ИЛИ С ПРОВОКАЦИОННЫМ НАЗВАНИЕМ", "app_lang": "ru-RU", "x_request_id": "trace-ocr-censor-uuid" }
OCRError: ImageUnreadable (не удалось сегментировать текст или смазано фото)
KafkaException: DeliveryTimeout

Примеры ответов сервера

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.

Successful Asynchronous Response (HTTP 202 Accepted)

{
  "status": "PROCESSING",
  "data": {
    "trace_id": "req-8c2a-4b9d-99ef",
    "message": "File uploaded successfully. The asynchronous AI moderation circuit and line-by-line OCR receipt reading pipeline have been initiated.",
    "processed_at": "2026-07-21T02:15:00Z"
  }
}

Exception: Low Receipt Photo Quality / Blurred Text (Asynchronous Outcome 10b)

Generated by the worker if the average character recognition confidence score of the OCR engine drops below 0.85.

{
  "error_code": "ERR-LOW-OCR-CONFIDENCE",
  "message": "The receipt text was only partially recognized due to low photo quality. Manual moderation is required.",
  "details": {
    "ocr_score": 0.61,
    "receipt_snapshot_url": "s3://receipt-images/uuid-77.jpg",
    "action": "Render interactive draft receipt table on UI for manual correction fallback."
  }
}

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

{
  "status": "PROCESSING",
  "data": {
    "trace_id": "req-8c2a-4b9d-99ef",
    "message": "Файл успешно загружен. Запущен асинхронный контур ИИ-модерации и построчного OCR-чтения чека.",
    "processed_at": "2026-07-21T02:15:00Z"
  }
}

Исключение: Низкое качество фото чека / Размытый текст (Асинхронный Исход 10б)

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

{
  "error_code": "ERR-LOW-OCR-CONFIDENCE",
  "message": "Текст чека распознан частично из-за низкого качества фотографии. Требуется ручная модерация.",
  "details": {
    "ocr_score": 0.61,
    "receipt_snapshot_url": "s3://receipt-images/uuid-77.jpg",
    "action": "Render interactive draft receipt table on UI for manual correction fallback."
  }
}