Инструменты пользователя

Инструменты сайта


sharixopen:knowledge:scenarios:service_request_booked

Это старая версия документа!


SERVICE_REQUEST в BOOKED: ожидание исполнителя и окно PENDING

Назначение: Сценарий процесса. Продукт: ShariX Open.

Для кого: Разработчик · Поддержка · Рецензент и приёмщик · Нейросеть.

Темы: Заказы → Назначение · Заказы → Жизненный цикл · Обработчики → Runtime.

Область: ShariX Open. Обработчик: open_service_request_booked, тип SERVICE_REQUEST (2), рабочий статус BOOKED (211). 31.10.2026 опубликованные исходники повторно получены из Git. Обе Python-копии заново сопоставлены с результатом генерации Blockly; проверены 11 исходников генераторов. Сам handler не исполнялся. Выбранную версию, конфигурацию и внешние подключения сервера проверяют отдельно.

Назначение и границы

Handler сопровождает размещённый заказ в таком порядке:

  1. Попытаться применить одно разрешённое намерение take/cancel.
  2. Если проход не завершён — загрузить актуальный контекст заказа.
  3. Проверить окно автоматического перехода в PENDING.
  4. При отсутствии завершённого перехода назначить повтор.

В BOOKED handler не выбирает кандидатов, не рассылает предложения и не проводит раунд победителя. Это отдельная стадия PENDING.

Условие перехода зависит от заказа:

  • ASAP: попытка PENDING сразу после проверки intent и загрузки контекста.
  • Плановый заказ: ждать pending_at.

Универсальный autoaccept здесь не используется.

BPMN имеют isExecutable=false. Wiki не исполняет процесс: runtime выполняет выбранный проверенный Python из Blockly. End event завершает показанную операцию; он не означает завершения услуги.

Один проход и ожидание (BPMN)

Схема BPMN

Загрузка схемы…

