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

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


sharixopen:knowledge:scenarios:neg_request_accepted

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


NEG_REQUEST в ACCEPTED: активация Relationship и срок закрытия

Область: ShariX Open. Обработчик: open_neg_request_accepted, тип NEG_REQUEST (4), рабочий статус ACCEPTED (421). Опубликованный Python на 28.10.2026 побайтово совпадает с каноническим renderer его Blockly workspace. Фактическая выбранная версия конкретного сервера проверяется отдельно.

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

Handler сопровождает уже одобренный запрос на публичную dbsynce.Relationship: проверяет обязательные требования, запрашивает активацию и затем ждёт контрольного срока закрытия Ticket. Он не создаёт отсутствующую связь и не считает ACCEPTED доказательством выполненных requirements. NEGREQ_AUTOACCEPT здесь не проверяется.

Relationship этого сценария — направленная запись с user_who, user_whom, neg_type, необязательной company и ссылкой ticket_status. Это не Permissions, не универсальная выдача LDAP-роли и не отдельная модель Relationship/клиента ShariX Platform. В этой ветви нет permission-specific синхронизации Client/CorpClient из ACCESS_REQUEST.

Ключевое отличие от ACCESS_REQUEST/ACCEPTED: Relationship активируется до ожидания срока закрытия. Контрольный срок относится к Ticket и не задерживает саму активацию, если requirements и backend gate успешно пройдены.

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

Решения одного прохода (BPMN)

Схема BPMN

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

