Вот подробный системный промпт (System Definition), который описывает архитектуру, логику и контракт работы твоего OCR-сервиса. Сохрани этот текст как **`SYSTEM_PROMPT.md`** или в документацию проекта (Confluence/Wiki). К нему стоит обращаться при разработке API-клиентов, тестировании или доработке логики. --- # System Definition: RMSER OCR Service ## 1. Роль и Назначение **RMSER OCR Service** — это специализированный микросервис на базе FastAPI, предназначенный для извлечения структурированных данных (товарных позиций) из изображений кассовых чеков РФ. Сервис реализует **Гибридную Стратегию Распознавания**, отдавая приоритет получению верифицированных данных через ФНС, и используя оптическое распознавание (OCR) только как запасной вариант (fallback). ## 2. Логика Обработки (Workflow) При получении `POST /recognize` с изображением, сервис выполняет действия в строгой последовательности: ### Этап А: Поиск QR-кода (Priority 1) 1. **Детекция:** Сервис сканирует изображение на наличие QR-кода (библиотека `pyzbar`). 2. **Декодирование:** Извлекает сырую строку чека (формат: `t=YYYYMMDD...&s=SUM...&fn=...`). 3. **Запрос к API:** Отправляет сырые данные в API `proverkacheka.com` (или аналог). 4. **Результат:** * Если API возвращает успех: Возвращает идеальный список товаров. * **Метаданные ответа:** `source: "qr_api"`. ### Этап Б: Оптическое Распознавание (Fallback Strategy) *Запускается только если QR-код не найден или API вернул ошибку.* 1. **Препроцессинг (OpenCV):** * Поиск контуров документа. * Выравнивание перспективы (Perspective Warp). * Бинаризация (Adaptive Threshold) для подготовки к Tesseract. 2. **OCR (Tesseract):** Извлечение сырого текста (rus+eng). 3. **Парсинг (Regex):** * Поиск строк, содержащих паттерны цен (например, `120.00 * 2 = 240.00`). * Привязка текстового описания (названия товара) к найденным ценам. 4. **Результат:** Возвращает список товаров, найденных эвристическим путем. * **Метаданные ответа:** `source: "ocr"`. ## 3. Контракт API (Interface) ### Входные данные * **Endpoint:** `POST /recognize` * **Format:** `multipart/form-data` * **Field:** `image` (binary file: jpg, png, heic, etc.) ### Выходные данные (JSON) Сервис всегда возвращает объект `RecognitionResult`: ```json { "source": "qr_api", // или "ocr" "items": [ { "raw_name": "Молоко Домик в Деревне 3.2%", // Название товара "amount": 2.0, // Количество "price": 89.99, // Цена за единицу "sum": 179.98 // Общая сумма позиции }, { "raw_name": "Пакет-майка", "amount": 1.0, "price": 5.00, "sum": 5.00 } ], "raw_text": "..." // Сырой текст (для отладки) или содержимое QR } ``` ## 4. Технический Стек и Зависимости * **Runtime:** Python 3.10+ * **Web Framework:** FastAPI + Uvicorn * **Computer Vision:** OpenCV (`cv2`) — обработка изображений. * **OCR Engine:** Tesseract OCR 5 (`pytesseract`) — движок распознавания текста. * **QR Decoding:** `pyzbar` + `libzbar0`. * **External API:** `proverkacheka.com` (требует валидный токен). ## 5. Ограничения и Известные Проблемы 1. **Качество OCR:** В режиме `ocr` точность зависит от качества фото (освещение, помятость). Возможны ошибки в символах `3/8`, `1/7`, `З/3`. 2. **Зависимость от API:** Для работы режима `qr_api` необходим доступ в интернет и оплаченный токен провайдера. 3. **Скорость:** Режим `qr_api` работает быстрее (0.5-1.5 сек). Режим `ocr` может занимать 2-4 сек в зависимости от разрешения фото. ## 6. Инструкции для Интеграции При встраивании сервиса в общую систему (например, Telegram-бот или Backend приложения): 1. Всегда проверяйте поле `source`. Если `source == "ocr"`, помечайте данные для пользователя как "Требующие проверки" (Draft). Если `source == "qr_api"`, данные можно считать верифицированными. 2. Если массив `items` пустой, значит сервис не смог распознать чек (ни QR, ни текст не прочитался). Предложите пользователю переснять фото.