Исходник схемы
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:ns2="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:ns3="http://www.omg.org/spec/DD/20100524/DC" xmlns:ns4="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_service_booked_logic" targetNamespace="urn:sharix:knowledge:handlers">
  <bpmn:process id="booked_Process_booked" name="open_service_request_booked: пользовательский take/cancel и окно перехода в PENDING" isExecutable="false">
    <bpmn:documentation>{"notes": ["Git built-in, BPMN isExecutable=false; handler при генерации не исполняется.", "BOOKED не рассылает предложения кандидатам.", "pending_at=planned_start − SERVICE_REQUEST_PRE_START_DURATION_SECONDS − SERVICE_REQUEST_BOOKED_PENDING_LEAD_SECONDS.", "Часы проверки границы — runtime; backend move повторно проверяет статус и отсутствие provider."], "sources": [{"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "handlers/open_service_request_booked.py", "repository": "sharix-open-handlers-examples", "sha256": "44e066a3ccb7ee21abc8d252a343adf1ea3cbf5e177aebb62ed2059fe1c2f2d8"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "generated_handler_blocks/open_service_request_booked.json", "repository": "sharix-open-handlers-examples", "sha256": "7096cde8b581cc80b2f0f65dcc63e95adfdfdd8bf459e9a70ee229d329a7dcfc"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "catalog.py", "repository": "sharix-open-handlers-examples", "sha256": "e3dcb72b7e620e2837adacd7af053f35b04cdff475789496d9c114e17d57dfde"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "core/blockly_runtime.py", "repository": "sharix-open-handlers-backend", "sha256": "3e222150cbff315077c6c9b160d46e59856cedf6d6591d213e958c63cb2f2428"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "core/requesters.py", "repository": "sharix-open-handlers-backend", "sha256": "965a348cea477722bbaf4c8c6b06023eb238b71664a332f7ea8c90bfe72ea808"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "core/order_action_messages.py", "repository": "sharix-open-handlers-backend", "sha256": "046c262c0aabb02104fefca4e887324f99df22731e7726063f614aaf8839ca5c"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "ticket_blockly_codegen.py", "repository": "sharix-open-handlers-backend", "sha256": "bce71eab622922f8dd0954222842349799b60e18a0ab6310cc3e5f305603661e"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "ticket_codegen_contract.json", "repository": "sharix-open-handlers-backend", "sha256": "0bfd2b0ebb07bd380ed3c867386536ab88ef7dfa6e13f1cd8c91d32bb02c1ae9"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "lib/tickets.py", "repository": "sharix-open-tickets", "sha256": "0d260c17947f9a186d07af2749159780e3c7354a95b4bafe9d67493663c96883"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "api/handler_auth.py", "repository": "sharix-open-tickets", "sha256": "ac76dc45aaa9742e5e1da0b98aae914bb2e287048d33e97b4a245a6997bc8425"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "signals.py", "repository": "sharix-open-tickets", "sha256": "39aad8690a2e7d35cebfb052127a8130a951cbb4eea316c4f767a0a59fc5fa7e"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "services/handler_wakeup.py", "repository": "sharix-open-tickets", "sha256": "c9fdc62a18301fd7c075395c697d5b1c738c77713aa71fcbb5ab097e173d98de"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "apiviews/handler_order_workflow.py", "repository": "sharix-open-backend", "sha256": "35624ded6e67110437a25dd07caef214a04251eb0136194ae939fa32fef17e84"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "apiviews/open_api.py", "repository": "sharix-open-backend", "sha256": "cb8fdda304d29c2cc5c0fc938759a13c60022871b7b93d77883d521820021ad3"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/order_handler_relay.py", "repository": "sharix-open-backend", "sha256": "e49a7876169403970d995af464357e2134af19a398372c55db2a5b40681d731e"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/handler_order_context.py", "repository": "sharix-open-backend", "sha256": "f3c0731e74d30dbe5e59bd53040a06ee108f14f7aad04771e65d741cffeb7179"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/order_workflow_policy.py", "repository": "sharix-open-backend", "sha256": "3266c6ecab490a0e19c8bbc02041387b86fe4b14068750e545ba9bde8bf51326"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/order_actions.py", "repository": "sharix-open-backend", "sha256": "27ce243408a46f1b700d94bf78a25c68ef21d51078bb03627174e4a424d82ef0"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/order_permissions.py", "repository": "sharix-open-backend", "sha256": "9c1636daa80c4da68c3ae5cf347e279127d142eeff91e969559e8bd54ca3d81d"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "urls.py", "repository": "sharix-open-backend", "sha256": "61ffd2f0563291da2dcc9488a5443cb5e2c0395108740a6700034cfd90548158"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/order_lifecycle.py", "repository": "sharix-open-backend", "sha256": "66dd2c4db9da3aaf90cb080946c1920a4f9953d62d1e6c9e224dd52564c4d661"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/order_provider_requirements.py", "repository": "sharix-open-backend", "sha256": "392f1f9180a098a4749b5fe5b7948e34530ccdb2befed646e538cdb7a5ddcada"}]}</bpmn:documentation>
    <bpmn:laneSet id="booked_Lanes_booked">
      <bpmn:lane id="booked_Lane_worker" name="Worker: один проход Python">
        <bpmn:flowNodeRef>booked_start</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>booked_status</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>booked_intent</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>booked_handled</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>booked_intent_end</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>booked_stale</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>booked_stale_end</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>booked_context</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>booked_found</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>booked_missing</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>booked_reason</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>booked_asap</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>booked_due</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>booked_move</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>booked_ok</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>booked_end</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>booked_defer</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>booked_intent_error</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>booked_context_error</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>booked_move_error</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>booked_retry</bpmn:flowNodeRef>
      </bpmn:lane>
      <bpmn:lane id="booked_Lane_queue" name="Планировщик: ожидание без занятого worker">
        <bpmn:flowNodeRef>booked_wait</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>booked_timer</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>booked_event</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>booked_ready</bpmn:flowNodeRef>
      </bpmn:lane>
    </bpmn:laneSet>
    <bpmn:startEvent id="booked_start" name="Ticket готов к проходу">
      <bpmn:outgoing>booked_Flow_0</bpmn:outgoing>
    </bpmn:startEvent>
    <bpmn:exclusiveGateway id="booked_status" name="Статус BOOKED?">
      <bpmn:incoming>booked_Flow_0</bpmn:incoming>
      <bpmn:incoming>booked_Flow_27</bpmn:incoming>
      <bpmn:outgoing>booked_Flow_1</bpmn:outgoing>
      <bpmn:outgoing>booked_Flow_2</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:serviceTask id="booked_intent" name="Попробовать один доверенный take / cancel">
      <bpmn:incoming>booked_Flow_1</bpmn:incoming>
      <bpmn:outgoing>booked_Flow_4</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:exclusiveGateway id="booked_handled" name="Успех или stale?">
      <bpmn:incoming>booked_Flow_4</bpmn:incoming>
      <bpmn:outgoing>booked_Flow_5</bpmn:outgoing>
      <bpmn:outgoing>booked_Flow_6</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:endEvent id="booked_intent_end" name="Локальный Ticket исключён">
      <bpmn:incoming>booked_Flow_5</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:serviceTask id="booked_stale" name="Убрать Ticket и комнату">
      <bpmn:incoming>booked_Flow_2</bpmn:incoming>
      <bpmn:outgoing>booked_Flow_3</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:endEvent id="booked_stale_end" name="Прежний владелец освобождён">
      <bpmn:incoming>booked_Flow_3</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:serviceTask id="booked_context" name="Scoped API: актуальный order context">
      <bpmn:incoming>booked_Flow_6</bpmn:incoming>
      <bpmn:outgoing>booked_Flow_7</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:exclusiveGateway id="booked_found" name="Контекст найден?">
      <bpmn:incoming>booked_Flow_7</bpmn:incoming>
      <bpmn:outgoing>booked_Flow_8</bpmn:outgoing>
      <bpmn:outgoing>booked_Flow_9</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:endEvent id="booked_missing" name="404: очистка уже запрошена">
      <bpmn:incoming>booked_Flow_8</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:serviceTask id="booked_reason" name="Причина awaiting_pending_window">
      <bpmn:incoming>booked_Flow_9</bpmn:incoming>
      <bpmn:outgoing>booked_Flow_10</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:exclusiveGateway id="booked_asap" name="Заказ ASAP?">
      <bpmn:incoming>booked_Flow_10</bpmn:incoming>
      <bpmn:outgoing>booked_Flow_11</bpmn:outgoing>
      <bpmn:outgoing>booked_Flow_12</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:exclusiveGateway id="booked_due" name="Наступил pending_at?">
      <bpmn:incoming>booked_Flow_12</bpmn:incoming>
      <bpmn:outgoing>booked_Flow_13</bpmn:outgoing>
      <bpmn:outgoing>booked_Flow_14</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:serviceTask id="booked_move" name="Narrow order action: move-booked-to-pending">
      <bpmn:incoming>booked_Flow_11</bpmn:incoming>
      <bpmn:incoming>booked_Flow_13</bpmn:incoming>
      <bpmn:outgoing>booked_Flow_15</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:exclusiveGateway id="booked_ok" name="Успех или stale?">
      <bpmn:incoming>booked_Flow_15</bpmn:incoming>
      <bpmn:outgoing>booked_Flow_16</bpmn:outgoing>
      <bpmn:outgoing>booked_Flow_17</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:endEvent id="booked_end" name="Текущий Ticket исключён">
      <bpmn:incoming>booked_Flow_16</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:serviceTask id="booked_defer" name="SERVICE_REQUEST_BOOKED_RECHECK_SECONDS">
      <bpmn:incoming>booked_Flow_14</bpmn:incoming>
      <bpmn:incoming>booked_Flow_17</bpmn:incoming>
      <bpmn:outgoing>booked_Flow_18</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:boundaryEvent id="booked_intent_error" name="Ошибка API" attachedToRef="booked_intent" cancelActivity="true">
      <bpmn:outgoing>booked_Flow_20</bpmn:outgoing>
      <bpmn:errorEventDefinition />
    </bpmn:boundaryEvent>
    <bpmn:boundaryEvent id="booked_context_error" name="Ошибка context API" attachedToRef="booked_context" cancelActivity="true">
      <bpmn:outgoing>booked_Flow_21</bpmn:outgoing>
      <bpmn:errorEventDefinition />
    </bpmn:boundaryEvent>
    <bpmn:boundaryEvent id="booked_move_error" name="Ошибка API" attachedToRef="booked_move" cancelActivity="true">
      <bpmn:outgoing>booked_Flow_22</bpmn:outgoing>
      <bpmn:errorEventDefinition />
    </bpmn:boundaryEvent>
    <bpmn:serviceTask id="booked_retry" name="processing_error + общий defer">
      <bpmn:incoming>booked_Flow_20</bpmn:incoming>
      <bpmn:incoming>booked_Flow_21</bpmn:incoming>
      <bpmn:incoming>booked_Flow_22</bpmn:incoming>
      <bpmn:outgoing>booked_Flow_19</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:eventBasedGateway id="booked_wait" name="Что наступило раньше?">
      <bpmn:incoming>booked_Flow_18</bpmn:incoming>
      <bpmn:incoming>booked_Flow_19</bpmn:incoming>
      <bpmn:outgoing>booked_Flow_23</bpmn:outgoing>
      <bpmn:outgoing>booked_Flow_24</bpmn:outgoing>
    </bpmn:eventBasedGateway>
    <bpmn:intermediateCatchEvent id="booked_timer" name="Наступил локальный срок defer">
      <bpmn:incoming>booked_Flow_23</bpmn:incoming>
      <bpmn:outgoing>booked_Flow_25</bpmn:outgoing>
      <bpmn:timerEventDefinition>
        <bpmn:timeDate xsi:type="bpmn:tFormalExpression">deferred_until</bpmn:timeDate>
      </bpmn:timerEventDefinition>
    </bpmn:intermediateCatchEvent>
    <bpmn:intermediateCatchEvent id="booked_event" name="Новая ревизия / разрешённый intent">
      <bpmn:incoming>booked_Flow_24</bpmn:incoming>
      <bpmn:outgoing>booked_Flow_26</bpmn:outgoing>
      <bpmn:messageEventDefinition />
    </bpmn:intermediateCatchEvent>
    <bpmn:serviceTask id="booked_ready" name="Сделать Ticket готовым к проходу">
      <bpmn:incoming>booked_Flow_25</bpmn:incoming>
      <bpmn:incoming>booked_Flow_26</bpmn:incoming>
      <bpmn:outgoing>booked_Flow_27</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:sequenceFlow id="booked_Flow_0" sourceRef="booked_start" targetRef="booked_status" name="" />
    <bpmn:sequenceFlow id="booked_Flow_1" sourceRef="booked_status" targetRef="booked_intent" name="Да" />
    <bpmn:sequenceFlow id="booked_Flow_2" sourceRef="booked_status" targetRef="booked_stale" name="Нет" />
    <bpmn:sequenceFlow id="booked_Flow_3" sourceRef="booked_stale" targetRef="booked_stale_end" name="" />
    <bpmn:sequenceFlow id="booked_Flow_4" sourceRef="booked_intent" targetRef="booked_handled" name="" />
    <bpmn:sequenceFlow id="booked_Flow_5" sourceRef="booked_handled" targetRef="booked_intent_end" name="Да" />
    <bpmn:sequenceFlow id="booked_Flow_6" sourceRef="booked_handled" targetRef="booked_context" name="Нет" />
    <bpmn:sequenceFlow id="booked_Flow_7" sourceRef="booked_context" targetRef="booked_found" name="" />
    <bpmn:sequenceFlow id="booked_Flow_8" sourceRef="booked_found" targetRef="booked_missing" name="Нет (404)" />
    <bpmn:sequenceFlow id="booked_Flow_9" sourceRef="booked_found" targetRef="booked_reason" name="Да" />
    <bpmn:sequenceFlow id="booked_Flow_10" sourceRef="booked_reason" targetRef="booked_asap" name="" />
    <bpmn:sequenceFlow id="booked_Flow_11" sourceRef="booked_asap" targetRef="booked_move" name="Да" />
    <bpmn:sequenceFlow id="booked_Flow_12" sourceRef="booked_asap" targetRef="booked_due" name="Нет" />
    <bpmn:sequenceFlow id="booked_Flow_13" sourceRef="booked_due" targetRef="booked_move" name="Да" />
    <bpmn:sequenceFlow id="booked_Flow_14" sourceRef="booked_due" targetRef="booked_defer" name="Нет" />
    <bpmn:sequenceFlow id="booked_Flow_15" sourceRef="booked_move" targetRef="booked_ok" name="" />
    <bpmn:sequenceFlow id="booked_Flow_16" sourceRef="booked_ok" targetRef="booked_end" name="Да" />
    <bpmn:sequenceFlow id="booked_Flow_17" sourceRef="booked_ok" targetRef="booked_defer" name="Нет (доменный отказ)" />
    <bpmn:sequenceFlow id="booked_Flow_18" sourceRef="booked_defer" targetRef="booked_wait" name="" />
    <bpmn:sequenceFlow id="booked_Flow_19" sourceRef="booked_retry" targetRef="booked_wait" name="" />
    <bpmn:sequenceFlow id="booked_Flow_20" sourceRef="booked_intent_error" targetRef="booked_retry" name="" />
    <bpmn:sequenceFlow id="booked_Flow_21" sourceRef="booked_context_error" targetRef="booked_retry" name="" />
    <bpmn:sequenceFlow id="booked_Flow_22" sourceRef="booked_move_error" targetRef="booked_retry" name="" />
    <bpmn:sequenceFlow id="booked_Flow_23" sourceRef="booked_wait" targetRef="booked_timer" name="" />
    <bpmn:sequenceFlow id="booked_Flow_24" sourceRef="booked_wait" targetRef="booked_event" name="" />
    <bpmn:sequenceFlow id="booked_Flow_25" sourceRef="booked_timer" targetRef="booked_ready" name="" />
    <bpmn:sequenceFlow id="booked_Flow_26" sourceRef="booked_event" targetRef="booked_ready" name="" />
    <bpmn:sequenceFlow id="booked_Flow_27" sourceRef="booked_ready" targetRef="booked_status" name="Новый проход" />
  </bpmn:process>
  <bpmn:collaboration id="Collaboration_service_booked_logic">
    <bpmn:participant id="booked_Pool_booked" name="open_service_request_booked: пользовательский take/cancel и окно перехода в PENDING" processRef="booked_Process_booked" />
  </bpmn:collaboration>
  <ns2:BPMNDiagram id="Diagram_service_booked_logic">
    <ns2:BPMNPlane id="Plane_service_booked_logic" bpmnElement="Collaboration_service_booked_logic">
      <ns2:BPMNShape id="booked_DI_Pool_booked" bpmnElement="booked_Pool_booked" isHorizontal="true">
        <ns3:Bounds x="0.0" y="0.0" width="2710.0" height="1110.0" />
      </ns2:BPMNShape>
      <ns2:BPMNShape id="booked_DI_Lane_worker" bpmnElement="booked_Lane_worker" isHorizontal="true">
        <ns3:Bounds x="30.0" y="0.0" width="2680.0" height="710.0" />
      </ns2:BPMNShape>
      <ns2:BPMNShape id="booked_DI_Lane_queue" bpmnElement="booked_Lane_queue" isHorizontal="true">
        <ns3:Bounds x="30.0" y="710.0" width="2680.0" height="400.0" />
      </ns2:BPMNShape>
      <ns2:BPMNShape id="booked_DI_start" bpmnElement="booked_start">
        <ns3:Bounds x="132.0" y="92.0" width="36" height="36" />
      </ns2:BPMNShape>
      <ns2:BPMNShape id="booked_DI_status" bpmnElement="booked_status">
        <ns3:Bounds x="325.0" y="85.0" width="50" height="50" />
      </ns2:BPMNShape>
      <ns2:BPMNShape id="booked_DI_intent" bpmnElement="booked_intent">
        <ns3:Bounds x="515.0" y="75.0" width="150" height="70" />
      </ns2:BPMNShape>
      <ns2:BPMNShape id="booked_DI_handled" bpmnElement="booked_handled">
        <ns3:Bounds x="825.0" y="85.0" width="50" height="50" />
      </ns2:BPMNShape>
      <ns2:BPMNShape id="booked_DI_intent_end" bpmnElement="booked_intent_end">
        <ns3:Bounds x="1092.0" y="92.0" width="36" height="36" />
      </ns2:BPMNShape>
      <ns2:BPMNShape id="booked_DI_stale" bpmnElement="booked_stale">
        <ns3:Bounds x="275.0" y="275.0" width="150" height="70" />
      </ns2:BPMNShape>
      <ns2:BPMNShape id="booked_DI_stale_end" bpmnElement="booked_stale_end">
        <ns3:Bounds x="572.0" y="292.0" width="36" height="36" />
      </ns2:BPMNShape>
      <ns2:BPMNShape id="booked_DI_context" bpmnElement="booked_context">
        <ns3:Bounds x="775.0" y="275.0" width="150" height="70" />
      </ns2:BPMNShape>
      <ns2:BPMNShape id="booked_DI_found" bpmnElement="booked_found">
        <ns3:Bounds x="1085.0" y="285.0" width="50" height="50" />
      </ns2:BPMNShape>
      <ns2:BPMNShape id="booked_DI_missing" bpmnElement="booked_missing">
        <ns3:Bounds x="1092.0" y="492.0" width="36" height="36" />
      </ns2:BPMNShape>
      <ns2:BPMNShape id="booked_DI_reason" bpmnElement="booked_reason">
        <ns3:Bounds x="1295.0" y="275.0" width="150" height="70" />
      </ns2:BPMNShape>
      <ns2:BPMNShape id="booked_DI_asap" bpmnElement="booked_asap">
        <ns3:Bounds x="1605.0" y="285.0" width="50" height="50" />
      </ns2:BPMNShape>
      <ns2:BPMNShape id="booked_DI_due" bpmnElement="booked_due">
        <ns3:Bounds x="1605.0" y="485.0" width="50" height="50" />
      </ns2:BPMNShape>
      <ns2:BPMNShape id="booked_DI_move" bpmnElement="booked_move">
        <ns3:Bounds x="1815.0" y="275.0" width="150" height="70" />
      </ns2:BPMNShape>
      <ns2:BPMNShape id="booked_DI_ok" bpmnElement="booked_ok">
        <ns3:Bounds x="2125.0" y="285.0" width="50" height="50" />
      </ns2:BPMNShape>
      <ns2:BPMNShape id="booked_DI_end" bpmnElement="booked_end">
        <ns3:Bounds x="2392.0" y="292.0" width="36" height="36" />
      </ns2:BPMNShape>
      <ns2:BPMNShape id="booked_DI_defer" bpmnElement="booked_defer">
        <ns3:Bounds x="1815.0" y="575.0" width="150" height="70" />
      </ns2:BPMNShape>
      <ns2:BPMNShape id="booked_DI_intent_error" bpmnElement="booked_intent_error">
        <ns3:Bounds x="622.0" y="127.0" width="36" height="36" />
      </ns2:BPMNShape>
      <ns2:BPMNShape id="booked_DI_context_error" bpmnElement="booked_context_error">
        <ns3:Bounds x="882.0" y="327.0" width="36" height="36" />
      </ns2:BPMNShape>
      <ns2:BPMNShape id="booked_DI_move_error" bpmnElement="booked_move_error">
        <ns3:Bounds x="1922.0" y="327.0" width="36" height="36" />
      </ns2:BPMNShape>
      <ns2:BPMNShape id="booked_DI_retry" bpmnElement="booked_retry">
        <ns3:Bounds x="2335.0" y="575.0" width="150" height="70" />
      </ns2:BPMNShape>
      <ns2:BPMNShape id="booked_DI_wait" bpmnElement="booked_wait">
        <ns3:Bounds x="1345.0" y="855.0" width="50" height="50" />
      </ns2:BPMNShape>
      <ns2:BPMNShape id="booked_DI_timer" bpmnElement="booked_timer">
        <ns3:Bounds x="1612.0" y="792.0" width="36" height="36" />
      </ns2:BPMNShape>
      <ns2:BPMNShape id="booked_DI_event" bpmnElement="booked_event">
        <ns3:Bounds x="1612.0" y="992.0" width="36" height="36" />
      </ns2:BPMNShape>
      <ns2:BPMNShape id="booked_DI_ready" bpmnElement="booked_ready">
        <ns3:Bounds x="1815.0" y="845.0" width="150" height="70" />
      </ns2:BPMNShape>
      <ns2:BPMNEdge id="booked_DI_Flow_0" bpmnElement="booked_Flow_0">
        <ns4:waypoint x="168.0" y="110.0" />
        <ns4:waypoint x="325.0" y="110.0" />
      </ns2:BPMNEdge>
      <ns2:BPMNEdge id="booked_DI_Flow_1" bpmnElement="booked_Flow_1">
        <ns4:waypoint x="375.0" y="110.0" />
        <ns4:waypoint x="515.0" y="110.0" />
      </ns2:BPMNEdge>
      <ns2:BPMNEdge id="booked_DI_Flow_2" bpmnElement="booked_Flow_2">
        <ns4:waypoint x="350.0" y="135.0" />
        <ns4:waypoint x="350.0" y="275.0" />
      </ns2:BPMNEdge>
      <ns2:BPMNEdge id="booked_DI_Flow_3" bpmnElement="booked_Flow_3">
        <ns4:waypoint x="425.0" y="310.0" />
        <ns4:waypoint x="572.0" y="310.0" />
      </ns2:BPMNEdge>
      <ns2:BPMNEdge id="booked_DI_Flow_4" bpmnElement="booked_Flow_4">
        <ns4:waypoint x="665.0" y="110.0" />
        <ns4:waypoint x="825.0" y="110.0" />
      </ns2:BPMNEdge>
      <ns2:BPMNEdge id="booked_DI_Flow_5" bpmnElement="booked_Flow_5">
        <ns4:waypoint x="875.0" y="110.0" />
        <ns4:waypoint x="1092.0" y="110.0" />
      </ns2:BPMNEdge>
      <ns2:BPMNEdge id="booked_DI_Flow_6" bpmnElement="booked_Flow_6">
        <ns4:waypoint x="850.0" y="135.0" />
        <ns4:waypoint x="850.0" y="275.0" />
      </ns2:BPMNEdge>
      <ns2:BPMNEdge id="booked_DI_Flow_7" bpmnElement="booked_Flow_7">
        <ns4:waypoint x="925.0" y="310.0" />
        <ns4:waypoint x="1085.0" y="310.0" />
      </ns2:BPMNEdge>
      <ns2:BPMNEdge id="booked_DI_Flow_8" bpmnElement="booked_Flow_8">
        <ns4:waypoint x="1110.0" y="335.0" />
        <ns4:waypoint x="1110.0" y="492.0" />
      </ns2:BPMNEdge>
      <ns2:BPMNEdge id="booked_DI_Flow_9" bpmnElement="booked_Flow_9">
        <ns4:waypoint x="1135.0" y="310.0" />
        <ns4:waypoint x="1295.0" y="310.0" />
      </ns2:BPMNEdge>
      <ns2:BPMNEdge id="booked_DI_Flow_10" bpmnElement="booked_Flow_10">
        <ns4:waypoint x="1445.0" y="310.0" />
        <ns4:waypoint x="1605.0" y="310.0" />
      </ns2:BPMNEdge>
      <ns2:BPMNEdge id="booked_DI_Flow_11" bpmnElement="booked_Flow_11">
        <ns4:waypoint x="1655.0" y="310.0" />
        <ns4:waypoint x="1815.0" y="310.0" />
      </ns2:BPMNEdge>
      <ns2:BPMNEdge id="booked_DI_Flow_12" bpmnElement="booked_Flow_12">
        <ns4:waypoint x="1630.0" y="335.0" />
        <ns4:waypoint x="1630.0" y="485.0" />
      </ns2:BPMNEdge>
      <ns2:BPMNEdge id="booked_DI_Flow_13" bpmnElement="booked_Flow_13">
        <ns4:waypoint x="1655.0" y="510.0" />
        <ns4:waypoint x="1750.0" y="510.0" />
        <ns4:waypoint x="1820.0" y="510.0" />
        <ns4:waypoint x="1820.0" y="240.0" />
        <ns4:waypoint x="1890.0" y="240.0" />
        <ns4:waypoint x="1890.0" y="275.0" />
      </ns2:BPMNEdge>
      <ns2:BPMNEdge id="booked_DI_Flow_14" bpmnElement="booked_Flow_14">
        <ns4:waypoint x="1655.0" y="510.0" />
        <ns4:waypoint x="1735.0" y="510.0" />
        <ns4:waypoint x="1735.0" y="610.0" />
        <ns4:waypoint x="1815.0" y="610.0" />
      </ns2:BPMNEdge>
      <ns2:BPMNEdge id="booked_DI_Flow_15" bpmnElement="booked_Flow_15">
        <ns4:waypoint x="1965.0" y="310.0" />
        <ns4:waypoint x="2125.0" y="310.0" />
      </ns2:BPMNEdge>
      <ns2:BPMNEdge id="booked_DI_Flow_16" bpmnElement="booked_Flow_16">
        <ns4:waypoint x="2175.0" y="310.0" />
        <ns4:waypoint x="2392.0" y="310.0" />
      </ns2:BPMNEdge>
      <ns2:BPMNEdge id="booked_DI_Flow_17" bpmnElement="booked_Flow_17">
        <ns4:waypoint x="2175.0" y="310.0" />
        <ns4:waypoint x="2270.0" y="310.0" />
        <ns4:waypoint x="2270.0" y="540.0" />
        <ns4:waypoint x="1890.0" y="540.0" />
        <ns4:waypoint x="1890.0" y="575.0" />
      </ns2:BPMNEdge>
      <ns2:BPMNEdge id="booked_DI_Flow_18" bpmnElement="booked_Flow_18">
        <ns4:waypoint x="1965.0" y="610.0" />
        <ns4:waypoint x="2010.0" y="610.0" />
        <ns4:waypoint x="2010.0" y="740.0" />
        <ns4:waypoint x="1370.0" y="740.0" />
        <ns4:waypoint x="1370.0" y="855.0" />
      </ns2:BPMNEdge>
      <ns2:BPMNEdge id="booked_DI_Flow_19" bpmnElement="booked_Flow_19">
        <ns4:waypoint x="2485.0" y="610.0" />
        <ns4:waypoint x="2530.0" y="610.0" />
        <ns4:waypoint x="2530.0" y="720.0" />
        <ns4:waypoint x="1370.0" y="720.0" />
        <ns4:waypoint x="1370.0" y="855.0" />
      </ns2:BPMNEdge>
      <ns2:BPMNEdge id="booked_DI_Flow_20" bpmnElement="booked_Flow_20">
        <ns4:waypoint x="658.0" y="145.0" />
        <ns4:waypoint x="700.0" y="145.0" />
        <ns4:waypoint x="700.0" y="690.0" />
        <ns4:waypoint x="2410.0" y="690.0" />
        <ns4:waypoint x="2410.0" y="575.0" />
      </ns2:BPMNEdge>
      <ns2:BPMNEdge id="booked_DI_Flow_21" bpmnElement="booked_Flow_21">
        <ns4:waypoint x="918.0" y="345.0" />
        <ns4:waypoint x="960.0" y="345.0" />
        <ns4:waypoint x="960.0" y="670.0" />
        <ns4:waypoint x="2410.0" y="670.0" />
        <ns4:waypoint x="2410.0" y="575.0" />
      </ns2:BPMNEdge>
      <ns2:BPMNEdge id="booked_DI_Flow_22" bpmnElement="booked_Flow_22">
        <ns4:waypoint x="1958.0" y="345.0" />
        <ns4:waypoint x="2000.0" y="345.0" />
        <ns4:waypoint x="2410.0" y="345.0" />
        <ns4:waypoint x="2410.0" y="575.0" />
      </ns2:BPMNEdge>
      <ns2:BPMNEdge id="booked_DI_Flow_23" bpmnElement="booked_Flow_23">
        <ns4:waypoint x="1395.0" y="880.0" />
        <ns4:waypoint x="1503.5" y="880.0" />
        <ns4:waypoint x="1503.5" y="810.0" />
        <ns4:waypoint x="1612.0" y="810.0" />
      </ns2:BPMNEdge>
      <ns2:BPMNEdge id="booked_DI_Flow_24" bpmnElement="booked_Flow_24">
        <ns4:waypoint x="1395.0" y="880.0" />
        <ns4:waypoint x="1503.5" y="880.0" />
        <ns4:waypoint x="1503.5" y="1010.0" />
        <ns4:waypoint x="1612.0" y="1010.0" />
      </ns2:BPMNEdge>
      <ns2:BPMNEdge id="booked_DI_Flow_25" bpmnElement="booked_Flow_25">
        <ns4:waypoint x="1648.0" y="810.0" />
        <ns4:waypoint x="1731.5" y="810.0" />
        <ns4:waypoint x="1731.5" y="880.0" />
        <ns4:waypoint x="1815.0" y="880.0" />
      </ns2:BPMNEdge>
      <ns2:BPMNEdge id="booked_DI_Flow_26" bpmnElement="booked_Flow_26">
        <ns4:waypoint x="1648.0" y="1010.0" />
        <ns4:waypoint x="1731.5" y="1010.0" />
        <ns4:waypoint x="1731.5" y="880.0" />
        <ns4:waypoint x="1815.0" y="880.0" />
      </ns2:BPMNEdge>
      <ns2:BPMNEdge id="booked_DI_Flow_27" bpmnElement="booked_Flow_27">
        <ns4:waypoint x="1965.0" y="880.0" />
        <ns4:waypoint x="2670.0" y="880.0" />
        <ns4:waypoint x="2670.0" y="25.0" />
        <ns4:waypoint x="350.0" y="25.0" />
        <ns4:waypoint x="350.0" y="85.0" />
        <ns2:BPMNLabel>
          <ns3:Bounds x="2370.0" y="5.0" width="180" height="26" />
        </ns2:BPMNLabel>
      </ns2:BPMNEdge>
    </ns2:BPMNPlane>
  </ns2:BPMNDiagram>