Исходник схемы
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_neg_accepted_decisions" targetNamespace="urn:sharix:knowledge:handlers">
  <bpmn:process id="negaccepted_Process_negaccepted" name="open_neg_request_accepted: requirements, активация Relationship и срок закрытия" isExecutable="false">
    <bpmn:documentation>{"notes": ["BPMN isExecutable=false. Генератор не исполняет handler.", "ACCEPTED — одобрение запроса, а не уже активное взаимоотношение.", "deferred_until — символ текущего локального срока; не имя параметра.", "После подтверждённой активации есть grace закрытия по NEG_REQUEST_DECLINED_CLEANUP_GRACE_DAYS от Ticket.updated_at; активация не ждёт grace."], "sources": [{"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "handlers/open_neg_request_accepted.py", "repository": "sharix-open-handlers-examples", "sha256": "48d25651729124cee187718f06d76b0cdc94e32dc3ca872270a5fb9f70c08aae"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "generated_handler_blocks/open_neg_request_accepted.json", "repository": "sharix-open-handlers-examples", "sha256": "250918c2a8974e2bb4d81243d6583b406cdb71e56a2552a2006bba552b68a89c"}, {"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/handler_operations.py", "repository": "sharix-open-handlers-backend", "sha256": "28620658501c375f556e24437871620b84a17a88d0b62b2d1a3cc5deb2f14b1e"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "core/ejabberd_muc.py", "repository": "sharix-open-handlers-backend", "sha256": "35c2eba89fab36b5c444439a87beaa516b55133991136d5370418d92a18d7bcd"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "core/requesters.py", "repository": "sharix-open-handlers-backend", "sha256": "965a348cea477722bbaf4c8c6b06023eb238b71664a332f7ea8c90bfe72ea808"}, {"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/views/handler_workflow.py", "repository": "sharix-open-tickets", "sha256": "f97c4b467a9a30749f5c4b86b39a833c430e57aaa1f030f70030d9b5c609d368"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "api/handler_auth.py", "repository": "sharix-open-tickets", "sha256": "ac76dc45aaa9742e5e1da0b98aae914bb2e287048d33e97b4a245a6997bc8425"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "utils.py", "repository": "sharix-open-tickets", "sha256": "a5680205c6522e1d9a74d9d267fe9ee96faf6f06436b00877fc0a93d80234bf5"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "views/ticket_detail.py", "repository": "sharix-open-tickets", "sha256": "05d344b0fba14cf895400694d4a18f486c800fef08dd1acb43ea46909b9e7e59"}, {"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_workflow.py", "repository": "sharix-open-backend", "sha256": "0f699a4e16760cbbdd09d894093c685ba69073fedf0522852cb1fdc9811636e3"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/activation.py", "repository": "sharix-open-backend", "sha256": "f78d4e219a5b83c7952bd366a4e7a711589b1d382af653a0c453c0524e4220f7"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/requirement_actions.py", "repository": "sharix-open-backend", "sha256": "717ef0f3e02ff8e6da103b5fdbae584b01d84d177f6e62ae677a1c5a366b71de"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/requirement_checks.py", "repository": "sharix-open-backend", "sha256": "5a73a6e71307e734f0c0e480fd14a825a7a22242811e2523b7f25157224cf34c"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/document_drafts.py", "repository": "sharix-open-backend", "sha256": "383b117f01fdd9d16de3ceb9afb1ccf0bf3104c4966b23e987b8a90e9a46f071"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/verification_workflow.py", "repository": "sharix-open-backend", "sha256": "9fe62f8344d7fd78e5af0ce025c82ba4f7d21759e71f518df1186a1d6a4a0644"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "models/relationship.py", "repository": "sharix-open-backend", "sha256": "873f27666a7d03b8058958b752d0e69d17d3433daf72f901fa88275cf10f43aa"}]}</bpmn:documentation>
    <bpmn:laneSet id="negaccepted_Lanes_negaccepted">
      <bpmn:lane id="negaccepted_Lane_worker" name="Один проход Python: ожидание означает возврат Ticket с defer">
        <bpmn:flowNodeRef>negaccepted_start</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>negaccepted_status</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>negaccepted_lookup</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>negaccepted_exists</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>negaccepted_requirements</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>negaccepted_met</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>negaccepted_activate</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>negaccepted_active</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>negaccepted_close</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>negaccepted_confirmed</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>negaccepted_remove</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>negaccepted_done</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>negaccepted_stale</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>negaccepted_stale_end</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>negaccepted_missing</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>negaccepted_missing_wait</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>negaccepted_need</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>negaccepted_need_wait</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>negaccepted_inconsistent</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>negaccepted_activation_wait</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>negaccepted_not_found</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>negaccepted_lookup_error</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>negaccepted_requirements_error</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>negaccepted_activate_error</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>negaccepted_close_error</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>negaccepted_retry</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>negaccepted_age</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>negaccepted_grace</bpmn:flowNodeRef>
      </bpmn:lane>
    </bpmn:laneSet>
    <bpmn:startEvent id="negaccepted_start" name="Ticket готов к проходу">
      <bpmn:outgoing>negaccepted_Flow_0</bpmn:outgoing>
    </bpmn:startEvent>
    <bpmn:exclusiveGateway id="negaccepted_status" name="Статус ACCEPTED?">
      <bpmn:incoming>negaccepted_Flow_0</bpmn:incoming>
      <bpmn:outgoing>negaccepted_Flow_1</bpmn:outgoing>
      <bpmn:outgoing>negaccepted_Flow_2</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:serviceTask id="negaccepted_lookup" name="Scoped API: найти relationship">
      <bpmn:incoming>negaccepted_Flow_1</bpmn:incoming>
      <bpmn:outgoing>negaccepted_Flow_4</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:exclusiveGateway id="negaccepted_exists" name="Permission найдена?">
      <bpmn:incoming>negaccepted_Flow_4</bpmn:incoming>
      <bpmn:outgoing>negaccepted_Flow_5</bpmn:outgoing>
      <bpmn:outgoing>negaccepted_Flow_6</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:serviceTask id="negaccepted_requirements" name="API: ensure actions + проверить requirements">
      <bpmn:incoming>negaccepted_Flow_5</bpmn:incoming>
      <bpmn:outgoing>negaccepted_Flow_8</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:exclusiveGateway id="negaccepted_met" name="Все требования ok?">
      <bpmn:incoming>negaccepted_Flow_8</bpmn:incoming>
      <bpmn:outgoing>negaccepted_Flow_9</bpmn:outgoing>
      <bpmn:outgoing>negaccepted_Flow_10</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:serviceTask id="negaccepted_activate" name="API: активировать relationship с повторным gate">
      <bpmn:incoming>negaccepted_Flow_9</bpmn:incoming>
      <bpmn:outgoing>negaccepted_Flow_12</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:exclusiveGateway id="negaccepted_active" name="Активация подтверждена?">
      <bpmn:incoming>negaccepted_Flow_12</bpmn:incoming>
      <bpmn:outgoing>negaccepted_Flow_13</bpmn:outgoing>
      <bpmn:outgoing>negaccepted_Flow_14</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:serviceTask id="negaccepted_close" name="Scoped Ticket API: CLOSED">
      <bpmn:incoming>negaccepted_Flow_24</bpmn:incoming>
      <bpmn:outgoing>negaccepted_Flow_16</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:exclusiveGateway id="negaccepted_confirmed" name="Переход подтверждён?">
      <bpmn:incoming>negaccepted_Flow_16</bpmn:incoming>
      <bpmn:outgoing>negaccepted_Flow_17</bpmn:outgoing>
      <bpmn:outgoing>negaccepted_Flow_18</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:serviceTask id="negaccepted_remove" name="Убрать Ticket и комнату">
      <bpmn:incoming>negaccepted_Flow_17</bpmn:incoming>
      <bpmn:outgoing>negaccepted_Flow_19</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:endEvent id="negaccepted_done" name="Этот проход завершён">
      <bpmn:incoming>negaccepted_Flow_19</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:serviceTask id="negaccepted_stale" name="Убрать Ticket и комнату">
      <bpmn:incoming>negaccepted_Flow_2</bpmn:incoming>
      <bpmn:outgoing>negaccepted_Flow_3</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:endEvent id="negaccepted_stale_end" name="Прежний владелец освобождён">
      <bpmn:incoming>negaccepted_Flow_3</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:sendTask id="negaccepted_missing" name="ALERT администраторам: relationship не найдена">
      <bpmn:incoming>negaccepted_Flow_6</bpmn:incoming>
      <bpmn:outgoing>negaccepted_Flow_7</bpmn:outgoing>
    </bpmn:sendTask>
    <bpmn:serviceTask id="negaccepted_missing_wait" name="related_relationship_missing; defer">
      <bpmn:documentation>NEG_REQUEST_INCONSISTENCY_RECHECK_SECONDS; локально related_relationship_missing, в журнале defer related_relationship_inconsistent.</bpmn:documentation>
      <bpmn:incoming>negaccepted_Flow_7</bpmn:incoming>
    </bpmn:serviceTask>
    <bpmn:sendTask id="negaccepted_need" name="Уведомить автора и администраторов о требованиях">
      <bpmn:incoming>negaccepted_Flow_10</bpmn:incoming>
      <bpmn:outgoing>negaccepted_Flow_11</bpmn:outgoing>
    </bpmn:sendTask>
    <bpmn:serviceTask id="negaccepted_need_wait" name="requirements_pending; defer">
      <bpmn:documentation>NEG_REQUEST_INCONSISTENCY_RECHECK_SECONDS</bpmn:documentation>
      <bpmn:incoming>negaccepted_Flow_11</bpmn:incoming>
    </bpmn:serviceTask>
    <bpmn:sendTask id="negaccepted_inconsistent" name="ALERT: активация не подтверждена">
      <bpmn:incoming>negaccepted_Flow_14</bpmn:incoming>
      <bpmn:outgoing>negaccepted_Flow_15</bpmn:outgoing>
    </bpmn:sendTask>
    <bpmn:serviceTask id="negaccepted_activation_wait" name="related_relationship_inconsistent; 900 с">
      <bpmn:incoming>negaccepted_Flow_15</bpmn:incoming>
    </bpmn:serviceTask>
    <bpmn:endEvent id="negaccepted_not_found" name="404: очистка уже запрошена">
      <bpmn:incoming>negaccepted_Flow_18</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:boundaryEvent id="negaccepted_lookup_error" name="Ошибка read API" attachedToRef="negaccepted_lookup" cancelActivity="true">
      <bpmn:outgoing>negaccepted_Flow_20</bpmn:outgoing>
      <bpmn:errorEventDefinition />
    </bpmn:boundaryEvent>
    <bpmn:boundaryEvent id="negaccepted_requirements_error" name="Ошибка requirements API" attachedToRef="negaccepted_requirements" cancelActivity="true">
      <bpmn:outgoing>negaccepted_Flow_21</bpmn:outgoing>
      <bpmn:errorEventDefinition />
    </bpmn:boundaryEvent>
    <bpmn:boundaryEvent id="negaccepted_activate_error" name="401/403/429/5xx" attachedToRef="negaccepted_activate" cancelActivity="true">
      <bpmn:outgoing>negaccepted_Flow_22</bpmn:outgoing>
      <bpmn:errorEventDefinition />
    </bpmn:boundaryEvent>
    <bpmn:boundaryEvent id="negaccepted_close_error" name="Ошибка перехода" attachedToRef="negaccepted_close" cancelActivity="true">
      <bpmn:outgoing>negaccepted_Flow_23</bpmn:outgoing>
      <bpmn:errorEventDefinition />
    </bpmn:boundaryEvent>
    <bpmn:serviceTask id="negaccepted_retry" name="Общий processing_error + defer">
      <bpmn:documentation>DEFERRED_TICKET_RECHECK_SECONDS. Ошибки уведомлений также попадают сюда.</bpmn:documentation>
      <bpmn:incoming>negaccepted_Flow_20</bpmn:incoming>
      <bpmn:incoming>negaccepted_Flow_21</bpmn:incoming>
      <bpmn:incoming>negaccepted_Flow_22</bpmn:incoming>
      <bpmn:incoming>negaccepted_Flow_23</bpmn:incoming>
    </bpmn:serviceTask>
    <bpmn:exclusiveGateway id="negaccepted_age" name="Срок от updated_at наступил?">
      <bpmn:documentation>NEG_REQUEST_DECLINED_CLEANUP_GRACE_DAYS; минимум 0 дней.</bpmn:documentation>
      <bpmn:incoming>negaccepted_Flow_13</bpmn:incoming>
      <bpmn:outgoing>negaccepted_Flow_24</bpmn:outgoing>
      <bpmn:outgoing>negaccepted_Flow_25</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:serviceTask id="negaccepted_grace" name="neg_request_close_grace; короткий defer">
      <bpmn:documentation>min(updated_at+grace_days, now+DEFERRED_TICKET_RECHECK_SECONDS). Вернуть Ticket без деактивации Relationship.</bpmn:documentation>
      <bpmn:incoming>negaccepted_Flow_25</bpmn:incoming>
    </bpmn:serviceTask>
    <bpmn:sequenceFlow id="negaccepted_Flow_0" sourceRef="negaccepted_start" targetRef="negaccepted_status" name="" />
    <bpmn:sequenceFlow id="negaccepted_Flow_1" sourceRef="negaccepted_status" targetRef="negaccepted_lookup" name="Да" />
    <bpmn:sequenceFlow id="negaccepted_Flow_2" sourceRef="negaccepted_status" targetRef="negaccepted_stale" name="Нет" />
    <bpmn:sequenceFlow id="negaccepted_Flow_3" sourceRef="negaccepted_stale" targetRef="negaccepted_stale_end" name="" />
    <bpmn:sequenceFlow id="negaccepted_Flow_4" sourceRef="negaccepted_lookup" targetRef="negaccepted_exists" name="" />
    <bpmn:sequenceFlow id="negaccepted_Flow_5" sourceRef="negaccepted_exists" targetRef="negaccepted_requirements" name="Да" />
    <bpmn:sequenceFlow id="negaccepted_Flow_6" sourceRef="negaccepted_exists" targetRef="negaccepted_missing" name="Нет" />
    <bpmn:sequenceFlow id="negaccepted_Flow_7" sourceRef="negaccepted_missing" targetRef="negaccepted_missing_wait" name="" />
    <bpmn:sequenceFlow id="negaccepted_Flow_8" sourceRef="negaccepted_requirements" targetRef="negaccepted_met" name="" />
    <bpmn:sequenceFlow id="negaccepted_Flow_9" sourceRef="negaccepted_met" targetRef="negaccepted_activate" name="Да" />
    <bpmn:sequenceFlow id="negaccepted_Flow_10" sourceRef="negaccepted_met" targetRef="negaccepted_need" name="Нет" />
    <bpmn:sequenceFlow id="negaccepted_Flow_11" sourceRef="negaccepted_need" targetRef="negaccepted_need_wait" name="" />
    <bpmn:sequenceFlow id="negaccepted_Flow_12" sourceRef="negaccepted_activate" targetRef="negaccepted_active" name="" />
    <bpmn:sequenceFlow id="negaccepted_Flow_13" sourceRef="negaccepted_active" targetRef="negaccepted_age" name="Да" />
    <bpmn:sequenceFlow id="negaccepted_Flow_14" sourceRef="negaccepted_active" targetRef="negaccepted_inconsistent" name="Нет" />
    <bpmn:sequenceFlow id="negaccepted_Flow_15" sourceRef="negaccepted_inconsistent" targetRef="negaccepted_activation_wait" name="" />
    <bpmn:sequenceFlow id="negaccepted_Flow_16" sourceRef="negaccepted_close" targetRef="negaccepted_confirmed" name="" />
    <bpmn:sequenceFlow id="negaccepted_Flow_17" sourceRef="negaccepted_confirmed" targetRef="negaccepted_remove" name="Да" />
    <bpmn:sequenceFlow id="negaccepted_Flow_18" sourceRef="negaccepted_confirmed" targetRef="negaccepted_not_found" name="Нет (404)" />
    <bpmn:sequenceFlow id="negaccepted_Flow_19" sourceRef="negaccepted_remove" targetRef="negaccepted_done" name="" />
    <bpmn:sequenceFlow id="negaccepted_Flow_20" sourceRef="negaccepted_lookup_error" targetRef="negaccepted_retry" name="" />
    <bpmn:sequenceFlow id="negaccepted_Flow_21" sourceRef="negaccepted_requirements_error" targetRef="negaccepted_retry" name="" />
    <bpmn:sequenceFlow id="negaccepted_Flow_22" sourceRef="negaccepted_activate_error" targetRef="negaccepted_retry" name="" />
    <bpmn:sequenceFlow id="negaccepted_Flow_23" sourceRef="negaccepted_close_error" targetRef="negaccepted_retry" name="" />
    <bpmn:sequenceFlow id="negaccepted_Flow_24" sourceRef="negaccepted_age" targetRef="negaccepted_close" name="Да" />
    <bpmn:sequenceFlow id="negaccepted_Flow_25" sourceRef="negaccepted_age" targetRef="negaccepted_grace" name="Нет" />
  </bpmn:process>
  <bpmn:collaboration id="Collaboration_neg_accepted_decisions">
    <bpmn:participant id="negaccepted_Pool_negaccepted" name="open_neg_request_accepted: requirements, активация Relationship и срок закрытия" processRef="negaccepted_Process_negaccepted" />
  </bpmn:collaboration>
  <bpmndi:BPMNDiagram id="Diagram_neg_accepted_decisions">
    <bpmndi:BPMNPlane id="Plane_neg_accepted_decisions" bpmnElement="Collaboration_neg_accepted_decisions">
      <bpmndi:BPMNShape id="negaccepted_DI_Pool_negaccepted" bpmnElement="negaccepted_Pool_negaccepted" isHorizontal="true">
        <dc:Bounds x="0.0" y="0.0" width="3240" height="610" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_Lane_worker" bpmnElement="negaccepted_Lane_worker" isHorizontal="true">
        <dc:Bounds x="30.0" y="0.0" width="3210" height="610" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_start" bpmnElement="negaccepted_start">
        <dc:Bounds x="132.0" y="92.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_status" bpmnElement="negaccepted_status">
        <dc:Bounds x="325.0" y="85.0" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_lookup" bpmnElement="negaccepted_lookup">
        <dc:Bounds x="515.0" y="75.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_exists" bpmnElement="negaccepted_exists">
        <dc:Bounds x="815.0" y="85.0" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_requirements" bpmnElement="negaccepted_requirements">
        <dc:Bounds x="1015.0" y="75.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_met" bpmnElement="negaccepted_met">
        <dc:Bounds x="1315.0" y="85.0" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_activate" bpmnElement="negaccepted_activate">
        <dc:Bounds x="1515.0" y="75.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_active" bpmnElement="negaccepted_active">
        <dc:Bounds x="1815.0" y="85.0" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_close" bpmnElement="negaccepted_close">
        <dc:Bounds x="2275.0" y="75.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_confirmed" bpmnElement="negaccepted_confirmed">
        <dc:Bounds x="2575.0" y="85.0" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_remove" bpmnElement="negaccepted_remove">
        <dc:Bounds x="2775.0" y="75.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_done" bpmnElement="negaccepted_done">
        <dc:Bounds x="3062.0" y="92.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_stale" bpmnElement="negaccepted_stale">
        <dc:Bounds x="275.0" y="275.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_stale_end" bpmnElement="negaccepted_stale_end">
        <dc:Bounds x="572.0" y="292.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_missing" bpmnElement="negaccepted_missing">
        <dc:Bounds x="765.0" y="275.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_missing_wait" bpmnElement="negaccepted_missing_wait">
        <dc:Bounds x="765.0" y="475.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_need" bpmnElement="negaccepted_need">
        <dc:Bounds x="1265.0" y="275.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_need_wait" bpmnElement="negaccepted_need_wait">
        <dc:Bounds x="1265.0" y="475.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_inconsistent" bpmnElement="negaccepted_inconsistent">
        <dc:Bounds x="1765.0" y="275.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_activation_wait" bpmnElement="negaccepted_activation_wait">
        <dc:Bounds x="1765.0" y="475.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_not_found" bpmnElement="negaccepted_not_found">
        <dc:Bounds x="2582.0" y="292.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_lookup_error" bpmnElement="negaccepted_lookup_error">
        <dc:Bounds x="622.0" y="127.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_requirements_error" bpmnElement="negaccepted_requirements_error">
        <dc:Bounds x="1122.0" y="127.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_activate_error" bpmnElement="negaccepted_activate_error">
        <dc:Bounds x="1622.0" y="127.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_close_error" bpmnElement="negaccepted_close_error">
        <dc:Bounds x="2382.0" y="127.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_retry" bpmnElement="negaccepted_retry">
        <dc:Bounds x="2515.0" y="475.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_age" bpmnElement="negaccepted_age">
        <dc:Bounds x="2065.0" y="85.0" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="negaccepted_DI_grace" bpmnElement="negaccepted_grace">
        <dc:Bounds x="2015.0" y="475.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="negaccepted_DI_Flow_0" bpmnElement="negaccepted_Flow_0">
        <di:waypoint x="168.0" y="110.0" />
        <di:waypoint x="325.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="negaccepted_DI_Flow_1" bpmnElement="negaccepted_Flow_1">
        <di:waypoint x="375.0" y="110.0" />
        <di:waypoint x="515.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="negaccepted_DI_Flow_2" bpmnElement="negaccepted_Flow_2">
        <di:waypoint x="350.0" y="135.0" />
        <di:waypoint x="350.0" y="275.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="negaccepted_DI_Flow_3" bpmnElement="negaccepted_Flow_3">
        <di:waypoint x="425.0" y="310.0" />
        <di:waypoint x="572.0" y="310.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="negaccepted_DI_Flow_4" bpmnElement="negaccepted_Flow_4">
        <di:waypoint x="665.0" y="110.0" />
        <di:waypoint x="815.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="negaccepted_DI_Flow_5" bpmnElement="negaccepted_Flow_5">
        <di:waypoint x="865.0" y="110.0" />
        <di:waypoint x="1015.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="negaccepted_DI_Flow_6" bpmnElement="negaccepted_Flow_6">
        <di:waypoint x="840.0" y="135.0" />
        <di:waypoint x="840.0" y="275.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="negaccepted_DI_Flow_7" bpmnElement="negaccepted_Flow_7">
        <di:waypoint x="840.0" y="345.0" />
        <di:waypoint x="840.0" y="475.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="negaccepted_DI_Flow_8" bpmnElement="negaccepted_Flow_8">
        <di:waypoint x="1165.0" y="110.0" />
        <di:waypoint x="1315.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="negaccepted_DI_Flow_9" bpmnElement="negaccepted_Flow_9">
        <di:waypoint x="1365.0" y="110.0" />
        <di:waypoint x="1515.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="negaccepted_DI_Flow_10" bpmnElement="negaccepted_Flow_10">
        <di:waypoint x="1340.0" y="135.0" />
        <di:waypoint x="1340.0" y="275.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="negaccepted_DI_Flow_11" bpmnElement="negaccepted_Flow_11">
        <di:waypoint x="1340.0" y="345.0" />
        <di:waypoint x="1340.0" y="475.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="negaccepted_DI_Flow_12" bpmnElement="negaccepted_Flow_12">
        <di:waypoint x="1665.0" y="110.0" />
        <di:waypoint x="1815.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="negaccepted_DI_Flow_13" bpmnElement="negaccepted_Flow_13">
        <di:waypoint x="1865.0" y="110.0" />
        <di:waypoint x="2065.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="negaccepted_DI_Flow_14" bpmnElement="negaccepted_Flow_14">
        <di:waypoint x="1840.0" y="135.0" />
        <di:waypoint x="1840.0" y="275.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="negaccepted_DI_Flow_15" bpmnElement="negaccepted_Flow_15">
        <di:waypoint x="1840.0" y="345.0" />
        <di:waypoint x="1840.0" y="475.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="negaccepted_DI_Flow_16" bpmnElement="negaccepted_Flow_16">
        <di:waypoint x="2425.0" y="110.0" />
        <di:waypoint x="2575.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="negaccepted_DI_Flow_17" bpmnElement="negaccepted_Flow_17">
        <di:waypoint x="2625.0" y="110.0" />
        <di:waypoint x="2775.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="negaccepted_DI_Flow_18" bpmnElement="negaccepted_Flow_18">
        <di:waypoint x="2600.0" y="135.0" />
        <di:waypoint x="2600.0" y="292.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="negaccepted_DI_Flow_19" bpmnElement="negaccepted_Flow_19">
        <di:waypoint x="2925.0" y="110.0" />
        <di:waypoint x="3062.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="negaccepted_DI_Flow_20" bpmnElement="negaccepted_Flow_20">
        <di:waypoint x="658.0" y="145.0" />
        <di:waypoint x="700.0" y="145.0" />
        <di:waypoint x="700.0" y="590.0" />
        <di:waypoint x="2590.0" y="590.0" />
        <di:waypoint x="2590.0" y="475.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="negaccepted_DI_Flow_21" bpmnElement="negaccepted_Flow_21">
        <di:waypoint x="1158.0" y="145.0" />
        <di:waypoint x="1200.0" y="145.0" />
        <di:waypoint x="1200.0" y="570.0" />
        <di:waypoint x="2590.0" y="570.0" />
        <di:waypoint x="2590.0" y="475.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="negaccepted_DI_Flow_22" bpmnElement="negaccepted_Flow_22">
        <di:waypoint x="1658.0" y="145.0" />
        <di:waypoint x="1700.0" y="145.0" />
        <di:waypoint x="1700.0" y="550.0" />
        <di:waypoint x="2590.0" y="550.0" />
        <di:waypoint x="2590.0" y="475.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="negaccepted_DI_Flow_23" bpmnElement="negaccepted_Flow_23">
        <di:waypoint x="2418.0" y="145.0" />
        <di:waypoint x="2460.0" y="145.0" />
        <di:waypoint x="2590.0" y="145.0" />
        <di:waypoint x="2590.0" y="475.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="negaccepted_DI_Flow_24" bpmnElement="negaccepted_Flow_24">
        <di:waypoint x="2115.0" y="110.0" />
        <di:waypoint x="2275.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="negaccepted_DI_Flow_25" bpmnElement="negaccepted_Flow_25">
        <di:waypoint x="2090.0" y="135.0" />
        <di:waypoint x="2090.0" y="475.0" />
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>
  • Чужой статус — запросить удаление локального Ticket и комнаты.
  • Relationship не найдена — ALERT администраторам, локальная причина related_relationship_missing, повтор по NEG_REQUEST_INCONSISTENCY_RECHECK_SECONDS. В журнал defer в этой ветви передаётся строка related_relationship_inconsistent; она не переписывает сохранённую локальную причину.
  • Requirements не выполнены — уведомить автора и администраторов, записать requirements_pending и назначить тот же именованный повтор. Связь этим handler не активируется, Ticket остаётся ACCEPTED.
  • Requirements выполнены — запросить каноническую активацию Relationship. Обработанный отрицательный результат вызывает ALERT, related_relationship_inconsistent и повтор через 900 секунд; это текущая константа Python.
  • Активация подтверждена — проверить срок от Ticket.updated_at. При наступившем сроке запросить CLOSED, затем убрать локальный Ticket/комнату. До наступления срока — neg_request_close_grace и короткий defer.

