Бизнес-процессы приложения (BPMN)

Часть 1: Асинхронный пайплайн импорта, ИИ-распознавания и модерации чеков ОФД

Author

Lead Systems Architect / Business Process Analyst

Published

July 14, 2026

1. Архитектурный регламент моделирования BPMN

При проектировании событийно-ориентированных процессов симулятора FoodLifeCycle ключевой задачей нотации BPMN является визуализация асинхронных межсервисных переходов и точек контроля данных. Процесс импорта продуктов построен по паттерну Fire-and-Forget (Пожар-и-Забыл): тяжелый инференс нейросетей на GPU полностью изолирован от UI мобильного АРМ foodlifecyclemobile1.

Для обеспечения сквозного аудита процессов (Process Mining), каждый шаг диаграммы генерирует стандартизированный маркер в аналитический топик №14 (bpds.pma.out.process.event), где bupar-audit-service агрегирует шаги в цепочки по уникальному case_id.

2. Сквозная BPMN-диаграмма процесса импорта чеков

Диаграмма наглядно разделяет зоны ответственности между Пользователем, Системным шлюзом и Тяжелыми GPU-воркерами (ИИ-слой). Ветвление ромба иллюстрирует петлю обратной связи — ИИ-модерацию при низком уровне уверенности распознавания номенклатур.

Receipt_Processing_BPMN Start_Event START U_Snap 1. Фотографирование чека ОФД / QR Start_Event->U_Snap End_Success END Gateway_Confidence G_Ticket 5. Изоляция в буфер moderation_tickets Gateway_Confidence->G_Ticket Low Confidence G_Commit 8. Фиксация транзакции в billing_db / fridge_db Gateway_Confidence->G_Commit Уверенность > 85% G_Upload 2. Сохранение в S3 + HTTP 202 Accepted U_Snap->G_Upload  S3 URL   U_Review 6. Ручная правка черновика в App U_Approve 7. Подтверждение пакета расходов U_Review->U_Approve U_Approve->G_Commit  HTTP POST   AI_OCR 3. Инференс EasyOCR (Извлечение текста) G_Upload->AI_OCR  Топик №1   G_Ticket->U_Review  Push Alert   G_Commit->End_Success Bupar_Log bpds.pma.out.process.event (Activity Log: PURCHASED) G_Commit->Bupar_Log AI_NER 4. Ollama Structured Outputs (БЖУ-паспорт) AI_OCR->AI_NER  Топик №2   AI_NER->Gateway_Confidence  Каноничный JSON  

Receipt_Processing_BPMN_Lanes cluster_lane_user Pool: foodlifecyclemobile1 (АРМ Пользователя) cluster_lane_gateway Pool: backend-api / mdm-service (Серверный эшелон) cluster_lane_ai Pool: ai-orchestration-domain ( Heavy GPU Инференс ) Start_Event START U_Snap 1. Снимок чека ОФД / QR (foodlifecyclemobile1) Start_Event->U_Snap G_Upload 2. Загрузка в S3 MinIO + HTTP 202 Accepted U_Snap->G_Upload  S3 Object URL   U_Review 6. Корректировка черновика (Экран модерации) U_Approve 7. Тап кнопки 'Подтвердить' (Зачисление расходов) U_Review->U_Approve G_Commit 8. Транзакционный коммит в СУБД fridge_db / billing_db U_Approve->G_Commit  HTTP POST /approve   Gateway_Confidence G_Ticket 5. Создание черновика в moderation_tickets Gateway_Confidence->G_Ticket Низкая уверенность Gateway_Confidence->G_Commit Уверенность > 85% AI_OCR 3. Извлечение строк текста (image-processor: EasyOCR) G_Upload->AI_OCR  bpds.inventory.in.receipt.upload (Топик №1)   G_Ticket->U_Review  FCM Push Alert   End_Success END G_Commit->End_Success AI_NER 4. Структурирование БЖУ (purchase-ollama-worker) AI_OCR->AI_NER  bpds.inventory.out.receipt.parsed (Топик №2)   AI_NER->Gateway_Confidence  Каноничный JSON  