</bpmn:definitions>

Чужой статус запрашивает очистку локального Ticket и комнаты. В своём статусе успешный intent либо stale завершают проход. Если намерение не найдено или доменное пользовательское действие отклонено, handler продолжает обычную проверку BOOKED и загружает scoped order context.

После контекста записывается локальная причина awaiting_pending_window. ASAP идёт к move-booked-to-pending без ожидания планового окна. Иначе pending_at сравнивается с текущим временем runtime. Подтверждённый успех/stale исключает Ticket из очереди; обработанный доменный отказ оставляет его для повтора по SERVICE_REQUEST_BOOKED_RECHECK_SECONDS.

Ошибки контекста и action трактуются отдельно:

  • 404: устаревший scope, запрашивается локальная очистка.
  • Нет единственного связанного Orders: конфликт API, а не выбор произвольной записи.
  • Auth, 5xx или неожиданный ответ: processing_error с DEFERRED_TICKET_RECHECK_SECONDS.

Временная граница

Контекст рассчитывает:

  • planned_start — корректное Orders.time_start;
  • pre_start_at — planned_start минус SERVICE_REQUEST_PRE_START_DURATION_SECONDS;
  • pending_at — pre_start_at минус SERVICE_REQUEST_BOOKED_PENDING_LEAD_SECONDS.