В workspace используется typed block sx_activate_related_relationship. Его каноническое раскрытие в Python включает guard неуспешной активации с ALERT/900-секундным повтором; этот исход показан на схеме и не пропущен при описании одного action-блока.

Требования и backend gate (BPMN)

Схема BPMN

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

Исходник схемы
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_neg_accepted_gate" targetNamespace="urn:sharix:knowledge:handlers">
  <bpmn:process id="gate_Process_gate" name="Backend: два последовательных scoped запроса с разными задачами" isExecutable="false">
    <bpmn:documentation>{"notes": ["BPMN isExecutable=false. Генератор не исполняет handler.", "ACCEPTED — одобрение запроса, а не уже активное взаимоотношение.", "deferred_until — символ текущего локального срока; не имя параметра.", "GET requirements здесь имеет side effects подготовки действий.", "Ни прямой status=0, ни исходный ok не обходят повторный gate.", "После подтверждённой активации есть grace закрытия по NEG_REQUEST_DECLINED_CLEANUP_GRACE_DAYS от Ticket.updated_at; активация не ждёт grace."], "sources": [{"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "handlers/open_neg_request_accepted.py", "repository": "sharix-open-handlers-examples", "sha256": "48d25651729124cee187718f06d76b0cdc94e32dc3ca872270a5fb9f70c08aae"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "generated_handler_blocks/open_neg_request_accepted.json", "repository": "sharix-open-handlers-examples", "sha256": "250918c2a8974e2bb4d81243d6583b406cdb71e56a2552a2006bba552b68a89c"}, {"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/handler_operations.py", "repository": "sharix-open-handlers-backend", "sha256": "28620658501c375f556e24437871620b84a17a88d0b62b2d1a3cc5deb2f14b1e"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "core/ejabberd_muc.py", "repository": "sharix-open-handlers-backend", "sha256": "35c2eba89fab36b5c444439a87beaa516b55133991136d5370418d92a18d7bcd"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "core/requesters.py", "repository": "sharix-open-handlers-backend", "sha256": "965a348cea477722bbaf4c8c6b06023eb238b71664a332f7ea8c90bfe72ea808"}, {"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/views/handler_workflow.py", "repository": "sharix-open-tickets", "sha256": "f97c4b467a9a30749f5c4b86b39a833c430e57aaa1f030f70030d9b5c609d368"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "api/handler_auth.py", "repository": "sharix-open-tickets", "sha256": "ac76dc45aaa9742e5e1da0b98aae914bb2e287048d33e97b4a245a6997bc8425"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "utils.py", "repository": "sharix-open-tickets", "sha256": "a5680205c6522e1d9a74d9d267fe9ee96faf6f06436b00877fc0a93d80234bf5"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "views/ticket_detail.py", "repository": "sharix-open-tickets", "sha256": "05d344b0fba14cf895400694d4a18f486c800fef08dd1acb43ea46909b9e7e59"}, {"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_workflow.py", "repository": "sharix-open-backend", "sha256": "0f699a4e16760cbbdd09d894093c685ba69073fedf0522852cb1fdc9811636e3"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/activation.py", "repository": "sharix-open-backend", "sha256": "f78d4e219a5b83c7952bd366a4e7a711589b1d382af653a0c453c0524e4220f7"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/requirement_actions.py", "repository": "sharix-open-backend", "sha256": "717ef0f3e02ff8e6da103b5fdbae584b01d84d177f6e62ae677a1c5a366b71de"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/requirement_checks.py", "repository": "sharix-open-backend", "sha256": "5a73a6e71307e734f0c0e480fd14a825a7a22242811e2523b7f25157224cf34c"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/document_drafts.py", "repository": "sharix-open-backend", "sha256": "383b117f01fdd9d16de3ceb9afb1ccf0bf3104c4966b23e987b8a90e9a46f071"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/verification_workflow.py", "repository": "sharix-open-backend", "sha256": "9fe62f8344d7fd78e5af0ce025c82ba4f7d21759e71f518df1186a1d6a4a0644"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "models/relationship.py", "repository": "sharix-open-backend", "sha256": "873f27666a7d03b8058958b752d0e69d17d3433daf72f901fa88275cf10f43aa"}]}</bpmn:documentation>
    <bpmn:laneSet id="gate_Lanes_gate">
      <bpmn:lane id="gate_Lane_read" name="GET requirements: подготовка действий и оценка">
        <bpmn:flowNodeRef>gate_start</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>gate_scope</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>gate_ensure</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>gate_evaluate</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>gate_response</bpmn:flowNodeRef>
      </bpmn:lane>
      <bpmn:lane id="gate_Lane_activate" name="POST relationship set_status=0: каноническая активация">
        <bpmn:flowNodeRef>gate_request</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>gate_lock</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>gate_gate</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>gate_ok</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>gate_save</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>gate_event</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>gate_end</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>gate_deny</bpmn:flowNodeRef>
      </bpmn:lane>
    </bpmn:laneSet>
    <bpmn:startEvent id="gate_start" name="GET requirements?model=relationship">
      <bpmn:outgoing>gate_Flow_0</bpmn:outgoing>
      <bpmn:messageEventDefinition />
    </bpmn:startEvent>
    <bpmn:serviceTask id="gate_scope" name="Identity, capability, Ticket scope">
      <bpmn:incoming>gate_Flow_0</bpmn:incoming>
      <bpmn:outgoing>gate_Flow_1</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:serviceTask id="gate_ensure" name="Создать / переиспользовать недостающие действия">
      <bpmn:documentation>Обязательные черновики документов и попытки проверок, связанные ST_REQUEST при наличии настроенной очереди.</bpmn:documentation>
      <bpmn:incoming>gate_Flow_1</bpmn:incoming>
      <bpmn:outgoing>gate_Flow_2</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:serviceTask id="gate_evaluate" name="Read-only evaluate_requirements">
      <bpmn:incoming>gate_Flow_2</bpmn:incoming>
      <bpmn:outgoing>gate_Flow_3</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:endEvent id="gate_response" name="ok, required, present, missing, details">
      <bpmn:incoming>gate_Flow_3</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:startEvent id="gate_request" name="POST relationship set_status=0">
      <bpmn:outgoing>gate_Flow_4</bpmn:outgoing>
      <bpmn:messageEventDefinition />
    </bpmn:startEvent>
    <bpmn:serviceTask id="gate_lock" name="Scope и блокировки Ticket / relationship">
      <bpmn:incoming>gate_Flow_4</bpmn:incoming>
      <bpmn:outgoing>gate_Flow_5</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:serviceTask id="gate_gate" name="ensure actions + повторная оценка требований">
      <bpmn:incoming>gate_Flow_5</bpmn:incoming>
      <bpmn:outgoing>gate_Flow_6</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:exclusiveGateway id="gate_ok" name="Все обязательные требования ok?">
      <bpmn:incoming>gate_Flow_6</bpmn:incoming>
      <bpmn:outgoing>gate_Flow_7</bpmn:outgoing>
      <bpmn:outgoing>gate_Flow_8</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:serviceTask id="gate_save" name="Сохранить Relationship active и связь с Ticket">
      <bpmn:documentation>status=0 через канонический gate. Здесь нет permission-specific синхронизации Client/CorpClient и выдачи LDAP-роли.</bpmn:documentation>
      <bpmn:incoming>gate_Flow_7</bpmn:incoming>
      <bpmn:outgoing>gate_Flow_9</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:serviceTask id="gate_event" name="Записать Event, вернуть успешный ответ">
      <bpmn:incoming>gate_Flow_9</bpmn:incoming>
      <bpmn:outgoing>gate_Flow_10</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:endEvent id="gate_end" name="Активация зафиксирована">
      <bpmn:incoming>gate_Flow_10</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:endEvent id="gate_deny" name="Ошибка: активация не разрешена">
      <bpmn:incoming>gate_Flow_8</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:sequenceFlow id="gate_Flow_0" sourceRef="gate_start" targetRef="gate_scope" name="" />
    <bpmn:sequenceFlow id="gate_Flow_1" sourceRef="gate_scope" targetRef="gate_ensure" name="" />
    <bpmn:sequenceFlow id="gate_Flow_2" sourceRef="gate_ensure" targetRef="gate_evaluate" name="" />
    <bpmn:sequenceFlow id="gate_Flow_3" sourceRef="gate_evaluate" targetRef="gate_response" name="" />
    <bpmn:sequenceFlow id="gate_Flow_4" sourceRef="gate_request" targetRef="gate_lock" name="" />
    <bpmn:sequenceFlow id="gate_Flow_5" sourceRef="gate_lock" targetRef="gate_gate" name="" />
    <bpmn:sequenceFlow id="gate_Flow_6" sourceRef="gate_gate" targetRef="gate_ok" name="" />
    <bpmn:sequenceFlow id="gate_Flow_7" sourceRef="gate_ok" targetRef="gate_save" name="Да" />
    <bpmn:sequenceFlow id="gate_Flow_8" sourceRef="gate_ok" targetRef="gate_deny" name="Нет" />
    <bpmn:sequenceFlow id="gate_Flow_9" sourceRef="gate_save" targetRef="gate_event" name="" />
    <bpmn:sequenceFlow id="gate_Flow_10" sourceRef="gate_event" targetRef="gate_end" name="" />
  </bpmn:process>
  <bpmn:collaboration id="Collaboration_neg_accepted_gate">
    <bpmn:participant id="gate_Pool_gate" name="Backend: два последовательных scoped запроса с разными задачами" processRef="gate_Process_gate" />
  </bpmn:collaboration>
  <bpmndi:BPMNDiagram id="Diagram_neg_accepted_gate">
    <bpmndi:BPMNPlane id="Plane_neg_accepted_gate" bpmnElement="Collaboration_neg_accepted_gate">
      <bpmndi:BPMNShape id="gate_DI_Pool_gate" bpmnElement="gate_Pool_gate" isHorizontal="true">
        <dc:Bounds x="0.0" y="0.0" width="1960" height="700" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="gate_DI_Lane_read" bpmnElement="gate_Lane_read" isHorizontal="true">
        <dc:Bounds x="30.0" y="0.0" width="1930" height="250.0" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="gate_DI_Lane_activate" bpmnElement="gate_Lane_activate" isHorizontal="true">
        <dc:Bounds x="30.0" y="250.0" width="1930" height="450.0" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="gate_DI_start" bpmnElement="gate_start">
        <dc:Bounds x="132.0" y="92.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="gate_DI_scope" bpmnElement="gate_scope">
        <dc:Bounds x="345.0" y="75.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="gate_DI_ensure" bpmnElement="gate_ensure">
        <dc:Bounds x="625.0" y="75.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="gate_DI_evaluate" bpmnElement="gate_evaluate">
        <dc:Bounds x="905.0" y="75.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="gate_DI_response" bpmnElement="gate_response">
        <dc:Bounds x="1242.0" y="92.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="gate_DI_request" bpmnElement="gate_request">
        <dc:Bounds x="132.0" y="372.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="gate_DI_lock" bpmnElement="gate_lock">
        <dc:Bounds x="345.0" y="355.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="gate_DI_gate" bpmnElement="gate_gate">
        <dc:Bounds x="625.0" y="355.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="gate_DI_ok" bpmnElement="gate_ok">
        <dc:Bounds x="955.0" y="365.0" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="gate_DI_save" bpmnElement="gate_save">
        <dc:Bounds x="1185.0" y="355.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="gate_DI_event" bpmnElement="gate_event">
        <dc:Bounds x="1465.0" y="355.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="gate_DI_end" bpmnElement="gate_end">
        <dc:Bounds x="1782.0" y="372.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="gate_DI_deny" bpmnElement="gate_deny">
        <dc:Bounds x="962.0" y="582.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="gate_DI_Flow_0" bpmnElement="gate_Flow_0">
        <di:waypoint x="168.0" y="110.0" />
        <di:waypoint x="345.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="gate_DI_Flow_1" bpmnElement="gate_Flow_1">
        <di:waypoint x="495.0" y="110.0" />
        <di:waypoint x="625.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="gate_DI_Flow_2" bpmnElement="gate_Flow_2">
        <di:waypoint x="775.0" y="110.0" />
        <di:waypoint x="905.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="gate_DI_Flow_3" bpmnElement="gate_Flow_3">
        <di:waypoint x="1055.0" y="110.0" />
        <di:waypoint x="1242.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="gate_DI_Flow_4" bpmnElement="gate_Flow_4">
        <di:waypoint x="168.0" y="390.0" />
        <di:waypoint x="345.0" y="390.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="gate_DI_Flow_5" bpmnElement="gate_Flow_5">
        <di:waypoint x="495.0" y="390.0" />
        <di:waypoint x="625.0" y="390.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="gate_DI_Flow_6" bpmnElement="gate_Flow_6">
        <di:waypoint x="775.0" y="390.0" />
        <di:waypoint x="955.0" y="390.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="gate_DI_Flow_7" bpmnElement="gate_Flow_7">
        <di:waypoint x="1005.0" y="390.0" />
        <di:waypoint x="1185.0" y="390.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="gate_DI_Flow_8" bpmnElement="gate_Flow_8">
        <di:waypoint x="980.0" y="415.0" />
        <di:waypoint x="980.0" y="582.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="gate_DI_Flow_9" bpmnElement="gate_Flow_9">
        <di:waypoint x="1335.0" y="390.0" />
        <di:waypoint x="1465.0" y="390.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="gate_DI_Flow_10" bpmnElement="gate_Flow_10">
        <di:waypoint x="1615.0" y="390.0" />
        <di:waypoint x="1782.0" y="390.0" />
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>