3. Регламент шагов и оркестрации данных

  1. Шаг 1 (U_Snap): Пользователь нажимает кнопку 1. Shop. Камера захватывает фрейм. Сессия метится сквозным trace_id.
  2. Шаг 2 (G_Upload): Файл отправляется в MinIO S3. Интерфейс Flutter разблокируется мгновенно благодаря асинхронному статусу HTTP 202 Accepted. Задача пушится в топик bpds.inventory.in.receipt.upload (Топик №1).
  3. Шаг 3-4 (AI_OCR / AI_NER): GPU-контейнеры обрабатывают текст. Если Ollama возвращает строгую JSON-структуру БЖУ с высоким коэффициентом уверенности, шаг модерации пропускается.
  4. Шаг 5-6 (G_Ticket / U_Review): При нечетком сканировании данные улетают в таблицу moderation_tickets СУБД mdm_db. Пользователь получает пуш-нотификацию, корректирует черновик на экране смартфона и закрывает тикет.
  5. Шаг 8 (G_Commit): Происходит двойной атомарный коммит: сумма чека фиксируется в billing_db, а партии товаров зачисляются поштучно во fridge_db. bupar-audit-service перехватывает финал и вносит запись PRODUCT_BATCH_PURCHASED в bupar_db по маркеру case_id.

4. Архитектурный контекст кулинарного контура (COOK)

Вторая часть спецификации описывает сквозной бизнес-процесс кулинарного цикла платформы FoodLifeCycle, запускаемый по нажатию кнопки 3. Cook. В отличие от асинхронного ИИ-пайплайна закупок, процесс приготовления еды является синхронным и жестко транзакционным.

Ключевой вызов проектирования — оркестрация gRPC-взаимодействия между recipes-service (который хранит тех-карты) и fridge-service (который управляет остатками). Процесс должен атомарно выполнить итерационную проверку и списание партий сырья по правилу FIFO, не создавая взаимных блокировок в fridge_db. Любое отклонение (нехватка объемов в контуре OFFICE) должно мгновенно прерывать цепочку и транслировать каноничный код ошибки на фронтенд.

5. Сквозная BPMN-диаграмма кулинарного процесса

Диаграмма наглядно иллюстрирует цикл перебора партий внутри FIFO-движка холодильника и разветвление логики в зависимости от типа мультитендентного пространства (HOME / OFFICE) при обнаружении виртуальных недостач.

Cook_Loop_BPMN Start_Cook START U_Select 1. Выбор рецепта в Кулинарной книге Start_Cook->U_Select End_Success SUCCESS End_Rollback FAIL 422 Gateway_Stock_Check Gateway_Tenant_Type Gateway_Stock_Check->Gateway_Tenant_Type НЕТ (quantity < 0) F_Cooked 5. Зачисление блюда status 'is_cooked = TRUE' Gateway_Stock_Check->F_Cooked ДА (quantity >= 0) U_Error Отображение ошибки INSUFFICIENT_STOCK Gateway_Tenant_Type->U_Error Контур = OFFICE F_Mask Разрешить теневой минус (Маскировка в 0 на UI) Gateway_Tenant_Type->F_Mask Контур = HOME R_Validate 2. gRPC: Валидация тех-карты в recipes_db U_Select->R_Validate  trace_id   U_Error->End_Rollback  ROLLBACK   F_Sort 3. Сортировка партий сырья ORDER BY created_at ASC R_Validate->F_Sort  gRPC   F_Deduct 4. Итеративное FIFO вычитание quantity = quantity - вес F_Sort->F_Deduct F_Deduct->Gateway_Stock_Check  Выход за рамки остатка?   F_Mask->F_Cooked F_Cooked->End_Success  COMMIT   Bupar_Log bpds.pma.out.process.event (Activity Log: COOKED) F_Cooked->Bupar_Log

Cook_Loop_BPMN_Lanes cluster_lane_cook_user Pool: foodlifecyclemobile1 (АРМ Пользователя) cluster_lane_cook_server Pool: fridge-service / recipes-service (Транзакционное ядро) Start_Cook START U_Select 1. Выбор рецепта блюда в Кулинарной книге Start_Cook->U_Select End_Rollback FAIL 422 R_Validate 2. gRPC: Чтение тех-карт и БЖУ из recipes_db U_Select->R_Validate  trace_id   U_Error Отображение ошибки INSUFFICIENT_STOCK U_Error->End_Rollback  ROLLBACK   Gateway_Stock_Check Gateway_Tenant_Type Gateway_Stock_Check->Gateway_Tenant_Type Дефицит (quantity < 0) F_Cooked 5. Выпуск блюда status 'is_cooked = TRUE' Gateway_Stock_Check->F_Cooked Хватает (quantity >= 0) Gateway_Tenant_Type->U_Error Контур = OFFICE F_Mask Разрешить теневой минус (Маскировка в 0 на UI) Gateway_Tenant_Type->F_Mask Контур = HOME F_Sort 3. Сортировка партий ORDER BY created_at ASC R_Validate->F_Sort  gRPC   F_Deduct 4. Итеративное FIFO вычитание quantity = quantity - вес F_Sort->F_Deduct F_Deduct->Gateway_Stock_Check F_Mask->F_Cooked End_Success SUCCESS COMMIT F_Cooked->End_Success