Это не отсчёт от даты создания Ticket. При отсутствующем/некорректном pending_at плановая граница не считается достигнутой; исправление даты может потребоваться отдельно. ASAP использует свою явную ветвь и не ждёт наличия pending_at.

Дату сравнивает runtime. Backend move_booked_order_to_pending_as_handler повторно проверяет актуальный BOOKED и отсутствие provider под блокировкой, но не пересчитывает время окна. Поэтому выбранный Python и именованные параметры тайминга являются частью политики перехода.

Канонические действия и внешние участники (BPMN)

Схема BPMN

Загрузка схемы…

Исходник схемы
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:ns1="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:ns2="http://www.omg.org/spec/DD/20100524/DC" xmlns:ns3="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_service_booked_actions" targetNamespace="urn:sharix:knowledge:handlers">
  <bpmn:process id="backend_Process_backend" name="Backend: окончательные права, блокировки и актуальное состояние" isExecutable="false">
    <bpmn:documentation>{"notes": ["Git built-in, BPMN isExecutable=false; handler при генерации не исполняется.", "BOOKED не рассылает предложения кандидатам.", "pending_at=planned_start − SERVICE_REQUEST_PRE_START_DURATION_SECONDS − SERVICE_REQUEST_BOOKED_PENDING_LEAD_SECONDS.", "Часы проверки границы — runtime; backend move повторно проверяет статус и отсутствие provider.", "Общий transport/202/direct actions разобран в TEMPLATE. Здесь — отличающиеся канонические действия BOOKED."], "sources": [{"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "handlers/open_service_request_booked.py", "repository": "sharix-open-handlers-examples", "sha256": "44e066a3ccb7ee21abc8d252a343adf1ea3cbf5e177aebb62ed2059fe1c2f2d8"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "generated_handler_blocks/open_service_request_booked.json", "repository": "sharix-open-handlers-examples", "sha256": "7096cde8b581cc80b2f0f65dcc63e95adfdfdd8bf459e9a70ee229d329a7dcfc"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "catalog.py", "repository": "sharix-open-handlers-examples", "sha256": "e3dcb72b7e620e2837adacd7af053f35b04cdff475789496d9c114e17d57dfde"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "core/blockly_runtime.py", "repository": "sharix-open-handlers-backend", "sha256": "3e222150cbff315077c6c9b160d46e59856cedf6d6591d213e958c63cb2f2428"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "core/requesters.py", "repository": "sharix-open-handlers-backend", "sha256": "965a348cea477722bbaf4c8c6b06023eb238b71664a332f7ea8c90bfe72ea808"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "core/order_action_messages.py", "repository": "sharix-open-handlers-backend", "sha256": "046c262c0aabb02104fefca4e887324f99df22731e7726063f614aaf8839ca5c"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "ticket_blockly_codegen.py", "repository": "sharix-open-handlers-backend", "sha256": "bce71eab622922f8dd0954222842349799b60e18a0ab6310cc3e5f305603661e"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "ticket_codegen_contract.json", "repository": "sharix-open-handlers-backend", "sha256": "0bfd2b0ebb07bd380ed3c867386536ab88ef7dfa6e13f1cd8c91d32bb02c1ae9"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "lib/tickets.py", "repository": "sharix-open-tickets", "sha256": "0d260c17947f9a186d07af2749159780e3c7354a95b4bafe9d67493663c96883"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "api/handler_auth.py", "repository": "sharix-open-tickets", "sha256": "ac76dc45aaa9742e5e1da0b98aae914bb2e287048d33e97b4a245a6997bc8425"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "signals.py", "repository": "sharix-open-tickets", "sha256": "39aad8690a2e7d35cebfb052127a8130a951cbb4eea316c4f767a0a59fc5fa7e"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "services/handler_wakeup.py", "repository": "sharix-open-tickets", "sha256": "c9fdc62a18301fd7c075395c697d5b1c738c77713aa71fcbb5ab097e173d98de"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "apiviews/handler_order_workflow.py", "repository": "sharix-open-backend", "sha256": "35624ded6e67110437a25dd07caef214a04251eb0136194ae939fa32fef17e84"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "apiviews/open_api.py", "repository": "sharix-open-backend", "sha256": "cb8fdda304d29c2cc5c0fc938759a13c60022871b7b93d77883d521820021ad3"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/order_handler_relay.py", "repository": "sharix-open-backend", "sha256": "e49a7876169403970d995af464357e2134af19a398372c55db2a5b40681d731e"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/handler_order_context.py", "repository": "sharix-open-backend", "sha256": "f3c0731e74d30dbe5e59bd53040a06ee108f14f7aad04771e65d741cffeb7179"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/order_workflow_policy.py", "repository": "sharix-open-backend", "sha256": "3266c6ecab490a0e19c8bbc02041387b86fe4b14068750e545ba9bde8bf51326"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/order_actions.py", "repository": "sharix-open-backend", "sha256": "27ce243408a46f1b700d94bf78a25c68ef21d51078bb03627174e4a424d82ef0"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/order_permissions.py", "repository": "sharix-open-backend", "sha256": "9c1636daa80c4da68c3ae5cf347e279127d142eeff91e969559e8bd54ca3d81d"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "urls.py", "repository": "sharix-open-backend", "sha256": "61ffd2f0563291da2dcc9488a5443cb5e2c0395108740a6700034cfd90548158"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/order_lifecycle.py", "repository": "sharix-open-backend", "sha256": "66dd2c4db9da3aaf90cb080946c1920a4f9953d62d1e6c9e224dd52564c4d661"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/order_provider_requirements.py", "repository": "sharix-open-backend", "sha256": "392f1f9180a098a4749b5fe5b7948e34530ccdb2befed646e538cdb7a5ddcada"}]}</bpmn:documentation>
    <bpmn:laneSet id="backend_Lanes_backend">
      <bpmn:lane id="backend_Lane_user" name="Пользовательское действие: relay→apply-user-intent либо прямой actions API">
        <bpmn:flowNodeRef>backend_user</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>backend_acl</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>backend_choice</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>backend_take</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>backend_taken</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>backend_cancel</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>backend_cancelled</bpmn:flowNodeRef>
      </bpmn:lane>
      <bpmn:lane id="backend_Lane_worker" name="Scoped handler action move-booked-to-pending">
        <bpmn:flowNodeRef>backend_move</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>backend_scope</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>backend_state</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>backend_save</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>backend_done</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>backend_reject</bpmn:flowNodeRef>
      </bpmn:lane>
    </bpmn:laneSet>
    <bpmn:startEvent id="backend_user" name="take / cancel с actor">
      <bpmn:outgoing>backend_Flow_0</bpmn:outgoing>
      <bpmn:messageEventDefinition />
    </bpmn:startEvent>
    <bpmn:serviceTask id="backend_acl" name="Повторить права и проверить текущий заказ">
      <bpmn:incoming>backend_Flow_0</bpmn:incoming>
      <bpmn:outgoing>backend_Flow_1</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:exclusiveGateway id="backend_choice" name="Какое действие?">
      <bpmn:incoming>backend_Flow_1</bpmn:incoming>
      <bpmn:outgoing>backend_Flow_2</bpmn:outgoing>
      <bpmn:outgoing>backend_Flow_4</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:serviceTask id="backend_take" name="Provider, eligibility/concurrency и requirements; ASSIGNED">
      <bpmn:documentation>Назначить только допустимого Provider; недостающие check-действия могут быть подготовлены без успешного take.</bpmn:documentation>
      <bpmn:incoming>backend_Flow_2</bpmn:incoming>
      <bpmn:outgoing>backend_Flow_3</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:endEvent id="backend_taken" name="Ответ take: успех либо отказ">
      <bpmn:incoming>backend_Flow_3</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:serviceTask id="backend_cancel" name="Разрешённая отмена BOOKED → CANCELLED">
      <bpmn:incoming>backend_Flow_4</bpmn:incoming>
      <bpmn:outgoing>backend_Flow_5</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:endEvent id="backend_cancelled" name="Ответ cancel: сверить фактический результат">
      <bpmn:incoming>backend_Flow_5</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:startEvent id="backend_move" name="move-booked-to-pending">
      <bpmn:outgoing>backend_Flow_6</bpmn:outgoing>
      <bpmn:messageEventDefinition />
    </bpmn:startEvent>
    <bpmn:serviceTask id="backend_scope" name="Capability order.move_booked_to_pending; scope и lock">
      <bpmn:incoming>backend_Flow_6</bpmn:incoming>
      <bpmn:outgoing>backend_Flow_7</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:exclusiveGateway id="backend_state" name="BOOKED и provider отсутствует?">
      <bpmn:incoming>backend_Flow_7</bpmn:incoming>
      <bpmn:outgoing>backend_Flow_8</bpmn:outgoing>
      <bpmn:outgoing>backend_Flow_10</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:serviceTask id="backend_save" name="Канонический PENDING; Event и commit-события">
      <bpmn:incoming>backend_Flow_8</bpmn:incoming>
      <bpmn:outgoing>backend_Flow_9</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:endEvent id="backend_done" name="Новый владелец получит PENDING">
      <bpmn:incoming>backend_Flow_9</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:endEvent id="backend_reject" name="Доменный отказ: повторить по обычному recheck">
      <bpmn:incoming>backend_Flow_10</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:sequenceFlow id="backend_Flow_0" sourceRef="backend_user" targetRef="backend_acl" name="" />
    <bpmn:sequenceFlow id="backend_Flow_1" sourceRef="backend_acl" targetRef="backend_choice" name="" />
    <bpmn:sequenceFlow id="backend_Flow_2" sourceRef="backend_choice" targetRef="backend_take" name="take" />
    <bpmn:sequenceFlow id="backend_Flow_3" sourceRef="backend_take" targetRef="backend_taken" name="" />
    <bpmn:sequenceFlow id="backend_Flow_4" sourceRef="backend_choice" targetRef="backend_cancel" name="cancel" />
    <bpmn:sequenceFlow id="backend_Flow_5" sourceRef="backend_cancel" targetRef="backend_cancelled" name="" />
    <bpmn:sequenceFlow id="backend_Flow_6" sourceRef="backend_move" targetRef="backend_scope" name="" />
    <bpmn:sequenceFlow id="backend_Flow_7" sourceRef="backend_scope" targetRef="backend_state" name="" />
    <bpmn:sequenceFlow id="backend_Flow_8" sourceRef="backend_state" targetRef="backend_save" name="Да" />
    <bpmn:sequenceFlow id="backend_Flow_9" sourceRef="backend_save" targetRef="backend_done" name="" />
    <bpmn:sequenceFlow id="backend_Flow_10" sourceRef="backend_state" targetRef="backend_reject" name="Нет" />
  </bpmn:process>
  <bpmn:collaboration id="Collaboration_service_booked_actions">
    <bpmn:participant id="person_Participant" name="Допустимый Provider: take; автор/личный клиент заказа: cancel" />
    <bpmn:participant id="runtime_Participant" name="BOOKED handler: ASAP либо достигнут pending_at" />
    <bpmn:participant id="backend_Pool_backend" name="Backend: окончательные права, блокировки и актуальное состояние" processRef="backend_Process_backend" />
    <bpmn:messageFlow id="Message_service_booked_actions_0" sourceRef="person_Participant" targetRef="backend_user" name="Пользовательское действие с identity" />
    <bpmn:messageFlow id="Message_service_booked_actions_1" sourceRef="runtime_Participant" targetRef="backend_move" name="Узкое действие handler, не generic ticket.transition" />
  </bpmn:collaboration>
  <ns1:BPMNDiagram id="Diagram_service_booked_actions">
    <ns1:BPMNPlane id="Plane_service_booked_actions" bpmnElement="Collaboration_service_booked_actions">
      <ns1:BPMNShape id="DI_person_Participant" bpmnElement="person_Participant" isHorizontal="true">
        <ns2:Bounds x="0" y="0" width="2080.0" height="90" />
      </ns1:BPMNShape>
      <ns1:BPMNShape id="DI_runtime_Participant" bpmnElement="runtime_Participant" isHorizontal="true">
        <ns2:Bounds x="0" y="220" width="1900" height="90" />
      </ns1:BPMNShape>
      <ns1:BPMNShape id="backend_DI_Pool_backend" bpmnElement="backend_Pool_backend" isHorizontal="true">
        <ns2:Bounds x="0.0" y="450.0" width="1420" height="800" />
      </ns1:BPMNShape>
      <ns1:BPMNShape id="backend_DI_Lane_user" bpmnElement="backend_Lane_user" isHorizontal="true">
        <ns2:Bounds x="30.0" y="450.0" width="1390" height="390.0" />
      </ns1:BPMNShape>
      <ns1:BPMNShape id="backend_DI_Lane_worker" bpmnElement="backend_Lane_worker" isHorizontal="true">
        <ns2:Bounds x="30.0" y="840.0" width="1390" height="410.0" />
      </ns1:BPMNShape>
      <ns1:BPMNShape id="backend_DI_user" bpmnElement="backend_user">
        <ns2:Bounds x="132.0" y="532.0" width="36" height="36" />
      </ns1:BPMNShape>
      <ns1:BPMNShape id="backend_DI_acl" bpmnElement="backend_acl">
        <ns2:Bounds x="345.0" y="515.0" width="150" height="70" />
      </ns1:BPMNShape>
      <ns1:BPMNShape id="backend_DI_choice" bpmnElement="backend_choice">
        <ns2:Bounds x="675.0" y="525.0" width="50" height="50" />
      </ns1:BPMNShape>
      <ns1:BPMNShape id="backend_DI_take" bpmnElement="backend_take">
        <ns2:Bounds x="905.0" y="515.0" width="150" height="70" />
      </ns1:BPMNShape>
      <ns1:BPMNShape id="backend_DI_taken" bpmnElement="backend_taken">
        <ns2:Bounds x="1242.0" y="532.0" width="36" height="36" />
      </ns1:BPMNShape>
      <ns1:BPMNShape id="backend_DI_cancel" bpmnElement="backend_cancel">
        <ns2:Bounds x="905.0" y="695.0" width="150" height="70" />
      </ns1:BPMNShape>
      <ns1:BPMNShape id="backend_DI_cancelled" bpmnElement="backend_cancelled">
        <ns2:Bounds x="1242.0" y="712.0" width="36" height="36" />
      </ns1:BPMNShape>
      <ns1:BPMNShape id="backend_DI_move" bpmnElement="backend_move">
        <ns2:Bounds x="132.0" y="932.0" width="36" height="36" />
      </ns1:BPMNShape>
      <ns1:BPMNShape id="backend_DI_scope" bpmnElement="backend_scope">
        <ns2:Bounds x="345.0" y="915.0" width="150" height="70" />
      </ns1:BPMNShape>
      <ns1:BPMNShape id="backend_DI_state" bpmnElement="backend_state">
        <ns2:Bounds x="675.0" y="925.0" width="50" height="50" />
      </ns1:BPMNShape>
      <ns1:BPMNShape id="backend_DI_save" bpmnElement="backend_save">
        <ns2:Bounds x="905.0" y="915.0" width="150" height="70" />
      </ns1:BPMNShape>
      <ns1:BPMNShape id="backend_DI_done" bpmnElement="backend_done">
        <ns2:Bounds x="1242.0" y="932.0" width="36" height="36" />
      </ns1:BPMNShape>
      <ns1:BPMNShape id="backend_DI_reject" bpmnElement="backend_reject">
        <ns2:Bounds x="682.0" y="1132.0" width="36" height="36" />
      </ns1:BPMNShape>
      <ns1:BPMNEdge id="backend_DI_Flow_0" bpmnElement="backend_Flow_0">
        <ns3:waypoint x="168.0" y="550.0" />
        <ns3:waypoint x="345.0" y="550.0" />
      </ns1:BPMNEdge>
      <ns1:BPMNEdge id="backend_DI_Flow_1" bpmnElement="backend_Flow_1">
        <ns3:waypoint x="495.0" y="550.0" />
        <ns3:waypoint x="675.0" y="550.0" />
      </ns1:BPMNEdge>
      <ns1:BPMNEdge id="backend_DI_Flow_2" bpmnElement="backend_Flow_2">
        <ns3:waypoint x="725.0" y="550.0" />
        <ns3:waypoint x="905.0" y="550.0" />
      </ns1:BPMNEdge>
      <ns1:BPMNEdge id="backend_DI_Flow_3" bpmnElement="backend_Flow_3">
        <ns3:waypoint x="1055.0" y="550.0" />
        <ns3:waypoint x="1242.0" y="550.0" />
      </ns1:BPMNEdge>
      <ns1:BPMNEdge id="backend_DI_Flow_4" bpmnElement="backend_Flow_4">
        <ns3:waypoint x="725.0" y="550.0" />
        <ns3:waypoint x="815.0" y="550.0" />
        <ns3:waypoint x="815.0" y="730.0" />
        <ns3:waypoint x="905.0" y="730.0" />
      </ns1:BPMNEdge>
      <ns1:BPMNEdge id="backend_DI_Flow_5" bpmnElement="backend_Flow_5">
        <ns3:waypoint x="1055.0" y="730.0" />
        <ns3:waypoint x="1242.0" y="730.0" />
      </ns1:BPMNEdge>
      <ns1:BPMNEdge id="backend_DI_Flow_6" bpmnElement="backend_Flow_6">
        <ns3:waypoint x="168.0" y="950.0" />
        <ns3:waypoint x="345.0" y="950.0" />
      </ns1:BPMNEdge>
      <ns1:BPMNEdge id="backend_DI_Flow_7" bpmnElement="backend_Flow_7">
        <ns3:waypoint x="495.0" y="950.0" />
        <ns3:waypoint x="675.0" y="950.0" />
      </ns1:BPMNEdge>
      <ns1:BPMNEdge id="backend_DI_Flow_8" bpmnElement="backend_Flow_8">
        <ns3:waypoint x="725.0" y="950.0" />
        <ns3:waypoint x="905.0" y="950.0" />
      </ns1:BPMNEdge>
      <ns1:BPMNEdge id="backend_DI_Flow_9" bpmnElement="backend_Flow_9">
        <ns3:waypoint x="1055.0" y="950.0" />
        <ns3:waypoint x="1242.0" y="950.0" />
      </ns1:BPMNEdge>
      <ns1:BPMNEdge id="backend_DI_Flow_10" bpmnElement="backend_Flow_10">
        <ns3:waypoint x="700.0" y="975.0" />
        <ns3:waypoint x="700.0" y="1132.0" />
      </ns1:BPMNEdge>
      <ns1:BPMNEdge id="DI_Message_service_booked_actions_0" bpmnElement="Message_service_booked_actions_0">
        <ns3:waypoint x="150" y="90" />
        <ns3:waypoint x="150" y="532" />
        <ns1:BPMNLabel>
          <ns2:Bounds x="170" y="360" width="260" height="42" />
        </ns1:BPMNLabel>
      </ns1:BPMNEdge>
      <ns1:BPMNEdge id="DI_Message_service_booked_actions_1" bpmnElement="Message_service_booked_actions_1">
        <ns3:waypoint x="1880" y="310" />
        <ns3:waypoint x="2040" y="310" />
        <ns3:waypoint x="2040" y="900" />
        <ns3:waypoint x="150" y="900" />
        <ns3:waypoint x="150" y="932" />
        <ns1:BPMNLabel>
          <ns2:Bounds x="1000" y="865" width="260" height="42" />
        </ns1:BPMNLabel>
      </ns1:BPMNEdge>
    </ns1:BPMNPlane>
  </ns1:BPMNDiagram>