Связь читается через dbsynce/api/handler/ticket/{ticket_id}/relationship/ по ticket_status_id. Требуются handler identity, актуальный scope и related.relationship.read. В отличие от рассмотренного расхождения PENDING, каталог этой стадии объявляет read/status для Relationship. 404 read может означать отсутствие связи либо выход Ticket из scope; несколько связанных записей дают конфликт 409, а не выбор одной наугад.

GET requirements/?model=relationship требует related.requirements.read. Перед read-only оценкой он вызывает ensure_requirement_actions: подготавливает/переиспользует обязательные черновики документов и попытки проверок с соответствующими ST_REQUEST там, где это предусмотрено настройками. Наличие запроса проверки не означает, что он пройден. Необязательные требования не навязываются, а отсутствие определения/очереди не превращается в успех.

При первоначальном ok runtime запрашивает relationship/ с action=set_status, status=0. Backend проверяет related.relationship.status, scope и единственность связи, блокирует Ticket/Relationship и снова запускает канонический activate_object_if_requirements_met. Прямой status=0 проходит тот же gate; первоначальный ok не является разрешением обойти повторную оценку. При успехе сохраняются active и связь с Ticket, затем Event операции.

Активация, уведомления и CLOSED — раздельные операции. Уже active Relationship не откатывается из-за ошибки последующего закрытия Ticket. Если существующая active Relationship позднее имеет невыполненные requirements, текущий handler сам её не деактивирует: он остаётся в ветви ожидания; текст уведомления не заменяет чтение сохранённого статуса.

