Перейти к содержанию

Очередь приёма

Модуль лояльности принимает часть команд изменения баланса (начисление, списание, резерв) асинхронно: внешняя система отправляет команду, получает подтверждение приёма и не ждёт результата. Приём кладёт команду в очередь, отдельный обработчик исполняет её поверх обычного пути начисления/списания. Экран «Очередь приёма» — рабочее место оператора, который разбирает то, что в этой очереди застряло.

Существующие синхронные точки приёма (события покупки, интеграционные ручки) не заменяются асинхронным входом и не считаются устаревшими: синхронный отклик по-прежнему нужен, например, на кассе при создании резерва.

Когда команда требует внимания оператора

Обработчик повторяет неудавшуюся команду с нарастающей паузой. Если команда неисполнима в принципе (неизвестный тип, неразбираемое тело, неизвестный клиент или субсчёт) или исчерпала допустимое число попыток — она переходит в состояние «В разборе» и ждёт решения оператора: вернуть в работу или отменить с указанием основания.

Статусы команды

Статус Значение
PENDING — «Ожидает» Команда в очереди, ждёт своей очереди на исполнение (в том числе назначенная на будущее время).
RUNNING — «Исполняется» Команда захвачена обработчиком и выполняется.
DONE — «Выполнена» Команда исполнена (или отменена оператором — см. ниже).
PARKED — «В разборе» Команда неисполнима или исчерпала попытки — ждёт решения оператора.

Переключатель над таблицей позволяет посмотреть очередь в любом из четырёх статусов. По умолчанию открывается состояние «В разборе» — ради него экран и заведён: смотреть на тысячи выполненных команд смысла нет.

При состоянии «В разборе» под переключателем выводится предупреждение: «Эти команды отложены в разбор: они либо неисполнимы, либо исчерпали попытки. Пока их не вернут в работу или не отменят, они не исполнятся.»

Таблица очереди

Порядок строк фиксированный — свежие изменения первыми; сортировки по колонкам нет (сервер её не применяет). Настройка состава и ширины колонок — через шестерёнку в шапке экрана.

Колонка Описание
Идентификатор события Идентификатор команды у отправителя — ключ дедупликации приёма. Ссылка открывает карточку команды.
Тип Тип команды: ACCRUE, REDEEM, HOLD.
Клиент Внешний идентификатор клиента.
Источник Источник, из которого пришла команда.
Состояние Текущий статус (см. выше).
Попыток Сколько раз обработчик уже пытался исполнить команду.
Следующая попытка Момент следующей попытки (для «Ожидает») или срок, на который назначено исполнение.
Причина отказа Текст последнего отказа — выделен как ошибка. Пусто, если отказа не было.
Действия Кнопка «Вернуть в работу» и кнопка отмены (значок с подсказкой «Отменить команду») — только те, что сервер примет для этой строки (см. «Действия оператора»). Без роли LOYALTY_INTAKE_WRITE кнопки неактивны; если действий нет — «—».

Колонки «Идентификатор события» и «Действия» из таблицы не убираются.

Карточка команды

Клик по идентификатору события открывает боковую панель с полным составом команды:

Поле Описание
Идентификатор события Ключ дедупликации приёма; копируется по клику.
Тип ACCRUE / REDEEM / HOLD.
Клиент Внешний идентификатор.
Ссылка Бизнес-ключ операции — последний рубеж защиты от повторного исполнения на стороне леджера.
Источник Источник команды.
Состояние Текущий статус.
Попыток Число попыток исполнения.
Произошло Время события у источника (не время подачи команды).
Следующая попытка Момент следующей попытки или назначенного исполнения.
Причина отказа Текст последнего отказа (если был).
Тело команды Исходное тело запроса как есть, без интерпретации — разбор застрявшей команды начинается с вопроса «что именно прислали».
Итог исполнения Тело результата, если команда уже исполнена.

Действия оператора

Действия применимы только к команде в состоянии «В разборе» — доступность каждой кнопки в таблице определяется тем, что сервер уже принял решение для этой строки:

Действие Когда доступно Что делает
«Вернуть в работу» Статус «В разборе». Обнуляет счётчик попыток и причину отказа, переводит команду в «Ожидает» — обработчик исполнит её на общих основаниях.
«Отменить» Статус «В разборе», а также — отдельной операцией — команда, назначенная на будущее (см. ниже). Требует основание; переводит команду в «Выполнена» с указанной причиной — команда больше никогда не исполнится.

Модальное окно отмены требует обязательное основание (до 500 символов): «Отменённая команда не исполнится никогда. Основание останется в журнале — по нему потом восстанавливают, почему так решили.» Кнопка подтверждения недоступна, пока основание не введено.

Отмена команды, назначенной на будущее

Отдельно от разбора застрявших команд, оператор может отменить команду, которая ещё не наступила («Ожидает» со сроком исполнения позже текущего момента) — например, когда решили не начислять запланированные баллы. Кнопка отмены в таблице доступна и для таких строк; отменяется только команда с ещё не наступившим сроком: если срок уже подошёл, обработчик мог успеть забрать команду в работу первым, и отмена в этом случае отклоняется 409 intake_command_not_scheduled.

Ограничения

  • Оператор управляет только отложенными и ещё не наступившими командами: команда в статусе «Исполняется» или уже наступившая в статусе «Ожидает» разбирается обработчиком самостоятельно — вмешательство в неё означало бы гонку с обработчиком.
  • Отмена без основания отклоняется валидацией запроса — 400 (пустое основание не проходит на сервер как отдельный домен-код).
  • Действие над командой не в ожидаемом статусе отклоняется: 409 intake_command_not_parked (для возврата в работу и обычной отмены) или 409 intake_command_not_scheduled (для отмены назначенной команды).

Управление доступом

Роль Возможности
LOYALTY_INTAKE_READ Просмотр очереди приёма и карточки команды.
LOYALTY_INTAKE_WRITE Подача команд в очередь (интеграционная ручка) и действия разбора: возврат в работу, отмена.

Программный интерфейс

Метод и путь Назначение Роль
POST /v1/intake/commands Подать команду в очередь приёма (ответ 202, подтверждение приёма). LOYALTY_INTAKE_WRITE
GET /v1/admin/intake/commands Список команд в заданном состоянии (постранично). LOYALTY_INTAKE_READ
GET /v1/admin/intake/commands/{eventId} Команда по идентификатору события. LOYALTY_INTAKE_READ
POST /v1/admin/intake/commands/{eventId}/retry Вернуть отложенную команду в работу. LOYALTY_INTAKE_WRITE
POST /v1/admin/intake/commands/{eventId}/discard Отменить отложенную команду с основанием. LOYALTY_INTAKE_WRITE
POST /v1/admin/intake/commands/{eventId}/cancel Отменить команду, назначенную на будущее, пока её срок не наступил. LOYALTY_INTAKE_WRITE

Список команд отдаётся страницей ({items, page, size, total}), как и остальные коллекции продукта.

Коды ошибок

Код HTTP-статус Когда возникает
intake_payload_invalid 422 Тело команды не разбирается или содержит недопустимые значения.
intake_command_not_found 404 Команда с указанным идентификатором события не найдена.
intake_command_not_parked 409 Действие разбора (возврат в работу, обычная отмена) применено к команде не в состоянии «В разборе».
intake_discard_reason_required 422 Зарезервирован; через REST не воспроизводится — пустое основание отклоняется раньше, общей валидацией запроса (400).
intake_schedule_too_far 422 Назначенный момент исполнения команды выходит за предельный горизонт отсрочки.
intake_command_not_scheduled 409 Отмена команды, которая не в состоянии «Ожидает» с не наступившим сроком (либо срок уже наступил и команда в работе у обработчика).

Приём через брокер сообщений

Помимо POST /v1/intake/commands, модуль поддерживает приём той же очереди через брокер сообщений (Kafka) — транспорт выключен по умолчанию и включается на уровне развёртывания под контуром заказчика. С точки зрения оператора и экрана разбора команда, пришедшая через API или через брокер, ничем не отличается: она проходит ту же очередь и те же статусы.