</bpmn:definitions>

Доставка через доверенный handler-intents и прямой actions API описаны в TEMPLATE. Ответ 202 relay не доказывает исполнение. Runtime принимает доверенное намерение в память, а backend повторно проверяет actor и актуальное состояние. После рестарта intent-очередь не заменяет persisted результат заказа.

Взять заказ

take доступен допустимому исполнителю, пока заказ BOOKED и provider ещё не назначен. Каноническая операция проверяет роль исполнителя сервиса, совместимый active Provider по service/company/resource, применимую политику одновременных заказов и требования выбранного исполнителя. Только затем сохраняет provider и переводит в ASSIGNED.

Подготовка недостающих check-действий может закончиться отказом взять заказ, если requirements ещё не удовлетворены. Появление такой заявки проверки не является успешным назначением, а этот BOOKED handler не обещает автоматически повторить уже отклонённый пользовательский take после её завершения. Нужно смотреть фактический ответ и состояние.

Отменить заказ

Допустимый автор/личный клиент может отменить свой BOOKED-заказ. Цель этой стадии — CANCELLED. Это отличается от отмены TEMPLATE, которая ведёт в CLOSED. Приоритет обработки queued intent перед автоматическим окном не отменяет backend-проверку актуального состояния и прав пользователя.

Перейти в PENDING