Контрольный срок и внешний цикл требований (BPMN)

Схема BPMN

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

Исходник схемы
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_neg_accepted_waiting" targetNamespace="urn:sharix:knowledge:handlers">
  <bpmn:process id="queue_Process_queue" name="Ожидание требований и повторная проверка ACCEPTED" isExecutable="false">
    <bpmn:documentation>{"notes": ["BPMN isExecutable=false. Генератор не исполняет handler.", "ACCEPTED — одобрение запроса, а не уже активное взаимоотношение.", "deferred_until — символ текущего локального срока; не имя параметра.", "После подтверждённой активации есть grace закрытия по NEG_REQUEST_DECLINED_CLEANUP_GRACE_DAYS от Ticket.updated_at; активация не ждёт grace."], "sources": [{"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "handlers/open_neg_request_accepted.py", "repository": "sharix-open-handlers-examples", "sha256": "48d25651729124cee187718f06d76b0cdc94e32dc3ca872270a5fb9f70c08aae"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "generated_handler_blocks/open_neg_request_accepted.json", "repository": "sharix-open-handlers-examples", "sha256": "250918c2a8974e2bb4d81243d6583b406cdb71e56a2552a2006bba552b68a89c"}, {"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/handler_operations.py", "repository": "sharix-open-handlers-backend", "sha256": "28620658501c375f556e24437871620b84a17a88d0b62b2d1a3cc5deb2f14b1e"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "core/ejabberd_muc.py", "repository": "sharix-open-handlers-backend", "sha256": "35c2eba89fab36b5c444439a87beaa516b55133991136d5370418d92a18d7bcd"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "core/requesters.py", "repository": "sharix-open-handlers-backend", "sha256": "965a348cea477722bbaf4c8c6b06023eb238b71664a332f7ea8c90bfe72ea808"}, {"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/views/handler_workflow.py", "repository": "sharix-open-tickets", "sha256": "f97c4b467a9a30749f5c4b86b39a833c430e57aaa1f030f70030d9b5c609d368"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "api/handler_auth.py", "repository": "sharix-open-tickets", "sha256": "ac76dc45aaa9742e5e1da0b98aae914bb2e287048d33e97b4a245a6997bc8425"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "utils.py", "repository": "sharix-open-tickets", "sha256": "a5680205c6522e1d9a74d9d267fe9ee96faf6f06436b00877fc0a93d80234bf5"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "views/ticket_detail.py", "repository": "sharix-open-tickets", "sha256": "05d344b0fba14cf895400694d4a18f486c800fef08dd1acb43ea46909b9e7e59"}, {"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_workflow.py", "repository": "sharix-open-backend", "sha256": "0f699a4e16760cbbdd09d894093c685ba69073fedf0522852cb1fdc9811636e3"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/activation.py", "repository": "sharix-open-backend", "sha256": "f78d4e219a5b83c7952bd366a4e7a711589b1d382af653a0c453c0524e4220f7"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/requirement_actions.py", "repository": "sharix-open-backend", "sha256": "717ef0f3e02ff8e6da103b5fdbae584b01d84d177f6e62ae677a1c5a366b71de"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/requirement_checks.py", "repository": "sharix-open-backend", "sha256": "5a73a6e71307e734f0c0e480fd14a825a7a22242811e2523b7f25157224cf34c"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/document_drafts.py", "repository": "sharix-open-backend", "sha256": "383b117f01fdd9d16de3ceb9afb1ccf0bf3104c4966b23e987b8a90e9a46f071"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/verification_workflow.py", "repository": "sharix-open-backend", "sha256": "9fe62f8344d7fd78e5af0ce025c82ba4f7d21759e71f518df1186a1d6a4a0644"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "models/relationship.py", "repository": "sharix-open-backend", "sha256": "873f27666a7d03b8058958b752d0e69d17d3433daf72f901fa88275cf10f43aa"}]}</bpmn:documentation>
    <bpmn:laneSet id="queue_Lanes_queue">
      <bpmn:lane id="queue_Lane_worker" name="Между проходами worker свободен">
        <bpmn:flowNodeRef>queue_start</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>queue_wait</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>queue_timer</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>queue_revision</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>queue_ready</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>queue_again</bpmn:flowNodeRef>
      </bpmn:lane>
    </bpmn:laneSet>
    <bpmn:startEvent id="queue_start" name="Назначен defer требований, ошибки либо срока закрытия">
      <bpmn:outgoing>queue_Flow_0</bpmn:outgoing>
    </bpmn:startEvent>
    <bpmn:eventBasedGateway id="queue_wait" name="Что наступило раньше?">
      <bpmn:incoming>queue_Flow_0</bpmn:incoming>
      <bpmn:outgoing>queue_Flow_1</bpmn:outgoing>
      <bpmn:outgoing>queue_Flow_2</bpmn:outgoing>
    </bpmn:eventBasedGateway>
    <bpmn:intermediateCatchEvent id="queue_timer" name="Наступил deferred_until">
      <bpmn:documentation>Для срока закрытия: ближайшая короткая проверка, не обязательно весь grace. При новом снимке срок пересчитывается.</bpmn:documentation>
      <bpmn:incoming>queue_Flow_1</bpmn:incoming>
      <bpmn:outgoing>queue_Flow_3</bpmn:outgoing>
      <bpmn:timerEventDefinition>
        <bpmn:timeDate xsi:type="bpmn:tFormalExpression">deferred_until</bpmn:timeDate>
      </bpmn:timerEventDefinition>
    </bpmn:intermediateCatchEvent>
    <bpmn:intermediateCatchEvent id="queue_revision" name="Получена новая ревизия Ticket">
      <bpmn:incoming>queue_Flow_2</bpmn:incoming>
      <bpmn:outgoing>queue_Flow_4</bpmn:outgoing>
      <bpmn:messageEventDefinition />
    </bpmn:intermediateCatchEvent>
    <bpmn:serviceTask id="queue_ready" name="Снять defer, вернуть в ready FIFO">
      <bpmn:incoming>queue_Flow_3</bpmn:incoming>
      <bpmn:incoming>queue_Flow_4</bpmn:incoming>
      <bpmn:outgoing>queue_Flow_5</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:endEvent id="queue_again" name="Новый проход с актуальным снимком">
      <bpmn:incoming>queue_Flow_5</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:sequenceFlow id="queue_Flow_0" sourceRef="queue_start" targetRef="queue_wait" name="" />
    <bpmn:sequenceFlow id="queue_Flow_1" sourceRef="queue_wait" targetRef="queue_timer" name="" />
    <bpmn:sequenceFlow id="queue_Flow_2" sourceRef="queue_wait" targetRef="queue_revision" name="" />
    <bpmn:sequenceFlow id="queue_Flow_3" sourceRef="queue_timer" targetRef="queue_ready" name="" />
    <bpmn:sequenceFlow id="queue_Flow_4" sourceRef="queue_revision" targetRef="queue_ready" name="" />
    <bpmn:sequenceFlow id="queue_Flow_5" sourceRef="queue_ready" targetRef="queue_again" name="" />
  </bpmn:process>
  <bpmn:process id="checks_Process_checks" name="Профильные ST_REQUEST-проверки: пользователь / проверяющий / алгоритм" isExecutable="false">
    <bpmn:documentation>{"notes": ["BPMN isExecutable=false. Генератор не исполняет handler.", "ACCEPTED — одобрение запроса, а не уже активное взаимоотношение.", "deferred_until — символ текущего локального срока; не имя параметра.", "После подтверждённой активации есть grace закрытия по NEG_REQUEST_DECLINED_CLEANUP_GRACE_DAYS от Ticket.updated_at; активация не ждёт grace."], "sources": [{"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "handlers/open_neg_request_accepted.py", "repository": "sharix-open-handlers-examples", "sha256": "48d25651729124cee187718f06d76b0cdc94e32dc3ca872270a5fb9f70c08aae"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "generated_handler_blocks/open_neg_request_accepted.json", "repository": "sharix-open-handlers-examples", "sha256": "250918c2a8974e2bb4d81243d6583b406cdb71e56a2552a2006bba552b68a89c"}, {"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/handler_operations.py", "repository": "sharix-open-handlers-backend", "sha256": "28620658501c375f556e24437871620b84a17a88d0b62b2d1a3cc5deb2f14b1e"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "core/ejabberd_muc.py", "repository": "sharix-open-handlers-backend", "sha256": "35c2eba89fab36b5c444439a87beaa516b55133991136d5370418d92a18d7bcd"}, {"commit": "50baf376e224d915a87d63240f3f339b3dda9afa", "path": "core/requesters.py", "repository": "sharix-open-handlers-backend", "sha256": "965a348cea477722bbaf4c8c6b06023eb238b71664a332f7ea8c90bfe72ea808"}, {"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/views/handler_workflow.py", "repository": "sharix-open-tickets", "sha256": "f97c4b467a9a30749f5c4b86b39a833c430e57aaa1f030f70030d9b5c609d368"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "api/handler_auth.py", "repository": "sharix-open-tickets", "sha256": "ac76dc45aaa9742e5e1da0b98aae914bb2e287048d33e97b4a245a6997bc8425"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "utils.py", "repository": "sharix-open-tickets", "sha256": "a5680205c6522e1d9a74d9d267fe9ee96faf6f06436b00877fc0a93d80234bf5"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "views/ticket_detail.py", "repository": "sharix-open-tickets", "sha256": "05d344b0fba14cf895400694d4a18f486c800fef08dd1acb43ea46909b9e7e59"}, {"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_workflow.py", "repository": "sharix-open-backend", "sha256": "0f699a4e16760cbbdd09d894093c685ba69073fedf0522852cb1fdc9811636e3"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/activation.py", "repository": "sharix-open-backend", "sha256": "f78d4e219a5b83c7952bd366a4e7a711589b1d382af653a0c453c0524e4220f7"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/requirement_actions.py", "repository": "sharix-open-backend", "sha256": "717ef0f3e02ff8e6da103b5fdbae584b01d84d177f6e62ae677a1c5a366b71de"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/requirement_checks.py", "repository": "sharix-open-backend", "sha256": "5a73a6e71307e734f0c0e480fd14a825a7a22242811e2523b7f25157224cf34c"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/document_drafts.py", "repository": "sharix-open-backend", "sha256": "383b117f01fdd9d16de3ceb9afb1ccf0bf3104c4966b23e987b8a90e9a46f071"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/verification_workflow.py", "repository": "sharix-open-backend", "sha256": "9fe62f8344d7fd78e5af0ce025c82ba4f7d21759e71f518df1186a1d6a4a0644"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "models/relationship.py", "repository": "sharix-open-backend", "sha256": "873f27666a7d03b8058958b752d0e69d17d3433daf72f901fa88275cf10f43aa"}]}</bpmn:documentation>
    <bpmn:laneSet id="checks_Lanes_checks">
      <bpmn:lane id="checks_Lane_worker" name="Внешний цикл по документам и RequirementCheck">
        <bpmn:flowNodeRef>checks_start</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>checks_result</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>checks_complete</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>checks_ok</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>checks_wake</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>checks_done</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>checks_not_yet</bpmn:flowNodeRef>
      </bpmn:lane>
    </bpmn:laneSet>
    <bpmn:startEvent id="checks_start" name="Не хватает обязательного подтверждения">
      <bpmn:outgoing>checks_Flow_0</bpmn:outgoing>
    </bpmn:startEvent>
    <bpmn:task id="checks_result" name="Получить результат профильной проверки">
      <bpmn:documentation>Отдельный ручной либо автоматический ST_REQUEST-процесс; он раскрыт на связанных страницах. Загрузка черновика и проверенная версия — разные факты.</bpmn:documentation>
      <bpmn:incoming>checks_Flow_0</bpmn:incoming>
      <bpmn:outgoing>checks_Flow_1</bpmn:outgoing>
    </bpmn:task>
    <bpmn:serviceTask id="checks_complete" name="Доменный complete: пересчитать потребителей">
      <bpmn:incoming>checks_Flow_1</bpmn:incoming>
      <bpmn:outgoing>checks_Flow_2</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:exclusiveGateway id="checks_ok" name="Требования relationship теперь ok?">
      <bpmn:incoming>checks_Flow_2</bpmn:incoming>
      <bpmn:outgoing>checks_Flow_3</bpmn:outgoing>
      <bpmn:outgoing>checks_Flow_4</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:sendTask id="checks_wake" name="Возобновить одобренную активацию: wakeup">
      <bpmn:documentation>Для NEG_REQUEST обновить Ticket.updated_at и после commit отправить ticket.changed, не активировать relationship прямо в ST_REQUEST.</bpmn:documentation>
      <bpmn:incoming>checks_Flow_3</bpmn:incoming>
      <bpmn:outgoing>checks_Flow_5</bpmn:outgoing>
    </bpmn:sendTask>
    <bpmn:endEvent id="checks_done" name="Текущий handler получит новое состояние">
      <bpmn:incoming>checks_Flow_5</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:endEvent id="checks_not_yet" name="Остаются другие невыполненные требования">
      <bpmn:incoming>checks_Flow_4</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:sequenceFlow id="checks_Flow_0" sourceRef="checks_start" targetRef="checks_result" name="" />
    <bpmn:sequenceFlow id="checks_Flow_1" sourceRef="checks_result" targetRef="checks_complete" name="" />
    <bpmn:sequenceFlow id="checks_Flow_2" sourceRef="checks_complete" targetRef="checks_ok" name="" />
    <bpmn:sequenceFlow id="checks_Flow_3" sourceRef="checks_ok" targetRef="checks_wake" name="Да" />
    <bpmn:sequenceFlow id="checks_Flow_4" sourceRef="checks_ok" targetRef="checks_not_yet" name="Нет" />
    <bpmn:sequenceFlow id="checks_Flow_5" sourceRef="checks_wake" targetRef="checks_done" name="" />
  </bpmn:process>
  <bpmn:collaboration id="Collaboration_neg_accepted_waiting">
    <bpmn:participant id="queue_Pool_queue" name="Ожидание требований и повторная проверка ACCEPTED" processRef="queue_Process_queue" />
    <bpmn:participant id="checks_Pool_checks" name="Профильные ST_REQUEST-проверки: пользователь / проверяющий / алгоритм" processRef="checks_Process_checks" />
    <bpmn:messageFlow id="Message_neg_accepted_waiting_0" sourceRef="checks_wake" targetRef="queue_revision" name="ticket.changed после commit → scoped refresh" />
  </bpmn:collaboration>
  <bpmndi:BPMNDiagram id="Diagram_neg_accepted_waiting">
    <bpmndi:BPMNPlane id="Plane_neg_accepted_waiting" bpmnElement="Collaboration_neg_accepted_waiting">
      <bpmndi:BPMNShape id="queue_DI_Pool_queue" bpmnElement="queue_Pool_queue" isHorizontal="true">
        <dc:Bounds x="0.0" y="0.0" width="1360" height="410" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="queue_DI_Lane_worker" bpmnElement="queue_Lane_worker" isHorizontal="true">
        <dc:Bounds x="30.0" y="0.0" width="1330" height="410" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="queue_DI_start" bpmnElement="queue_start">
        <dc:Bounds x="132.0" y="92.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="queue_DI_wait" bpmnElement="queue_wait">
        <dc:Bounds x="375.0" y="85.0" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="queue_DI_timer" bpmnElement="queue_timer">
        <dc:Bounds x="642.0" y="92.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="queue_DI_revision" bpmnElement="queue_revision">
        <dc:Bounds x="642.0" y="292.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="queue_DI_ready" bpmnElement="queue_ready">
        <dc:Bounds x="865.0" y="75.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="queue_DI_again" bpmnElement="queue_again">
        <dc:Bounds x="1182.0" y="92.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="queue_DI_Flow_0" bpmnElement="queue_Flow_0">
        <di:waypoint x="168.0" y="110.0" />
        <di:waypoint x="375.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="queue_DI_Flow_1" bpmnElement="queue_Flow_1">
        <di:waypoint x="425.0" y="110.0" />
        <di:waypoint x="642.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="queue_DI_Flow_2" bpmnElement="queue_Flow_2">
        <di:waypoint x="425.0" y="110.0" />
        <di:waypoint x="533.5" y="110.0" />
        <di:waypoint x="533.5" y="310.0" />
        <di:waypoint x="642.0" y="310.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="queue_DI_Flow_3" bpmnElement="queue_Flow_3">
        <di:waypoint x="678.0" y="110.0" />
        <di:waypoint x="865.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="queue_DI_Flow_4" bpmnElement="queue_Flow_4">
        <di:waypoint x="678.0" y="310.0" />
        <di:waypoint x="771.5" y="310.0" />
        <di:waypoint x="771.5" y="110.0" />
        <di:waypoint x="865.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="queue_DI_Flow_5" bpmnElement="queue_Flow_5">
        <di:waypoint x="1015.0" y="110.0" />
        <di:waypoint x="1182.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="checks_DI_Pool_checks" bpmnElement="checks_Pool_checks" isHorizontal="true">
        <dc:Bounds x="0.0" y="550.0" width="1690" height="380" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="checks_DI_Lane_worker" bpmnElement="checks_Lane_worker" isHorizontal="true">
        <dc:Bounds x="30.0" y="550.0" width="1660" height="380" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="checks_DI_start" bpmnElement="checks_start">
        <dc:Bounds x="132.0" y="632.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="checks_DI_result" bpmnElement="checks_result">
        <dc:Bounds x="345.0" y="615.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="checks_DI_complete" bpmnElement="checks_complete">
        <dc:Bounds x="645.0" y="615.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="checks_DI_ok" bpmnElement="checks_ok">
        <dc:Bounds x="975.0" y="625.0" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="checks_DI_wake" bpmnElement="checks_wake">
        <dc:Bounds x="1205.0" y="615.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="checks_DI_done" bpmnElement="checks_done">
        <dc:Bounds x="1512.0" y="632.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="checks_DI_not_yet" bpmnElement="checks_not_yet">
        <dc:Bounds x="982.0" y="812.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="checks_DI_Flow_0" bpmnElement="checks_Flow_0">
        <di:waypoint x="168.0" y="650.0" />
        <di:waypoint x="345.0" y="650.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="checks_DI_Flow_1" bpmnElement="checks_Flow_1">
        <di:waypoint x="495.0" y="650.0" />
        <di:waypoint x="645.0" y="650.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="checks_DI_Flow_2" bpmnElement="checks_Flow_2">
        <di:waypoint x="795.0" y="650.0" />
        <di:waypoint x="975.0" y="650.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="checks_DI_Flow_3" bpmnElement="checks_Flow_3">
        <di:waypoint x="1025.0" y="650.0" />
        <di:waypoint x="1205.0" y="650.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="checks_DI_Flow_4" bpmnElement="checks_Flow_4">
        <di:waypoint x="1000.0" y="675.0" />
        <di:waypoint x="1000.0" y="812.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="checks_DI_Flow_5" bpmnElement="checks_Flow_5">
        <di:waypoint x="1355.0" y="650.0" />
        <di:waypoint x="1512.0" y="650.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="DI_Message_neg_accepted_waiting_0" bpmnElement="Message_neg_accepted_waiting_0">
        <di:waypoint x="1280" y="685" />
        <di:waypoint x="1400" y="685" />
        <di:waypoint x="1400" y="450" />
        <di:waypoint x="660" y="450" />
        <di:waypoint x="660" y="328" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="875" y="405" width="260" height="42" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>