6. Регламент шагов кулинарной оркестрации

  1. Выбор и Валидация (Шаги 1-2): Пользователь тапает на карточку блюда. backend-api прокидывает команду в recipes-service. Происходит чтение состава тех-карты. Если рецепт удален, система мгновенно выбрасывает MDM_RECIPE_NOT_FOUND (HTTP 404).
  2. FIFO-Сортировка (Шаг 3): fridge-service открывает транзакцию в fridge_db и выстраивает партии нужных ингредиентов по дате создания (created_at ASC), чтобы первыми расходовать продукты, у которых первыми истекает срок годности.
  3. Итеративный вычет (Шаг 4): Объем уменьшается. Если текущая партия исчерпана, её quantity становится равным 0, и алгоритм переходит к следующей записи.
  4. Обработка дефицита (Шлюзы):
    • Если общего объема всех партий не хватило, а сессия принадлежит группе OFFICE, транзакция полностью откатывается (ROLLBACK), предотвращая кражу чужой еды на общей кухне. На фронтенд возвращается gRPC-код FAILED_PRECONDITION.
    • Если сессия принадлежит группе HOME, fridge-service разрешает загнать баланс конкретной партии в минус (виртуальная недостача), чтобы не ломать сценарий симуляции, если семья просто забыла сфотографировать новый чек.
  5. Выпуск готового блюда (Шаг 5): В базу записывается новая сущность (например, «Суп Борщ») объемом в порциях и флагом is_cooked = TRUE. bupar-audit-service асинхронно забирает событие из топика №14 (bpds.pma.out.process.event) и склеивает пройденные яблоками и мясом шаги в общую цепочку Process Mining по case_id.

7. Архитектурный контекст прямого выбытия и фоновых регламентов

Третья часть спецификации регламентирует операционные процессы выбытия продуктов без кулинарной обработки. Сюда входят прямое ручное съедение продуктов (CONSUME), утилизация испорченной еды (WASTE) с использованием речевого ИИ-инференса (Whisper tiny), а также автономный фоновый процесс автоматического списания просроченных товаров.

Ключевой вызов проектирования — оркестрация асинхронного голосового ввода с контролем текстовой безопасности [bupar-audit-service]. Потоковая аудиозапись рапорта пользователя проходит сквозную цензуру. В случае обнаружения обсценной лексики система должна атомарно инкрементировать счетчик нарушений в Redis и принудительно терминировать сессию при превышении лимита (2 попытки), защищая ИИ-симуляцию от загрязнения.

8. Сквозная BPMN-диаграмма выбытия и фонового списания

Диаграмма декомпозирует шаги пользователя при голосовом списании отходов, логику ветвления ИИ-цензора, а также изолированный автономный процесс ночного планировщика Celery Beat.

Waste_and_Cron_BPMN Start_Voice START VOICE U_Record 1. Удержание кнопки микрофона и диктовка рапорта порчи Start_Voice->U_Record Start_Cron 03:00 F_Cron_Scan Фоновое сканирование СУБД WHERE expired_at < NOW() Start_Cron->F_Cron_Scan End_Waste END OK End_Ban BAN 403 Gateway_Profanity AI_Lua_Inc Инкремент Redis Abuse Counter (Lua script: count = count + 1) Gateway_Profanity->AI_Lua_Inc ДА F_FIFO_Waste 4. Каскадное FIFO-удаление веса из fridge_inventory Gateway_Profanity->F_FIFO_Waste НЕТ Gateway_Abuse_Limit Gateway_Abuse_Limit->U_Record НЕТ (Предупреждение) U_Ban_Screen Экран принудительной блокировки АРМ Gateway_Abuse_Limit->U_Ban_Screen ДА AI_Whisper 2. Whisper tiny STT Инференс (Транскрибация аудиофайла) U_Record->AI_Whisper  Аудиострим S3   U_Ban_Screen->End_Ban  Топик №13 (Авто-бан)   AI_Censor 3. Проверка строки на мат (censorship-control-worker) AI_Whisper->AI_Censor  Топик №1   AI_Censor->Gateway_Profanity  Обнаружен мат?   AI_Lua_Inc->Gateway_Abuse_Limit  Счетчик >= 2?   F_FIFO_Waste->End_Waste  Commit   Bupar_Log_Waste bpds.pma.out.process.event (Activity Log: FOOD_WASTED) F_FIFO_Waste->Bupar_Log_Waste F_Auto_Clear Обнуление объема просрочки + Статус 'EXPIRED' F_Cron_Scan->F_Auto_Clear  Найдены батчи   F_Auto_Clear->End_Waste Bupar_Log_Cron bpds.pma.out.process.event (Log: SHORTAGE_RECONCILED) F_Auto_Clear->Bupar_Log_Cron

