Метод 14: generate_consumption_payload()

Домен: SIMULATION | Контур: Выбор готовой еды для обеда пользователя

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

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

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

1. Бизнес-спецификация метода

  • Идентификатор метода: BPDS-SIM-M014
  • Системное имя: generate_consumption_payload(context: TwinContext): ConsumeProductPayload
  • Микросервис: simulation-core-engine
  • Домен: SIMULATION
  • Класс / Компонент: simulation.engine.helpers.ConsumptionPayloadGenerator

1.1. Описание логики работы

Этот метод отвечает за подбор доступного для немедленного употребления продукта в холодильнике, когда на Шаге 9 выпал сценарий Потребления еды (SCENARIO_CONSUMING_FOOD). Поскольку у пользователя в голове нет абстрактных параметров, само бытовое действие запускается физиологическим сигналом голода.

Метод сканирует оперативную память в поисках готовых блюд (READY_MEALS) или штучных продуктов быстрого перекуса (например, йогуртов или сэндвичей с типом Ready-to-eat). Характер пользователя отдает приоритет готовой еде — ленивый пользователь предпочитает съесть то, что не требует готовки. Метод находит первый подходящий продукт, фиксирует объем порции и упаковывает данные в команду для отправки бэкенду.

Если в холодильнике абсолютно пусто, метод прерывается с ошибкой. Пользователь остается голодным, его показатель голода продолжит расти, что заставит его гарантированно идти за покупками в магазин на следующих тактах.

1.2. Пошаговое выполнение

  1. Проверка инвентаря: Метод запрашивает список продуктов пользователя, сохраненный в объекте TwinContext.
  2. Фильтрация готового: Программа ищет в массиве продукты, которые относятся к макро-категории READY_MEALS или имеют фабричный маркер типа Ready-to-eat.
  3. Выделение продукта: Метод берет первый доступный готовый продукт и фиксирует его уникальный номер (fridge_item_id).
  4. Фиксация порции: Объем порции для потребления готового блюда или йогурта жестко выставляется в 1.0000 штуку.
  5. Контроль пустоты: Если готовых продуктов в холодильнике не найдено, метод выбрасывает ошибку дефицита еды, оставляя пользователя голодным.
  6. Упаковка: Данные UUID продукта и объем порции упаковываются в иммутабельный JSON-payload для передачи сетевому контуру отправки (Метод 15).

2. Диаграмма последовательности метода (Вход и Выход флоу)

Диаграмма наглядно показывает, как метод принимает контекст, проверяет наличие готовой еды в оперативной памяти и формирует команду на поедание продукта.

sequenceDiagram
    autonumber
    participant Core as Метод 3
    participant G as ConsumptionPayloadGenerator
    participant RAM as Данные пользователя

    %% ВХОД МЕТОДА
    Core->>G: Вызов generateConsumptionPayload
    activate G
    Note over G: Вход метода: TwinContext со списком продуктов в холодильнике
    
    G->>RAM: Запрос списка продуктов rawFridgeSnapshot
    RAM-->>G: Возврат: Список продуктов Твина
    
    %% ВНУТРЕННИЙ ПОДБОР ГОТОВОЙ ЕДЫ
    G->>G: Фильтрация продуктов по категории READY MEALS или типу Ready to eat
    
    alt Ситуация: Готовая еда не найдена (В холодильнике пусто)
        Note over G: Прерывание: Выброс ошибки FoodMissingException
    end
    
    G->>G: Формирование ConsumeProductPayload (Порция = 1.0000)
    Note over G: Выход метода: Сформированный и готовый к отправке по сети DTO поедания продукта
    
    G-->>Core: Возврат: Пакет потребления ConsumeProductPayload DTO
    deactivate G


3. Схемы данных и SQL-взаимодействие

Этот метод обрабатывает извлеченный массив объектов внутри оперативной памяти симулятора и напрямую запросы к PostgreSQL симулятора на этом шаге не делает. Все UUID продуктов уже лежат в переданном объекте TwinContext.


4. Спецификация обмена данными (Вход / Выход)

Данные подготавливаются для отправки на прикладной эндпоинт потребления еды бэкенда приложения.

4.1. Входной состав холодильника пользователя в памяти (Входные параметры)

В холодильнике бэкенда лежит один готовый йогурт:

{
  "twin_id": "d3b07384-d113-4956-bf8a-e421cd7bf777",
  "current_tick": 105,
  "raw_fridge_snapshot": [
    {
      "fridge_item_id": "aa11b432-8411-4c12-a111-9992345bcbc9",
      "sku": "YOGURT_AMAL_READY",
      "category_id": "READY_MEALS",
      "item_type": "Ready-to-eat",
      "quantity": 1.0000
    }
  ]
}

4.2. Сформированная JSON-команда списания съеденной еды (Выходные параметры для Метода 15)

Симулятор указывает бэкенду точный UUID продукта, который пользователь съел:

{
  "fridge_item_id": "aa11b432-8411-4c12-a111-9992345bcbc9",
  "consume_quantity": 1.0000,
  "consumed_at": "2026-08-11T10:24:00Z"
}

5. ЗАДАЧА ДЛЯ РАЗРАБОТЧИКА: BACKEND

Заголовок: Реализация хелпера подбора и списания готовой еды generate_consumption_payload

5.1. Что нужно сделать

  1. Создать Java-класс ConsumptionPayloadGenerator в пакете simulation.engine.helpers и пометить его аннотацией @Component.
  2. Написать метод generateConsumptionPayload, принимающий TwinContext.
  3. С помощью Java Streams отфильтровать список context.rawFridgeSnapshot(), выделив продукты с макро-категорией READY_MEALS или признаком типа Ready-to-eat (без учета регистра). Из результатов взять первый доступный продукт через .findFirst().
  4. Добавить валидацию: если готовых к употреблению продуктов в списке не найдено, выбрасывать контролируемое бизнес-исключение FoodMissingException. Это прервет текущий такт выполнения, оставив Твина голодным, что приведет к неизбежному штурму магазина покупками на следующих часовых тактах.
  5. Сформировать результирующий DTO-объект ConsumeProductPayload, указав в нем fridgeItemId выбранного продукта, объем порции BigDecimal.valueOf(1.0000) и текущий таймстамп, после чего вернуть его оркестратору.

6. ЗАДАЧА ДЛЯ РАЗРАБОТЧИКА: МИГРАЦИЯ

Заголовок: Конфигурация каскадного удаления для логов потребления в СУБД бэкенда при удалении UUID продуктов

6.1. Что нужно сделать

Когда прикладной эндпоинт бэкенда приложения розничной сети Алматы принимает команду симулятора на поедание еды и физически удаляет строку продукта из таблицы public.fridge_products, база данных должна автоматически зачищать связанные исторические записи. Чтобы в СУБД бэкенда не скапливались «сиротские» строки (Orphan Rows), задача миграции — наложить ограничение внешнего ключа с каскадным удалением в схеме public бэкенда.

-- Изменения для базы данных бэкенда розничной сети (схема public)
ALTER TABLE public.fridge_consumption_logs
DROP CONSTRAINT IF EXISTS fk_fridge_product_id;

ALTER TABLE public.fridge_consumption_logs
ADD CONSTRAINT fk_fridge_product_id
FOREIGN KEY (fridge_item_id) 
REFERENCES public.fridge_products (fridge_item_id)
ON DELETE CASCADE;