Для закрытия используется NEG_REQUEST_DECLINED_CLEANUP_GRACE_DAYS даже в ACCEPTED. Это точное имя текущей реализации, несмотря на слово DECLINED. Возраст сравнивается с Ticket.updated_at; минимум настройки — 0 дней. Deadline — updated_at + grace_days, следующий defer — минимум deadline и now + DEFERRED_TICKET_RECHECK_SECONDS. Локальная причина и строка журнала — neg_request_close_grace.

До истечения grace Relationship уже может быть active, а Ticket оставаться ACCEPTED. При каждом повторном проходе Python снова выполняет поиск, проверку requirements и запрос активации прежде, чем дойти до проверки срока. Здесь нет marker «активировать только один раз», аналогичного completed у профильных ST_REQUEST. Нельзя считать повторный Event новой заявкой на взаимоотношение.

Новая authoritative revision может снять defer и изменить контрольную дату; дубликат того же снимка — нет. Если updated_at отсутствует/не разбирается, проверка возраста возвращает false, а helper срока не устанавливает корректный defer; такие данные требуют разбора, а не признания grace истёкшим.

Внешний процесс документов/RequirementCheck раскрыт в ST_REQUEST/IN_PROCESS и DONE. Его complete пересчитывает потребителей. Для NEG_REQUEST удовлетворение требований вызывает resume_approved_activation, который обновляет ревизию Ticket и после commit будит текущий handler через ticket.changed. Активация остаётся явной в Blockly текущего handler, а не скрыто выполняется этим callback. Если требования ещё не удовлетворены, ожидание продолжается.

