Архитектура Экосистемы BPDS: Топология Шины Данных

Спецификация топиков Apache Kafka (KRaft)

Author

Lead Systems Architect / FoodLifeCycle Core Team

Published

July 13, 2026

Событийно-Ориентированная Топология Broker Kafka

Взаимодействие между доменами системы BPDS реализовано на базе распределенной шины данных Apache Kafka (11 топиков, архитектура KRaft). Для маршрутизации пакетов и обеспечения безопасности на уровне ACL применяется строго типизированный паттерн разделения топиков через точку, поддерживающий концепцию CQRS (разделение команд и событий):

\[\text{Паттерн: } \text{bpds}.\langle\text{домен}\rangle.\langle\text{направление}\rangle.\langle\text{ресурс}\rangle.\langle\text{действие}\rangle\]

Где: * bpds — неизменный префикс проекта. * направление — принимает значение in (Входящая команда/тяжелый стрим) или out (Исходящий подтвержденный факт/событие).

Маппинг и Спецификация Топиков (11 Production Topics)

Название топика Kafka Направление потока данных Продюсер (Producer) Потребитель (Consumer)
1 bpds.inventory.in.receipt.upload IN (Команда на разбор чека) shop-engine (1. Shop) ai-vision-worker (EasyOCR)
2 bpds.inventory.out.receipt.parsed OUT (Факт: чек успешно разобран) ai-vision-worker (EasyOCR) shop-engine \(\rightarrow\) fridge-ops
3 bpds.inventory.in.voice.stream IN (Потоковое аудио голоса) shop-engine / 3. Cook ai-speech-worker (Whisper)
4 bpds.inventory.out.voice.transcribed OUT (Факт: голос переведен в текст) ai-speech-worker (Whisper) shop-engine / cookbook
5 bpds.mdm.in.product.process IN (Запрос на карточку продукта) API Gateway (при Cache miss) ollama-llm-proxy (Structured)
6 bpds.mdm.out.product.templated OUT (Факт: сгенерирован шаблон) ollama-llm-proxy product-registry-service
7 bpds.mdm.in.recipe.synthesize IN (Команда на парсинг текста) Веб-парсер / Админка ollama-llm-proxy
8 bpds.inventory.in.fridge_item.deduct IN (Команда на FIFO списание) recipe-cookbook (3. Cook) warehouse-fridge-ops (Склад)
9 bpds.inventory.out.meal_item.create OUT (Факт: готовое блюдо создано) warehouse-fridge-ops (Склад) bupar-audit / affinity-core
10 bpds.inventory.out.fridge_item.consume OUT (Факт: продукт утилизирован/съеден) warehouse-fridge-ops (4. Cons) affinity-prediction-core (+)
11 bpds.inventory.out.fridge_item.waste OUT (Факт: продукт выброшен в мусор) warehouse-fridge-ops (5. Waste) affinity-prediction-core (-)
12 bpds.iad.out.group.change OUT (Факт: изменение прав группы) auth-identity-service Все базы (Сброс кэша прав)
13 bpds.aid.out.profanity.violate OUT (Факт: лимит мата исчерпан) redis-profanity-censor auth-identity-service (Бан)
14 bpds.pma.out.process.event OUT (Сквозной бизнес-лог шага) Все микросервисы экосистемы bupar-audit-service \(\rightarrow\) UI

Маппинг и Спецификация Топиков (14 Production Topics)