Waste_and_Cron_BPMN_Lanes cluster_lane_waste_user Pool: foodlifecyclemobile1 (АРМ Пользователя) cluster_lane_waste_ai Pool: ai-orchestration-domain ( GPU Heavy ИИ-слой ) cluster_lane_waste_server Pool: fridge-service / waste-service (Складской эшелон) Start_Cron 03:00 F_Cron_Scan Фоновое сканирование СУБД WHERE expired_at < NOW() Start_Cron->F_Cron_Scan Start_Voice START VOICE U_Record 1. Удержание микрофона и диктовка рапорта порчи Start_Voice->U_Record End_Ban BAN 403 AI_Whisper 2. Whisper tiny STT Инференс (Транскрибация аудиофайла) U_Record->AI_Whisper  Аудио в S3   U_Ban_Screen Экран принудительной блокировки АРМ U_Ban_Screen->End_Ban  Топик №13   Gateway_Profanity AI_Lua_Inc Инкремент Redis Abuse Counter (Lua script: count = count + 1) Gateway_Profanity->AI_Lua_Inc Обнаружен мат F_FIFO_Waste 4. Каскадное FIFO-удаление веса из fridge_inventory Gateway_Profanity->F_FIFO_Waste Чистая речь Gateway_Abuse_Limit Gateway_Abuse_Limit->U_Record Счетчик < 2 (Предупреждение) Gateway_Abuse_Limit->U_Ban_Screen Счетчик >= 2 AI_Censor 3. Проверка строки на мат (censorship-control-worker) AI_Whisper->AI_Censor  Топик №1   AI_Censor->Gateway_Profanity AI_Lua_Inc->Gateway_Abuse_Limit End_Waste END OK F_FIFO_Waste->End_Waste F_Auto_Clear Обнуление объема просрочки + Статус 'EXPIRED' F_Cron_Scan->F_Auto_Clear  Дедлайн < NOW()   F_Auto_Clear->End_Waste

9. Регламент шагов и автоматизации выбытия

  1. Голосовой рапорт и Whisper-инференс (Шаги 1-2): Находясь на кухне, пользователь удерживает кнопку 5. Waste и диктует: «Выбросил 400 грамм протухшего молока». Аудиочанги аккумулируются в MinIO S3. Сервис grpc-analytics Речь Голос вычитывает топик №1, скачивает аудиофайл и транскрибирует его в сырой текст с помощью модели Whisper tiny.
  2. ИИ-Цензура и Блокировка (Шаг 3 и Шлюзы): Текст пушится в топик bpds.inventory.in.receipt.upload и перехватывается censorship-control-worker.
    • Если обсценная лексика не обнаружена, строка парсится Ollama, и waste-service через fridge-service проводит каскадный FIFO-вычет испорченного объема еды.
    • Если зафиксирован мат, срабатывает атомарный Redis Lua-скрипт инкремента. При достижении violation_count >= 2 воркер публикует критическое событие в топик №13 (bpds.aid.out.profanity.violate). Сессия авторизации пользователя аннулируется в auth-service, токен заносится в Blacklist, а приложение переходит на жесткий экран блокировки SECURITY_PROFANITY_BAN (HTTP 403).
  3. Автономная ночная утилизация просрочки (Celery Beat): В 03:00 ночи, когда симуляторы неактивны, планировщик Celery Beat запускает метод reconcile базы данных Fridge_db. Робот сканирует партии товаров, выявляет позиции с условием expired_at < NOW(), принудительно обнуляет их quantity и переводит в статус EXPIRED.
  4. След в Process Mining: Как при ручной утилизации отходов (FOOD_WASTED), так и при автоматическом ночном списании просрочки роботом (SHORTAGE_RECONCILED), система отправляет JSONB-слепки параметров в топик №14 (bpds.pma.out.process.event). bupar-audit-service фиксирует эти данные, завершая жизненный цикл конкретного продукта на глобальном аналитическом дашборде.