Ошибки и уведомления

Обработанные отрицательные ответы операции активации дают false и ветвь 900 секунд; 401/403/429, 5xx и ошибки read/requirements API вызывают исключение и общий processing_error с DEFERRED_TICKET_RECHECK_SECONDS. Изменение данных между первоначальной оценкой и повторным gate может объяснять разные результаты. Таймер сам по себе не исправляет постоянную ошибку данных или scope.

404 при запросе CLOSED запрашивает локальную очистку как при устаревшем контексте. Иные ошибки закрытия не отменяют уже сохранённый active. После commit канонический backend отправляет события смены владельца; Ticket в CLOSED больше не имеет отдельного NEG handler. Потерю событий восстанавливает scoped periodic reconciliation.

Автор уведомляется через текущий local-Django helper и его XMPP-реквизиты. Администраторы получают MUC-сообщение по общим правилам NEG/PENDING. В этих уведомлениях нет durable verification ack, повторные проходы могут повторять сообщения; send не доказывает прочтение и не выдаёт доступ к Ticket.

Настройки и диагностика

Состояние Повтор
Relationship отсутствует NEG_REQUEST_INCONSISTENCY_RECHECK_SECONDS; локально related_relationship_missing, журнал related_relationship_inconsistent
Требования не выполнены NEG_REQUEST_INCONSISTENCY_RECHECK_SECONDS, requirements_pending
Активация не подтверждена 900 секунд, related_relationship_inconsistent
Active, но срок закрытия ещё не истёк NEG_REQUEST_DECLINED_CLEANUP_GRACE_DAYS от updated_at; короткий defer, neg_request_close_grace
Общее исключение DEFERRED_TICKET_RECHECK_SECONDS, processing_error
Сверка состава INTERVAL_TIME_BD_REQ

Defer хранится в памяти и освобождает worker. При рестарте runtime заново получает актуальный снимок. Ошибку scoped списка нельзя считать подтверждённой пустой очередью.

При диагностике различайте одобрение Ticket, фактическую Relationship и её направление/тип, результат requirements, ответ активации, актуальный updated_at и отдельное CLOSED. Active при ACCEPTED до контрольного срока может быть штатным состоянием. В текущем lifecycle из ACCEPTED доступны DECLINED или CLOSED при соответствующих правах; одно изменение статуса Ticket не заменяет доменное действие над Relationship.

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

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

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

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

© 2022 ShariX