Содержание
SERVICE_REQUEST в PRE_START: начало выполнения и внешние действия
Назначение: Сценарий процесса. Продукт: ShariX Open.
Для кого: Разработчик · Интегратор · Поддержка · Рецензент и приёмщик · Нейросеть.
Темы: Заказы → Жизненный цикл · Заказы → Исполнение · Обработчики → Runtime.
Область: ShariX Open. Обработчик: open_service_request_prestart, тип SERVICE_REQUEST (2), статус PRE_START. 31.10.2026 исходники повторно получены из Git. Обе Python-копии совпали с новой канонической генерацией Blockly. Сам обработчик и его внешние действия при анализе не запускались. Выбранная версия, настройки и работоспособность конкретной установки проверяются отдельно.
Назначение и границы
Handler сопровождает переход PRE_START → PROCESS:
- Сначала попробовать разрешённое пользовательское намерение из локальной очереди.
- Если проход продолжается — получить актуальный scoped context заказа.
- Дождаться planned_start для обычной временной ветви.
- После даты — автоматически запросить начало либо предложить назначенному исполнителю подтвердить start.
Отсутствие ответа само по себе не превращается в автоматический отказ или форс-мажор.
Схемы BPMN описательные, isExecutable=false. Runtime исполняет проверенный Python из Blockly; Wiki не является исполняемым process engine. Человеческое подтверждение, доставка сообщения и сохранённый PROCESS — разные события.
Порядок решений (BPMN)
До временной ветви извлекается одно подходящее queued intent:
- start;
- force_majeure;
- decline;
- refuse.
Успех или stale заканчивает проход; обработанный доменный неуспех позволяет продолжить обычную логику. Исключение идёт в processing_error. Наличие intent в этой очереди зависит от маршрутизации, описанной ниже.
Затем загружается scoped order context, устанавливается локальная причина provider_start и проверяется planned_start. До этой даты — RECHECK. При отсутствии/некорректной дате helper не считает срок наступившим; обычная auto/round-ветка не стартует, но ранее обработанный пользовательский start — отдельный путь.
После даты:
SERVICE_REQUEST_PRE_START_AUTO_PROCESS=true→ narrow start сtime_mode=planned; неуспех ждёт RECHECK.- При выключенном auto winner → narrow start с
time_mode=actual; после доменного неуспеха проверяется порог action failures, при достижении раунд забывается. В любом случае неуспех ждёт RECHECK. - no_winner забывается, после чего можно создать новое приглашение в том же проходе.
- При исчерпании попыток активный раунд забывается, назначается RECHECK, и проход завершается.
- Иначе отправляется попытка start, разбираются queued intents и winner/no_winner проверяются снова. Иной результат ждёт NOTIFICATION_INTERVAL.
Забывание раунда не меняет бизнес-статус и не равняется отказу исполнителя. Автоматическая ветка не использует порог failures для изменения стадии; неуспех auto-start остаётся на повторе.
Приглашение и внешний ответ (BPMN)
Приглашение адресуется текущему provider с JID из backend context. Сообщение order.action.required содержит:
- действие start;
- popup_policy=active_order;
- due_at=planned_start.
Альтернативное действие и expires_at для PRE_START-раунда не задаются. Due_at сообщает плановую дату, а не создаёт срок истечения ответа.
Используются SERVICE_REQUEST_PRE_START_ROUND_STRATEGY, …DELIVERY_POLICY, …NOTIFICATION_ATTEMPTS и …NOTIFICATION_INTERVAL_SECONDS. Число попыток может быть 0: это не запрет приглашений, а отсутствие конечного лимита в RoundRegistry. При положительном лимите handler при очередной проверке может забыть исчерпанный раунд и позднее создать новый. Не следует переносить сюда OFFER_TTL из PENDING или формулу RESPONSE_WINDOW из ACCEPTED.
Таймер на схеме — срок очередного прохода/отправки, а не timeout ответа человека. Без expires_at стратегия не получает обычного timeout по дате. Попытка регистрируется до отправки; send failure может расходовать лимит, но не доказывает отказа человека. Пустой JID оставляет handler на повторе.
Входящий ответ проверяется по round/order/ticket/status, участнику JID, допустимому действию, offer при наличии и повтору. Прямой XMPP actor берётся из отправителя, web actor — только из доверенного relay. Успешный response ack не является сохранённым началом работы. Ответ делает Ticket ready для последующего прохода, где заново применяются текущие правила.
Web intent: подтверждённая граница текущей маршрутизации
Маршрутизация до processing:
- Найти явно указанный round id. Для доверенного web relay без него — найти активный раунд Ticket.
- Если раунд найден — отправить intent в него, пометить Ticket ready и закончить маршрутизацию.
- Если раунда нет — подходящий intent может попасть в immediate queue.
Направленный в существующий раунд intent не дублируется в immediate queue.
Для активного PRE_START раунда allowed_actions содержит start. Поэтому web force_majeure может получить action_mismatch и не дойти до ранней ветки process_immediate_order_intent. При отсутствии такого раунда intent попадает в очередь и может быть обработан как переход PRE_FORCEMAJEUER. Это подтверждённое расхождение доступного web действия и его доставки при активном приглашении; фактическая конфигурация сервера не запрашивалась, исправление кода этой публикацией не выполнялось.
Также web start с активным раундом становится его ответом, а без раунда — immediate пользовательским действием. Эти пути по-разному проходят временную ветку и backend action. Указание «нажал start» недостаточно для диагностики: нужно понимать, был ли активный раунд.
Backend: planned, actual и сообщение о проблеме (BPMN)
Narrow start-pre-start проверяет:
- capability order.start_pre_start и текущий scope;
- статус PRE_START;
- наличие provider;
- effective time под lock: planned берёт Orders.time_start, actual — текущее время backend.
Отсутствие плановой даты даёт неуспех planned-вызова. Проверку наступления даты выполняет Python; этот narrow action её отдельно не повторяет.
После успешного PROCESS:
- пустое time_start_real заполняется effective time;
- существующее time_start_real сохраняется;
- пустая location_start_real заполняется resolver, если есть корректная локация;
- actual-вызов передаёт допустимые location-поля победителя, planned-вызов не передаёт этот payload.
Planned записывает плановое время как effective time. Это не свидетельство физического начала работы человеком точно в эту секунду.
В отличие от ACCEPTED wrapper этот start-wrapper не передаёт expected_provider_id из context. Backend поддерживает такую проверку при наличии параметра, но нельзя приписывать текущему вызову привязку к старому provider id из снимка раунда.
Immediate start использует apply-user-intent: backend заново находит active actor, сверяет JID при его передаче и вызывает каноническое пользовательское start. Оно проверяет, что actor — текущий исполнитель и заказ в PRE_START, заполняет actual time/location и меняет стадию. Отдельного ожидания planned_start в этом пользовательском lifecycle-пути нет.
Queued force_majeure/decline/refuse использует move-active-to-pre-forcemajeur: narrow capability/scope, активный PRE_START/PROCESS и наличие provider. При успехе сохраняется PRE_FORCEMAJEUER, provider этим action не очищается. Аутентификацию и доступ к web intent проверяет relay; этот путь не выполняет apply-user-intent заново и не подменяет его каноническим пользовательским start. Ограничение доставки при активном раунде описано выше.
Настройки, ожидание и восстановление
| Назначение | Настройка |
|---|---|
| Auto-start после planned_start | SERVICE_REQUEST_PRE_START_AUTO_PROCESS |
| Обычный повтор / ожидание даты | SERVICE_REQUEST_PRE_START_RECHECK_SECONDS |
| Стратегия и доставка | SERVICE_REQUEST_PRE_START_ROUND_STRATEGY, SERVICE_REQUEST_PRE_START_DELIVERY_POLICY |
| Лимит рассылки и порог доменных неуспехов start | SERVICE_REQUEST_PRE_START_NOTIFICATION_ATTEMPTS |
| Интервал приглашений | SERVICE_REQUEST_PRE_START_NOTIFICATION_INTERVAL_SECONDS |
| Общая ошибка | DEFERRED_TICKET_RECHECK_SECONDS, processing_error |
| Восстановление состава | INTERVAL_TIME_BD_REQ |
Счётчики send и доменных неуспехов start различны; при attempts=0 порог failures не считается достигнутым. RoundRegistry, ответы, очередь intents и счётчики — память процесса. После рестарта старое подтверждение не считается ответом на новый round id. Defer освобождает worker; внешний ответ может снять defer раньше.
Порядок диагностики:
- Прочитать фактические статус и provider.
- Сверить planned_start и SERVICE_REQUEST_PRE_START_AUTO_PROCESS.
- Найти активный раунд и проверить, куда попал intent: в раунд или immediate queue.
- Различить transport 202, приём ответа, outcome стратегии и результат backend action.
- Подтвердить сохранённый PROCESS и последующую смену владельца очереди.
Auth/HTTP/transport exception не является отказом исполнителя. После commit ticket.changed/ticket.moved передают владение; periodic reconciliation восстанавливает состав при потере событий.
Проверенные источники
Источники закреплены в metadata/BPMN и повторно сверены при упаковке. Handler и бизнес-API не исполнялись. Общий автоматический hook Wiki пока не завершён.
- sharix-open-handlers-examples / handlers/open_service_request_prestart.py — Git 76e0c693b628ed4a1fa34515a3f8abdff26149bb.
- sharix-open-handlers-examples / generated_handler_blocks/open_service_request_prestart.json — Git 76e0c693b628ed4a1fa34515a3f8abdff26149bb.
- sharix-open-handlers-examples / catalog.py — Git 76e0c693b628ed4a1fa34515a3f8abdff26149bb.
- sharix-open-handlers-backend / core/blockly_runtime.py — Git 50baf376e224d915a87d63240f3f339b3dda9afa.
- sharix-open-handlers-backend / core/requesters.py — Git 50baf376e224d915a87d63240f3f339b3dda9afa.
- sharix-open-handlers-backend / core/order_action_messages.py — Git 50baf376e224d915a87d63240f3f339b3dda9afa.
- sharix-open-handlers-backend / ticket_blockly_codegen.py — Git 50baf376e224d915a87d63240f3f339b3dda9afa.
- sharix-open-handlers-backend / ticket_codegen_contract.json — Git 50baf376e224d915a87d63240f3f339b3dda9afa.
- sharix-open-tickets / lib/tickets.py — Git fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14.
- sharix-open-tickets / api/handler_auth.py — Git fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14.
- sharix-open-tickets / signals.py — Git fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14.
- sharix-open-tickets / services/handler_wakeup.py — Git fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14.
- sharix-open-backend / apiviews/handler_order_workflow.py — Git 778a3280cee115ba0efe3fdff7b0e708b0c10093.
- sharix-open-backend / apiviews/open_api.py — Git 778a3280cee115ba0efe3fdff7b0e708b0c10093.
- sharix-open-backend / lib/order_handler_relay.py — Git 778a3280cee115ba0efe3fdff7b0e708b0c10093.
- sharix-open-backend / lib/handler_order_context.py — Git 778a3280cee115ba0efe3fdff7b0e708b0c10093.
- sharix-open-backend / lib/order_workflow_policy.py — Git 778a3280cee115ba0efe3fdff7b0e708b0c10093.
- sharix-open-backend / lib/order_actions.py — Git 778a3280cee115ba0efe3fdff7b0e708b0c10093.
- sharix-open-backend / lib/order_permissions.py — Git 778a3280cee115ba0efe3fdff7b0e708b0c10093.
- sharix-open-backend / urls.py — Git 778a3280cee115ba0efe3fdff7b0e708b0c10093.
- sharix-open-backend / lib/order_lifecycle.py — Git 778a3280cee115ba0efe3fdff7b0e708b0c10093.
- sharix-open-backend / lib/order_provider_requirements.py — Git 778a3280cee115ba0efe3fdff7b0e708b0c10093.
- sharix-open-handlers-backend / core/order_rounds.py — Git 50baf376e224d915a87d63240f3f339b3dda9afa.
- sharix-open-handlers-backend / settings_schema.py — Git 50baf376e224d915a87d63240f3f339b3dda9afa.
- sharix-open-backend / lib/order_execution_location.py — Git 778a3280cee115ba0efe3fdff7b0e708b0c10093.