Название топика Kafka Направление потока данных Продюсер (Producer) Потребитель (Consumer)
1 bpds.inventory.in.receipt.upload IN (Команда на разбор чека) shop-engine (1. Shop) ai-vision-worker (EasyOCR)
2 bpds.inventory.out.receipt.parsed OUT (Факт: чек успешно разобран) ai-vision-worker (EasyOCR) shop-engine \(\rightarrow\) fridge-ops
3 bpds.inventory.in.voice.stream IN (Потоковое аудио голоса) shop-engine / 3. Cook ai-speech-worker (Whisper)
4 bpds.inventory.out.voice.transcribed OUT (Факт: голос переведен в текст) ai-speech-worker (Whisper) shop-engine / cookbook
5 bpds.mdm.in.product.process IN (Запрос на карточку продукта) API Gateway (при Cache miss) ollama-llm-proxy (Structured)
6 bpds.mdm.out.product.templated OUT (Факт: сгенерирован шаблон) ollama-llm-proxy product-registry-service
7 bpds.mdm.in.recipe.synthesize IN (Команда на парсинг текста рецепта) Веб-парсер / Админка ollama-llm-proxy
8 bpds.inventory.in.fridge_item.deduct IN (Команда на каскадное FIFO списание весов) fridge-service (3. Cook) fridge-service (FIFO-движок)
9 bpds.inventory.out.meal_item.create OUT (Факт: готовое составное блюдо создано) fridge-service bupar-audit-service / affinity-prediction-core
10 bpds.inventory.out.fridge_item.consume OUT (Факт: продукт съеден) fridge-service (4. Consume) affinity-prediction-core
11 bpds.inventory.out.fridge_item.waste OUT (Факт: продукт выброшен в мусор) fridge-service (5. Waste) affinity-prediction-core
12 bpds.iad.out.group.change OUT (Факт: изменение состава группы / тарифа) auth-identity-service billing-service / fridge-service / affinity-prediction-core
13 bpds.aid.out.profanity.violate OUT (Факт: превышен лимит мата, бан сессии) censorship-control-worker auth-identity-service
14 bpds.pma.out.process.event OUT (Сквозной технический маркер шага процесса) Все микросервисы экосистемы bupar-audit-service

Мультитентовое Разделение Данных (Multi-Tenancy)

Разделение арендаторов (HOME / OFFICE) инкапсулировано внутри мета-заголовков каждого сообщения и поддерживается стратегией секционирования брокера. Partition Key строго равен meta.tenant.home_group_id. Это гарантирует, что все события по одной семье или офису попадают в одну и ту же партицию Kafka, обеспечивая строгую последовательность FIFO.

Архитектура Сообщения (Payload Blueprint)

Ниже представлен эталонный контракт сообщения для топика команды на списание bpds.inventory.in.fridge_item.deduct (Генерируется во Flutter при клике на кнопку 3. Cook):

{
  "meta": {
    "event_id": "evt-8830-bf-2026",
    "timestamp": "2026-07-13T06:05:00Z",
    "trace_id": "X-Request-ID-Dio-Client-77755",
    "direction": "IN",
    "tenant": {
      "home_group_id": "group-office-corporate-4",
      "account_type": "OFFICE",
      "user_id": "usr-991"
    }
  },
  "payload": {
    "command": "EXECUTE_FIFO_DEDUCTION",
    "context": {
      "case_id": "case-food-lifecycle-loop-4412",
      "recipe_id": 2085,
      "target_meal_name": "Компот Ягодный"
    },
    "ingredients": [
      {
        "element_id": "mdm-prod-102",
        "element_symbol": "St",
        "requested_weight_g": 500.0000
      },
      {
        "element_id": "mdm-prod-005",
        "element_symbol": "Wt",
        "requested_weight_g": 2500.0000
      }
    ]
  }
}

Назначение ключевых полей структуры:

  1. meta.trace_id: Сюда пробрасывается X-Request-ID от Flutter-клиента. Позволяет Promtail агрегировать логи обработки сообщения в Grafana Loki и отображать их на ObservabilityScreen.
  2. meta.tenant.account_type: Контурный флаг (OFFICE). Сигнализирует сервису warehouse-fridge-ops: в случае нехватки остатков при каскадном FIFO-списании, транзакцию необходимо жестко заблокировать по gRPC с кодом ошибки 422.
  3. payload.context.case_id: Сквозной маркер цепочки процессов. Перехватывается bupar-audit-service для отрисовки карт жизненного цикла продуктов (Process Mining).