Узкий handler endpoint требует order.move_booked_to_pending, Ticket scope и единственный связанный заказ. Под блокировкой backend отвергает переход, если стадия уже не BOOKED или provider уже появился. Он не удаляет назначенного исполнителя ради поиска и не переводит заказ в PENDING по старому локальному снимку.

Успешный переход сохраняется каноническим action layer с Event и commit-событиями. Следующий владелец получает PENDING, прежний BOOKED исключает свой снимок по ticket.moved; потеря доставки восстанавливается scoped periodic reconciliation. Гонка take и автоматического перехода решается актуальным состоянием backend, а не очередностью уведомлений на экране.

Ожидание и диагностика

Назначение Настройка / состояние
Обычный повтор BOOKED SERVICE_REQUEST_BOOKED_RECHECK_SECONDS, awaiting_pending_window
Плановое окно SERVICE_REQUEST_PRE_START_DURATION_SECONDS и SERVICE_REQUEST_BOOKED_PENDING_LEAD_SECONDS
Общее исключение DEFERRED_TICKET_RECHECK_SECONDS, processing_error
Сверка очереди INTERVAL_TIME_BD_REQ

Defer хранится в памяти и освобождает worker. Новая authoritative revision либо разрешённый queued intent могут сделать Ticket готовым раньше; повтор того же снимка не сбрасывает обычное ожидание. Фактический запуск зависит от соединения и свободного worker. Ошибка API-списка не равна подтверждённой пустой очереди.

При долгом BOOKED проверить:

  • ASAP, planned_start и pending_at;
  • действующие именованные параметры времени;
  • актуальный provider;
  • для take — результат relay, канонического действия, подготовленных проверок и сохранённый ASSIGNED.

BOOKED с заполненным provider требует разбора согласованности; удалять provider ради успешного PENDING нельзя. Ожидание планового окна штатно. Предложения кандидатам относятся к PENDING, поэтому их отсутствие в BOOKED само по себе не означает поломку.

Проверенные источники

Git SHA/SHA-256 и параметры моделей закреплены в metadata и documentation BPMN. Handler и бизнес-действия при анализе не выполнялись; изменение источников требует повторного сопоставления.

Связанные материалы

sharixopen/knowledge/scenarios/service_request_booked.1793445617.txt.gz · Последнее изменение: — sx_knowledge_api_open

© 2022 ShariX