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

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


sharixopen:knowledge:scenarios:st_request_done

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


ST_REQUEST в DONE: подтверждение закрытия и завершение проверки

Область: ShariX Open. Обработчик: open_st_request_done, тип ST_REQUEST (1), рабочий статус DONE (141). Текущая встроенная реализация изучена по опубликованному Git на 28.10.2026; Python побайтово сверен с каноническим renderer Blockly workspace. На сервере отдельно проверяются выбранная версия и доступность runtime/API.

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

DONE — стадия Ticket, а не универсальное доказательство успешного завершения всего процесса. Для обычного обращения обработчик ждёт подтверждения закрытия. Для стабильных контрактов document-verification-v1 и requirement-check-v1 он вызывает backend complete, отправляет итоговое уведомление и запрашивает CLOSED. В этом handler нет развилки по STREQ_AUTOACCEPT и нет автоматического закрытия обычной заявки по истечении таймера.

Просмотрщик Wiki показывает описание, а не исполняет обработчик. Схемы помечены isExecutable=false; 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: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_st_done_logic" targetNamespace="urn:sharix:knowledge:handlers">
  <bpmn:process id="done_Process_done" name="open_st_request_done: проход Python, закрытие или ожидание" isExecutable="false">
    <bpmn:documentation>{"notes": ["Только опубликованный Git built-in. Никакой код обработчика при генерации не исполняется.", "End event — конец показанной операции; процесс isExecutable=false.", "deferred_until — символ срока в локальной памяти runtime."], "sources": [{"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "handlers/open_st_request_done.py", "repository": "sharix-open-handlers-examples", "sha256": "b6ae4733904d9ba8e691f43235d4836d201ac019ff99982d532816bfdc89bf31"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "generated_handler_blocks/open_st_request_done.json", "repository": "sharix-open-handlers-examples", "sha256": "dda48f4655ad0478a020114a31d7e1cb89547416a69ad2a99fdced1daee5db3c"}, {"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": "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": "services/verification_results.py", "repository": "sharix-open-tickets", "sha256": "682c5f6869373e649d6d62f44e63e8fb3bb34cf6bfc85d0187b26b2c96984e91"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "services/st_request_contracts.py", "repository": "sharix-open-tickets", "sha256": "9c1553437dbff63c608504ee000fa67a9be6e9887b1df0599552aa4d9141276c"}, {"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": "api/views/handler_workflow.py", "repository": "sharix-open-tickets", "sha256": "f97c4b467a9a30749f5c4b86b39a833c430e57aaa1f030f70030d9b5c609d368"}, {"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/verification_workflow.py", "repository": "sharix-open-backend", "sha256": "9fe62f8344d7fd78e5af0ce025c82ba4f7d21759e71f518df1186a1d6a4a0644"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/document_verification.py", "repository": "sharix-open-backend", "sha256": "1692ec40fb8503368a38e154dc4c53644c25a825efc91a87b34bde8065b387bb"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/verification_responsibility.py", "repository": "sharix-open-backend", "sha256": "7919b83c89cb4214545ea2c2db0cffac09af892b190ce3af72348d688abb9cf4"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/verification_algorithms.py", "repository": "sharix-open-backend", "sha256": "9e55e4119051847bb3596c3563b9b151ee92b660e89c39c533b16ed6b4a2099e"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/requirement_checks.py", "repository": "sharix-open-backend", "sha256": "5a73a6e71307e734f0c0e480fd14a825a7a22242811e2523b7f25157224cf34c"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/activation.py", "repository": "sharix-open-backend", "sha256": "f78d4e219a5b83c7952bd366a4e7a711589b1d382af653a0c453c0524e4220f7"}]}</bpmn:documentation>
    <bpmn:laneSet id="done_Lanes_done">
      <bpmn:lane id="done_Lane_worker" name="Worker">
        <bpmn:flowNodeRef>done_start</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>done_status</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>done_special</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>done_complete</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>done_notify</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>done_close</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>done_confirmed</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>done_remove</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>done_end</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>done_stale</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>done_stale_end</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>done_manual</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>done_missing</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>done_complete_error</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>done_completion_retry</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>done_notify_error</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>done_close_error</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>done_generic</bpmn:flowNodeRef>
      </bpmn:lane>
      <bpmn:lane id="done_Lane_queue" name="Планировщик: defer без занятого worker">
        <bpmn:flowNodeRef>done_wait</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>done_timer</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>done_revision</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>done_ready</bpmn:flowNodeRef>
      </bpmn:lane>
    </bpmn:laneSet>
    <bpmn:startEvent id="done_start" name="Ticket готов к проходу">
      <bpmn:outgoing>done_Flow_0</bpmn:outgoing>
    </bpmn:startEvent>
    <bpmn:exclusiveGateway id="done_status" name="Статус DONE?">
      <bpmn:incoming>done_Flow_0</bpmn:incoming>
      <bpmn:incoming>done_Flow_22</bpmn:incoming>
      <bpmn:outgoing>done_Flow_1</bpmn:outgoing>
      <bpmn:outgoing>done_Flow_2</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:exclusiveGateway id="done_special" name="Контракт проверки?">
      <bpmn:incoming>done_Flow_1</bpmn:incoming>
      <bpmn:outgoing>done_Flow_4</bpmn:outgoing>
      <bpmn:outgoing>done_Flow_5</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:serviceTask id="done_complete" name="Scoped verification API: complete">
      <bpmn:documentation>Доменный результат + marker completed + consumer_evaluations. Разбор — на отдельной схеме.</bpmn:documentation>
      <bpmn:incoming>done_Flow_4</bpmn:incoming>
      <bpmn:outgoing>done_Flow_6</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:sendTask id="done_notify" name="Уведомить автора, сохранить ack ключа">
      <bpmn:incoming>done_Flow_6</bpmn:incoming>
      <bpmn:outgoing>done_Flow_7</bpmn:outgoing>
    </bpmn:sendTask>
    <bpmn:serviceTask id="done_close" name="Scoped Ticket API: CLOSED">
      <bpmn:documentation>В текущем runtime после успешного ответа complete. Не требует consumer_evaluations=all ok.</bpmn:documentation>
      <bpmn:incoming>done_Flow_7</bpmn:incoming>
      <bpmn:outgoing>done_Flow_8</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:exclusiveGateway id="done_confirmed" name="Переход подтверждён?">
      <bpmn:incoming>done_Flow_8</bpmn:incoming>
      <bpmn:outgoing>done_Flow_9</bpmn:outgoing>
      <bpmn:outgoing>done_Flow_11</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:serviceTask id="done_remove" name="Удалить локальный Ticket и комнату">
      <bpmn:incoming>done_Flow_9</bpmn:incoming>
      <bpmn:outgoing>done_Flow_10</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:endEvent id="done_end" name="Этот проход завершён">
      <bpmn:incoming>done_Flow_10</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:serviceTask id="done_stale" name="Удалить локальный Ticket и комнату">
      <bpmn:incoming>done_Flow_2</bpmn:incoming>
      <bpmn:outgoing>done_Flow_3</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:endEvent id="done_stale_end" name="Прежний владелец освобождён">
      <bpmn:incoming>done_Flow_3</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:serviceTask id="done_manual" name="support_closure_confirmation; defer">
      <bpmn:documentation>ST_REQUEST_DONE_RECHECK_SECONDS, журнал st_request_done; autoaccept здесь не проверяется.</bpmn:documentation>
      <bpmn:incoming>done_Flow_5</bpmn:incoming>
      <bpmn:outgoing>done_Flow_12</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:endEvent id="done_missing" name="404: очистка уже запрошена">
      <bpmn:incoming>done_Flow_11</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:boundaryEvent id="done_complete_error" name="HTTP/JSON ошибка" attachedToRef="done_complete" cancelActivity="true">
      <bpmn:outgoing>done_Flow_13</bpmn:outgoing>
      <bpmn:errorEventDefinition />
    </bpmn:boundaryEvent>
    <bpmn:serviceTask id="done_completion_retry" name="defer 300 с: verification_completion_error">
      <bpmn:incoming>done_Flow_13</bpmn:incoming>
      <bpmn:outgoing>done_Flow_14</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:boundaryEvent id="done_notify_error" name="Ошибка отправки" attachedToRef="done_notify" cancelActivity="true">
      <bpmn:outgoing>done_Flow_15</bpmn:outgoing>
      <bpmn:errorEventDefinition />
    </bpmn:boundaryEvent>
    <bpmn:boundaryEvent id="done_close_error" name="Ошибка перехода" attachedToRef="done_close" cancelActivity="true">
      <bpmn:outgoing>done_Flow_16</bpmn:outgoing>
      <bpmn:errorEventDefinition />
    </bpmn:boundaryEvent>
    <bpmn:serviceTask id="done_generic" name="Общий processing_error + defer">
      <bpmn:documentation>DEFERRED_TICKET_RECHECK_SECONDS. Завершённый backend complete не откатывается.</bpmn:documentation>
      <bpmn:incoming>done_Flow_15</bpmn:incoming>
      <bpmn:incoming>done_Flow_16</bpmn:incoming>
      <bpmn:outgoing>done_Flow_17</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:eventBasedGateway id="done_wait" name="Что наступило раньше?">
      <bpmn:incoming>done_Flow_12</bpmn:incoming>
      <bpmn:incoming>done_Flow_14</bpmn:incoming>
      <bpmn:incoming>done_Flow_17</bpmn:incoming>
      <bpmn:outgoing>done_Flow_18</bpmn:outgoing>
      <bpmn:outgoing>done_Flow_19</bpmn:outgoing>
    </bpmn:eventBasedGateway>
    <bpmn:intermediateCatchEvent id="done_timer" name="Локальный срок defer">
      <bpmn:incoming>done_Flow_18</bpmn:incoming>
      <bpmn:outgoing>done_Flow_20</bpmn:outgoing>
      <bpmn:timerEventDefinition>
        <bpmn:timeDate xsi:type="bpmn:tFormalExpression">deferred_until</bpmn:timeDate>
      </bpmn:timerEventDefinition>
    </bpmn:intermediateCatchEvent>
    <bpmn:intermediateCatchEvent id="done_revision" name="Новая ревизия Ticket">
      <bpmn:incoming>done_Flow_19</bpmn:incoming>
      <bpmn:outgoing>done_Flow_21</bpmn:outgoing>
      <bpmn:messageEventDefinition />
    </bpmn:intermediateCatchEvent>
    <bpmn:serviceTask id="done_ready" name="Снять defer, вернуть Ticket в ready">
      <bpmn:documentation>При смене владельца убрать локальный снимок; при той же стадии повторить проход.</bpmn:documentation>
      <bpmn:incoming>done_Flow_20</bpmn:incoming>
      <bpmn:incoming>done_Flow_21</bpmn:incoming>
      <bpmn:outgoing>done_Flow_22</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:sequenceFlow id="done_Flow_0" sourceRef="done_start" targetRef="done_status" name="" />
    <bpmn:sequenceFlow id="done_Flow_1" sourceRef="done_status" targetRef="done_special" name="Да" />
    <bpmn:sequenceFlow id="done_Flow_2" sourceRef="done_status" targetRef="done_stale" name="Нет" />
    <bpmn:sequenceFlow id="done_Flow_3" sourceRef="done_stale" targetRef="done_stale_end" name="" />
    <bpmn:sequenceFlow id="done_Flow_4" sourceRef="done_special" targetRef="done_complete" name="Да" />
    <bpmn:sequenceFlow id="done_Flow_5" sourceRef="done_special" targetRef="done_manual" name="Нет" />
    <bpmn:sequenceFlow id="done_Flow_6" sourceRef="done_complete" targetRef="done_notify" name="" />
    <bpmn:sequenceFlow id="done_Flow_7" sourceRef="done_notify" targetRef="done_close" name="" />
    <bpmn:sequenceFlow id="done_Flow_8" sourceRef="done_close" targetRef="done_confirmed" name="" />
    <bpmn:sequenceFlow id="done_Flow_9" sourceRef="done_confirmed" targetRef="done_remove" name="Да" />
    <bpmn:sequenceFlow id="done_Flow_10" sourceRef="done_remove" targetRef="done_end" name="" />
    <bpmn:sequenceFlow id="done_Flow_11" sourceRef="done_confirmed" targetRef="done_missing" name="Нет (404)" />
    <bpmn:sequenceFlow id="done_Flow_12" sourceRef="done_manual" targetRef="done_wait" name="" />
    <bpmn:sequenceFlow id="done_Flow_13" sourceRef="done_complete_error" targetRef="done_completion_retry" name="" />
    <bpmn:sequenceFlow id="done_Flow_14" sourceRef="done_completion_retry" targetRef="done_wait" name="" />
    <bpmn:sequenceFlow id="done_Flow_15" sourceRef="done_notify_error" targetRef="done_generic" name="" />
    <bpmn:sequenceFlow id="done_Flow_16" sourceRef="done_close_error" targetRef="done_generic" name="" />
    <bpmn:sequenceFlow id="done_Flow_17" sourceRef="done_generic" targetRef="done_wait" name="" />
    <bpmn:sequenceFlow id="done_Flow_18" sourceRef="done_wait" targetRef="done_timer" name="" />
    <bpmn:sequenceFlow id="done_Flow_19" sourceRef="done_wait" targetRef="done_revision" name="" />
    <bpmn:sequenceFlow id="done_Flow_20" sourceRef="done_timer" targetRef="done_ready" name="" />
    <bpmn:sequenceFlow id="done_Flow_21" sourceRef="done_revision" targetRef="done_ready" name="" />
    <bpmn:sequenceFlow id="done_Flow_22" sourceRef="done_ready" targetRef="done_status" name="Новый проход" />
  </bpmn:process>
  <bpmn:collaboration id="Collaboration_st_done_logic">
    <bpmn:participant id="done_Pool_done" name="open_st_request_done: проход Python, закрытие или ожидание" processRef="done_Process_done" />
  </bpmn:collaboration>
  <bpmndi:BPMNDiagram id="Diagram_st_done_logic">
    <bpmndi:BPMNPlane id="Plane_st_done_logic" bpmnElement="Collaboration_st_done_logic">
      <bpmndi:BPMNShape id="done_DI_Pool_done" bpmnElement="done_Pool_done" isHorizontal="true">
        <dc:Bounds x="0.0" y="0.0" width="2210" height="970" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="done_DI_Lane_worker" bpmnElement="done_Lane_worker" isHorizontal="true">
        <dc:Bounds x="30.0" y="0.0" width="2180" height="580.0" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="done_DI_Lane_queue" bpmnElement="done_Lane_queue" isHorizontal="true">
        <dc:Bounds x="30.0" y="580.0" width="2180" height="390.0" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="done_DI_start" bpmnElement="done_start">
        <dc:Bounds x="132.0" y="92.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="done_DI_status" bpmnElement="done_status">
        <dc:Bounds x="325.0" y="85.0" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="done_DI_special" bpmnElement="done_special">
        <dc:Bounds x="555.0" y="85.0" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="done_DI_complete" bpmnElement="done_complete">
        <dc:Bounds x="755.0" y="75.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="done_DI_notify" bpmnElement="done_notify">
        <dc:Bounds x="1005.0" y="75.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="done_DI_close" bpmnElement="done_close">
        <dc:Bounds x="1255.0" y="75.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="done_DI_confirmed" bpmnElement="done_confirmed">
        <dc:Bounds x="1555.0" y="85.0" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="done_DI_remove" bpmnElement="done_remove">
        <dc:Bounds x="1745.0" y="75.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="done_DI_end" bpmnElement="done_end">
        <dc:Bounds x="2032.0" y="92.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="done_DI_stale" bpmnElement="done_stale">
        <dc:Bounds x="275.0" y="265.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="done_DI_stale_end" bpmnElement="done_stale_end">
        <dc:Bounds x="562.0" y="282.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="done_DI_manual" bpmnElement="done_manual">
        <dc:Bounds x="755.0" y="265.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="done_DI_missing" bpmnElement="done_missing">
        <dc:Bounds x="1562.0" y="282.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="done_DI_complete_error" bpmnElement="done_complete_error">
        <dc:Bounds x="862.0" y="127.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="done_DI_completion_retry" bpmnElement="done_completion_retry">
        <dc:Bounds x="1005.0" y="445.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="done_DI_notify_error" bpmnElement="done_notify_error">
        <dc:Bounds x="1112.0" y="127.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="done_DI_close_error" bpmnElement="done_close_error">
        <dc:Bounds x="1362.0" y="127.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="done_DI_generic" bpmnElement="done_generic">
        <dc:Bounds x="1505.0" y="445.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="done_DI_wait" bpmnElement="done_wait">
        <dc:Bounds x="1055.0" y="715.0" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="done_DI_timer" bpmnElement="done_timer">
        <dc:Bounds x="1312.0" y="662.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="done_DI_revision" bpmnElement="done_revision">
        <dc:Bounds x="1312.0" y="852.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="done_DI_ready" bpmnElement="done_ready">
        <dc:Bounds x="1505.0" y="705.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="done_DI_Flow_0" bpmnElement="done_Flow_0">
        <di:waypoint x="168.0" y="110.0" />
        <di:waypoint x="325.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="done_DI_Flow_1" bpmnElement="done_Flow_1">
        <di:waypoint x="375.0" y="110.0" />
        <di:waypoint x="555.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="done_DI_Flow_2" bpmnElement="done_Flow_2">
        <di:waypoint x="350.0" y="135.0" />
        <di:waypoint x="350.0" y="265.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="done_DI_Flow_3" bpmnElement="done_Flow_3">
        <di:waypoint x="425.0" y="300.0" />
        <di:waypoint x="562.0" y="300.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="done_DI_Flow_4" bpmnElement="done_Flow_4">
        <di:waypoint x="605.0" y="110.0" />
        <di:waypoint x="755.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="done_DI_Flow_5" bpmnElement="done_Flow_5">
        <di:waypoint x="605.0" y="110.0" />
        <di:waypoint x="700.0" y="110.0" />
        <di:waypoint x="700.0" y="235.0" />
        <di:waypoint x="830.0" y="235.0" />
        <di:waypoint x="830.0" y="265.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="done_DI_Flow_6" bpmnElement="done_Flow_6">
        <di:waypoint x="905.0" y="110.0" />
        <di:waypoint x="1005.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="done_DI_Flow_7" bpmnElement="done_Flow_7">
        <di:waypoint x="1155.0" y="110.0" />
        <di:waypoint x="1255.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="done_DI_Flow_8" bpmnElement="done_Flow_8">
        <di:waypoint x="1405.0" y="110.0" />
        <di:waypoint x="1555.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="done_DI_Flow_9" bpmnElement="done_Flow_9">
        <di:waypoint x="1605.0" y="110.0" />
        <di:waypoint x="1745.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="done_DI_Flow_10" bpmnElement="done_Flow_10">
        <di:waypoint x="1895.0" y="110.0" />
        <di:waypoint x="2032.0" y="110.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="done_DI_Flow_11" bpmnElement="done_Flow_11">
        <di:waypoint x="1580.0" y="135.0" />
        <di:waypoint x="1580.0" y="282.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="done_DI_Flow_12" bpmnElement="done_Flow_12">
        <di:waypoint x="905.0" y="300.0" />
        <di:waypoint x="950.0" y="300.0" />
        <di:waypoint x="950.0" y="625.0" />
        <di:waypoint x="1080.0" y="625.0" />
        <di:waypoint x="1080.0" y="715.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="done_DI_Flow_13" bpmnElement="done_Flow_13">
        <di:waypoint x="898.0" y="145.0" />
        <di:waypoint x="940.0" y="145.0" />
        <di:waypoint x="940.0" y="400.0" />
        <di:waypoint x="1080.0" y="400.0" />
        <di:waypoint x="1080.0" y="445.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="done_DI_Flow_14" bpmnElement="done_Flow_14">
        <di:waypoint x="1080.0" y="515.0" />
        <di:waypoint x="1080.0" y="715.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="done_DI_Flow_15" bpmnElement="done_Flow_15">
        <di:waypoint x="1148.0" y="145.0" />
        <di:waypoint x="1190.0" y="145.0" />
        <di:waypoint x="1190.0" y="400.0" />
        <di:waypoint x="1580.0" y="400.0" />
        <di:waypoint x="1580.0" y="445.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="done_DI_Flow_16" bpmnElement="done_Flow_16">
        <di:waypoint x="1398.0" y="145.0" />
        <di:waypoint x="1440.0" y="145.0" />
        <di:waypoint x="1440.0" y="370.0" />
        <di:waypoint x="1580.0" y="370.0" />
        <di:waypoint x="1580.0" y="445.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="done_DI_Flow_17" bpmnElement="done_Flow_17">
        <di:waypoint x="1655.0" y="480.0" />
        <di:waypoint x="1720.0" y="480.0" />
        <di:waypoint x="1720.0" y="620.0" />
        <di:waypoint x="1080.0" y="620.0" />
        <di:waypoint x="1080.0" y="715.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="done_DI_Flow_18" bpmnElement="done_Flow_18">
        <di:waypoint x="1105.0" y="740.0" />
        <di:waypoint x="1208.5" y="740.0" />
        <di:waypoint x="1208.5" y="680.0" />
        <di:waypoint x="1312.0" y="680.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="done_DI_Flow_19" bpmnElement="done_Flow_19">
        <di:waypoint x="1105.0" y="740.0" />
        <di:waypoint x="1208.5" y="740.0" />
        <di:waypoint x="1208.5" y="870.0" />
        <di:waypoint x="1312.0" y="870.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="done_DI_Flow_20" bpmnElement="done_Flow_20">
        <di:waypoint x="1348.0" y="680.0" />
        <di:waypoint x="1426.5" y="680.0" />
        <di:waypoint x="1426.5" y="740.0" />
        <di:waypoint x="1505.0" y="740.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="done_DI_Flow_21" bpmnElement="done_Flow_21">
        <di:waypoint x="1348.0" y="870.0" />
        <di:waypoint x="1426.5" y="870.0" />
        <di:waypoint x="1426.5" y="740.0" />
        <di:waypoint x="1505.0" y="740.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="done_DI_Flow_22" bpmnElement="done_Flow_22">
        <di:waypoint x="1655.0" y="740.0" />
        <di:waypoint x="2140.0" y="740.0" />
        <di:waypoint x="2140.0" y="25.0" />
        <di:waypoint x="350.0" y="25.0" />
        <di:waypoint x="350.0" y="85.0" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="1850.0" y="5.0" width="180" height="26" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>

Сначала runtime проверяет свой рабочий статус. Чужой статус означает очистку локального Ticket и комнаты. В своём статусе профильный контракт идёт в complete_verification_workflow; остальные обращения получают локальную причину support_closure_confirmation и defer по ST_REQUEST_DONE_RECHECK_SECONDS. Строка st_request_done используется в журнале defer и не заменяет сохранённую локальную причину.

Профильная ветвь вызывает scoped dbsynce/api/handler/ticket/{ticket_id}/verification/ с действием complete. Backend проверяет handler identity, capability verification.workflow и scope конкретного Ticket. При успешном HTTP/JSON-ответе runtime отправляет возвращённые уведомления, пишет message ответа в журнал и запрашивает CLOSED через scoped Ticket API. В изученном runtime нет дополнительного условия «все consumer_evaluations имеют ok» перед CLOSED.

404 при переходе в CLOSED запрашивает локальную очистку как для устаревшего scope. Остальные ошибки перехода или отправки идут в общий processing_error и defer по DEFERRED_TICKET_RECHECK_SECONDS. Успешно сохранённый backend-результат от этого не откатывается.

Применение результата в backend (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_st_done_complete" targetNamespace="urn:sharix:knowledge:handlers">
  <bpmn:process id="complete_Process_complete" name="dbsynce: complete_specialized_ticket — результат и потребители" isExecutable="false">
    <bpmn:documentation>{"notes": ["Только опубликованный Git built-in. Никакой код обработчика при генерации не исполняется.", "End event — конец показанной операции; процесс isExecutable=false.", "deferred_until — символ срока в локальной памяти runtime.", "Здесь показана ветвь первого complete для DONE. WONTFIX имеет другой результат документа.", "consumer_evaluations не являются условием CLOSED; успешная проверка не означает успех всех требований."], "sources": [{"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "handlers/open_st_request_done.py", "repository": "sharix-open-handlers-examples", "sha256": "b6ae4733904d9ba8e691f43235d4836d201ac019ff99982d532816bfdc89bf31"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "generated_handler_blocks/open_st_request_done.json", "repository": "sharix-open-handlers-examples", "sha256": "dda48f4655ad0478a020114a31d7e1cb89547416a69ad2a99fdced1daee5db3c"}, {"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": "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": "services/verification_results.py", "repository": "sharix-open-tickets", "sha256": "682c5f6869373e649d6d62f44e63e8fb3bb34cf6bfc85d0187b26b2c96984e91"}, {"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", "path": "services/st_request_contracts.py", "repository": "sharix-open-tickets", "sha256": "9c1553437dbff63c608504ee000fa67a9be6e9887b1df0599552aa4d9141276c"}, {"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": "api/views/handler_workflow.py", "repository": "sharix-open-tickets", "sha256": "f97c4b467a9a30749f5c4b86b39a833c430e57aaa1f030f70030d9b5c609d368"}, {"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/verification_workflow.py", "repository": "sharix-open-backend", "sha256": "9fe62f8344d7fd78e5af0ce025c82ba4f7d21759e71f518df1186a1d6a4a0644"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/document_verification.py", "repository": "sharix-open-backend", "sha256": "1692ec40fb8503368a38e154dc4c53644c25a825efc91a87b34bde8065b387bb"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/verification_responsibility.py", "repository": "sharix-open-backend", "sha256": "7919b83c89cb4214545ea2c2db0cffac09af892b190ce3af72348d688abb9cf4"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/verification_algorithms.py", "repository": "sharix-open-backend", "sha256": "9e55e4119051847bb3596c3563b9b151ee92b660e89c39c533b16ed6b4a2099e"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/requirement_checks.py", "repository": "sharix-open-backend", "sha256": "5a73a6e71307e734f0c0e480fd14a825a7a22242811e2523b7f25157224cf34c"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "lib/activation.py", "repository": "sharix-open-backend", "sha256": "f78d4e219a5b83c7952bd366a4e7a711589b1d382af653a0c453c0524e4220f7"}]}</bpmn:documentation>
    <bpmn:laneSet id="complete_Lanes_complete">
      <bpmn:lane id="complete_Lane_worker" name="Backend: транзакционная операция">
        <bpmn:flowNodeRef>complete_start</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>complete_acl</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>complete_seen</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>complete_cached</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>complete_cached_end</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>complete_check_status</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>complete_doc</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>complete_document</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>complete_check</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>complete_pending</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>complete_apply</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>complete_existing</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>complete_consumers</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>complete_mark</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>complete_response</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>complete_doc_error</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>complete_check_error</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>complete_apply_error</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>complete_mismatch</bpmn:flowNodeRef>
        <bpmn:flowNodeRef>complete_error</bpmn:flowNodeRef>
      </bpmn:lane>
    </bpmn:laneSet>
    <bpmn:startEvent id="complete_start" name="Scoped complete для DONE">
      <bpmn:outgoing>complete_Flow_0</bpmn:outgoing>
      <bpmn:messageEventDefinition />
    </bpmn:startEvent>
    <bpmn:serviceTask id="complete_acl" name="Проверить identity, capability, scope">
      <bpmn:incoming>complete_Flow_0</bpmn:incoming>
      <bpmn:outgoing>complete_Flow_1</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:exclusiveGateway id="complete_seen" name="Есть marker completed?">
      <bpmn:incoming>complete_Flow_1</bpmn:incoming>
      <bpmn:outgoing>complete_Flow_2</bpmn:outgoing>
      <bpmn:outgoing>complete_Flow_4</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:serviceTask id="complete_cached" name="Вернуть прежние outcome/details и неack уведомление">
      <bpmn:documentation>Без повторного применения результата и пересчёта потребителей.</bpmn:documentation>
      <bpmn:incoming>complete_Flow_2</bpmn:incoming>
      <bpmn:outgoing>complete_Flow_3</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:endEvent id="complete_cached_end" name="Ответ повторного вызова">
      <bpmn:incoming>complete_Flow_3</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:serviceTask id="complete_check_status" name="Проверить DONE/WONTFIX; выбрать actor">
      <bpmn:documentation>Явный actor → reviewer_user_id → assigned_to. В handler API actor не передаётся.</bpmn:documentation>
      <bpmn:incoming>complete_Flow_4</bpmn:incoming>
      <bpmn:outgoing>complete_Flow_5</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:exclusiveGateway id="complete_doc" name="Проверка документа?">
      <bpmn:incoming>complete_Flow_5</bpmn:incoming>
      <bpmn:outgoing>complete_Flow_6</bpmn:outgoing>
      <bpmn:outgoing>complete_Flow_7</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:serviceTask id="complete_document" name="Проверить редакцию/identity; создать DocumentVersion">
      <bpmn:documentation>Документ и Ticket должны совпадать; stale draft отклоняется. Копируются файлы снимка, обновляется current verified version.</bpmn:documentation>
      <bpmn:incoming>complete_Flow_6</bpmn:incoming>
      <bpmn:outgoing>complete_Flow_8</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:serviceTask id="complete_check" name="Загрузить RequirementCheck">
      <bpmn:incoming>complete_Flow_7</bpmn:incoming>
      <bpmn:outgoing>complete_Flow_9</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:exclusiveGateway id="complete_pending" name="Попытка PENDING?">
      <bpmn:incoming>complete_Flow_9</bpmn:incoming>
      <bpmn:outgoing>complete_Flow_10</bpmn:outgoing>
      <bpmn:outgoing>complete_Flow_11</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:serviceTask id="complete_apply" name="Применить результат и политику баллов">
      <bpmn:documentation>passed=True для DONE, но score-based порог может сохранить FAILED. Требуются допустимые actor/ответственный и поля результата.</bpmn:documentation>
      <bpmn:incoming>complete_Flow_10</bpmn:incoming>
      <bpmn:outgoing>complete_Flow_12</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:serviceTask id="complete_existing" name="Уже завершена: для DONE допускается только PASSED">
      <bpmn:incoming>complete_Flow_11</bpmn:incoming>
      <bpmn:outgoing>complete_Flow_13</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:serviceTask id="complete_consumers" name="Пересчитать найденных потребителей требований">
      <bpmn:documentation>evaluate_requirements; при ok вызвать resume_approved_activation. Нет новой выдачи прав или отмены прежних отказов.</bpmn:documentation>
      <bpmn:incoming>complete_Flow_8</bpmn:incoming>
      <bpmn:incoming>complete_Flow_12</bpmn:incoming>
      <bpmn:incoming>complete_Flow_13</bpmn:incoming>
      <bpmn:outgoing>complete_Flow_14</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:serviceTask id="complete_mark" name="Сохранить marker completed, outcome, детали">
      <bpmn:incoming>complete_Flow_14</bpmn:incoming>
      <bpmn:outgoing>complete_Flow_15</bpmn:outgoing>
    </bpmn:serviceTask>
    <bpmn:endEvent id="complete_response" name="Ответ completed + уведомление автору">
      <bpmn:incoming>complete_Flow_15</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:boundaryEvent id="complete_doc_error" name="Валидация" attachedToRef="complete_document" cancelActivity="true">
      <bpmn:outgoing>complete_Flow_16</bpmn:outgoing>
      <bpmn:errorEventDefinition />
    </bpmn:boundaryEvent>
    <bpmn:boundaryEvent id="complete_check_error" name="Нет попытки" attachedToRef="complete_check" cancelActivity="true">
      <bpmn:outgoing>complete_Flow_17</bpmn:outgoing>
      <bpmn:errorEventDefinition />
    </bpmn:boundaryEvent>
    <bpmn:boundaryEvent id="complete_apply_error" name="Валидация" attachedToRef="complete_apply" cancelActivity="true">
      <bpmn:outgoing>complete_Flow_18</bpmn:outgoing>
      <bpmn:errorEventDefinition />
    </bpmn:boundaryEvent>
    <bpmn:boundaryEvent id="complete_mismatch" name="Несовместимый статус" attachedToRef="complete_existing" cancelActivity="true">
      <bpmn:outgoing>complete_Flow_19</bpmn:outgoing>
      <bpmn:errorEventDefinition />
    </bpmn:boundaryEvent>
    <bpmn:endEvent id="complete_error" name="Ошибка: runtime отложит повтор">
      <bpmn:incoming>complete_Flow_16</bpmn:incoming>
      <bpmn:incoming>complete_Flow_17</bpmn:incoming>
      <bpmn:incoming>complete_Flow_18</bpmn:incoming>
      <bpmn:incoming>complete_Flow_19</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:sequenceFlow id="complete_Flow_0" sourceRef="complete_start" targetRef="complete_acl" name="" />
    <bpmn:sequenceFlow id="complete_Flow_1" sourceRef="complete_acl" targetRef="complete_seen" name="" />
    <bpmn:sequenceFlow id="complete_Flow_2" sourceRef="complete_seen" targetRef="complete_cached" name="Да" />
    <bpmn:sequenceFlow id="complete_Flow_3" sourceRef="complete_cached" targetRef="complete_cached_end" name="" />
    <bpmn:sequenceFlow id="complete_Flow_4" sourceRef="complete_seen" targetRef="complete_check_status" name="Нет" />
    <bpmn:sequenceFlow id="complete_Flow_5" sourceRef="complete_check_status" targetRef="complete_doc" name="" />
    <bpmn:sequenceFlow id="complete_Flow_6" sourceRef="complete_doc" targetRef="complete_document" name="Да" />
    <bpmn:sequenceFlow id="complete_Flow_7" sourceRef="complete_doc" targetRef="complete_check" name="Нет" />
    <bpmn:sequenceFlow id="complete_Flow_8" sourceRef="complete_document" targetRef="complete_consumers" name="" />
    <bpmn:sequenceFlow id="complete_Flow_9" sourceRef="complete_check" targetRef="complete_pending" name="" />
    <bpmn:sequenceFlow id="complete_Flow_10" sourceRef="complete_pending" targetRef="complete_apply" name="Да" />
    <bpmn:sequenceFlow id="complete_Flow_11" sourceRef="complete_pending" targetRef="complete_existing" name="Нет" />
    <bpmn:sequenceFlow id="complete_Flow_12" sourceRef="complete_apply" targetRef="complete_consumers" name="" />
    <bpmn:sequenceFlow id="complete_Flow_13" sourceRef="complete_existing" targetRef="complete_consumers" name="" />
    <bpmn:sequenceFlow id="complete_Flow_14" sourceRef="complete_consumers" targetRef="complete_mark" name="" />
    <bpmn:sequenceFlow id="complete_Flow_15" sourceRef="complete_mark" targetRef="complete_response" name="" />
    <bpmn:sequenceFlow id="complete_Flow_16" sourceRef="complete_doc_error" targetRef="complete_error" name="" />
    <bpmn:sequenceFlow id="complete_Flow_17" sourceRef="complete_check_error" targetRef="complete_error" name="" />
    <bpmn:sequenceFlow id="complete_Flow_18" sourceRef="complete_apply_error" targetRef="complete_error" name="" />
    <bpmn:sequenceFlow id="complete_Flow_19" sourceRef="complete_mismatch" targetRef="complete_error" name="" />
  </bpmn:process>
  <bpmn:collaboration id="Collaboration_st_done_complete">
    <bpmn:participant id="complete_Pool_complete" name="dbsynce: complete_specialized_ticket — результат и потребители" processRef="complete_Process_complete" />
  </bpmn:collaboration>
  <bpmndi:BPMNDiagram id="Diagram_st_done_complete">
    <bpmndi:BPMNPlane id="Plane_st_done_complete" bpmnElement="Collaboration_st_done_complete">
      <bpmndi:BPMNShape id="complete_DI_Pool_complete" bpmnElement="complete_Pool_complete" isHorizontal="true">
        <dc:Bounds x="0.0" y="0.0" width="2400" height="950" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="complete_DI_Lane_worker" bpmnElement="complete_Lane_worker" isHorizontal="true">
        <dc:Bounds x="30.0" y="0.0" width="2370" height="950" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="complete_DI_start" bpmnElement="complete_start">
        <dc:Bounds x="132.0" y="82.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="complete_DI_acl" bpmnElement="complete_acl">
        <dc:Bounds x="315.0" y="65.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="complete_DI_seen" bpmnElement="complete_seen">
        <dc:Bounds x="625.0" y="75.0" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="complete_DI_cached" bpmnElement="complete_cached">
        <dc:Bounds x="855.0" y="65.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="complete_DI_cached_end" bpmnElement="complete_cached_end">
        <dc:Bounds x="1182.0" y="82.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="complete_DI_check_status" bpmnElement="complete_check_status">
        <dc:Bounds x="575.0" y="255.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="complete_DI_doc" bpmnElement="complete_doc">
        <dc:Bounds x="905.0" y="265.0" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="complete_DI_document" bpmnElement="complete_document">
        <dc:Bounds x="1125.0" y="255.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="complete_DI_check" bpmnElement="complete_check">
        <dc:Bounds x="855.0" y="455.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="complete_DI_pending" bpmnElement="complete_pending">
        <dc:Bounds x="1175.0" y="465.0" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="complete_DI_apply" bpmnElement="complete_apply">
        <dc:Bounds x="1385.0" y="455.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="complete_DI_existing" bpmnElement="complete_existing">
        <dc:Bounds x="1125.0" y="655.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="complete_DI_consumers" bpmnElement="complete_consumers">
        <dc:Bounds x="1665.0" y="255.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="complete_DI_mark" bpmnElement="complete_mark">
        <dc:Bounds x="1925.0" y="255.0" width="150" height="70" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="complete_DI_response" bpmnElement="complete_response">
        <dc:Bounds x="2222.0" y="272.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="complete_DI_doc_error" bpmnElement="complete_doc_error">
        <dc:Bounds x="1232.0" y="307.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="complete_DI_check_error" bpmnElement="complete_check_error">
        <dc:Bounds x="962.0" y="507.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="complete_DI_apply_error" bpmnElement="complete_apply_error">
        <dc:Bounds x="1492.0" y="507.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="complete_DI_mismatch" bpmnElement="complete_mismatch">
        <dc:Bounds x="1232.0" y="707.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="complete_DI_error" bpmnElement="complete_error">
        <dc:Bounds x="1722.0" y="832.0" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="complete_DI_Flow_0" bpmnElement="complete_Flow_0">
        <di:waypoint x="168.0" y="100.0" />
        <di:waypoint x="315.0" y="100.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="complete_DI_Flow_1" bpmnElement="complete_Flow_1">
        <di:waypoint x="465.0" y="100.0" />
        <di:waypoint x="625.0" y="100.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="complete_DI_Flow_2" bpmnElement="complete_Flow_2">
        <di:waypoint x="675.0" y="100.0" />
        <di:waypoint x="855.0" y="100.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="complete_DI_Flow_3" bpmnElement="complete_Flow_3">
        <di:waypoint x="1005.0" y="100.0" />
        <di:waypoint x="1182.0" y="100.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="complete_DI_Flow_4" bpmnElement="complete_Flow_4">
        <di:waypoint x="650.0" y="125.0" />
        <di:waypoint x="650.0" y="255.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="complete_DI_Flow_5" bpmnElement="complete_Flow_5">
        <di:waypoint x="725.0" y="290.0" />
        <di:waypoint x="905.0" y="290.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="complete_DI_Flow_6" bpmnElement="complete_Flow_6">
        <di:waypoint x="955.0" y="290.0" />
        <di:waypoint x="1125.0" y="290.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="complete_DI_Flow_7" bpmnElement="complete_Flow_7">
        <di:waypoint x="930.0" y="315.0" />
        <di:waypoint x="930.0" y="455.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="complete_DI_Flow_8" bpmnElement="complete_Flow_8">
        <di:waypoint x="1275.0" y="290.0" />
        <di:waypoint x="1665.0" y="290.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="complete_DI_Flow_9" bpmnElement="complete_Flow_9">
        <di:waypoint x="1005.0" y="490.0" />
        <di:waypoint x="1175.0" y="490.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="complete_DI_Flow_10" bpmnElement="complete_Flow_10">
        <di:waypoint x="1225.0" y="490.0" />
        <di:waypoint x="1385.0" y="490.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="complete_DI_Flow_11" bpmnElement="complete_Flow_11">
        <di:waypoint x="1200.0" y="515.0" />
        <di:waypoint x="1200.0" y="655.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="complete_DI_Flow_12" bpmnElement="complete_Flow_12">
        <di:waypoint x="1535.0" y="490.0" />
        <di:waypoint x="1580.0" y="490.0" />
        <di:waypoint x="1660.0" y="490.0" />
        <di:waypoint x="1660.0" y="215.0" />
        <di:waypoint x="1740.0" y="215.0" />
        <di:waypoint x="1740.0" y="255.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="complete_DI_Flow_13" bpmnElement="complete_Flow_13">
        <di:waypoint x="1275.0" y="690.0" />
        <di:waypoint x="1320.0" y="690.0" />
        <di:waypoint x="1620.0" y="690.0" />
        <di:waypoint x="1620.0" y="215.0" />
        <di:waypoint x="1740.0" y="215.0" />
        <di:waypoint x="1740.0" y="255.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="complete_DI_Flow_14" bpmnElement="complete_Flow_14">
        <di:waypoint x="1815.0" y="290.0" />
        <di:waypoint x="1925.0" y="290.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="complete_DI_Flow_15" bpmnElement="complete_Flow_15">
        <di:waypoint x="2075.0" y="290.0" />
        <di:waypoint x="2222.0" y="290.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="complete_DI_Flow_16" bpmnElement="complete_Flow_16">
        <di:waypoint x="1268.0" y="325.0" />
        <di:waypoint x="1310.0" y="325.0" />
        <di:waypoint x="1690.0" y="325.0" />
        <di:waypoint x="1690.0" y="785.0" />
        <di:waypoint x="1740.0" y="785.0" />
        <di:waypoint x="1740.0" y="832.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="complete_DI_Flow_17" bpmnElement="complete_Flow_17">
        <di:waypoint x="998.0" y="525.0" />
        <di:waypoint x="1040.0" y="525.0" />
        <di:waypoint x="1040.0" y="785.0" />
        <di:waypoint x="1740.0" y="785.0" />
        <di:waypoint x="1740.0" y="832.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="complete_DI_Flow_18" bpmnElement="complete_Flow_18">
        <di:waypoint x="1528.0" y="525.0" />
        <di:waypoint x="1570.0" y="525.0" />
        <di:waypoint x="1740.0" y="525.0" />
        <di:waypoint x="1740.0" y="832.0" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="complete_DI_Flow_19" bpmnElement="complete_Flow_19">
        <di:waypoint x="1268.0" y="725.0" />
        <di:waypoint x="1310.0" y="725.0" />
        <di:waypoint x="1310.0" y="785.0" />
        <di:waypoint x="1740.0" y="785.0" />
        <di:waypoint x="1740.0" y="832.0" />
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>

Backend хранит доменный результат отдельно от статуса Ticket. При первом вызове он требует DONE или WONTFIX, получает metadata ручного результата и выбирает actor: явно переданный actor, иначе существующий пользователь reviewer_user_id, иначе assigned_to. Штатный вызов handler API явного actor не передаёт. Это выбор источника атрибуции; он не выдаёт пользователю новые права.

Документ

Для document-verification-v1 в DONE backend находит документ по public id и создаёт проверенную DocumentVersion. Проверяются соответствие документа Ticket, точная draft_revision и совместимость identity с уже проверенной версией. Изменившийся после запроса черновик отклоняется: требуется новая заявка проверки, а не подтверждение старой редакции.

В версию входят структурированные данные, срок действия, уровень/источник проверки, actor, ссылка на Ticket и снимки файлов. Обновляется указатель на текущую проверенную версию; планируется синхронизация документа. Сохранение формы Ticket само по себе этих действий не выполняет.

RequirementCheck

Для requirement-check-v1 backend загружает связанную попытку. Если она PENDING, вызывается доменное применение результата с passed=True, actor, комментарием и применимыми баллами. Проверяются связь с попыткой, возможность завершить её, обязательный ответственный и правила результата. Для уже завершённой попытки в DONE допустим только PASSED; несовместимое терминальное состояние приводит к ошибке.

Есть существенная граница текущей реализации: у автоматического алгоритма, использующего баллы и минимальный порог, положительное passed=True не отменяет порог. Низкий результат может сохранить FAILED, хотя Ticket пришёл в DONE. После первого применения backend возвращает фактический outcome; runtime всё равно переходит к CLOSED после успешного ответа. Поэтому надпись DONE или CLOSED не заменяет проверку outcome и состояния RequirementCheck. В схеме это отражено как доменная политика результата, а не как безусловное «DONE → PASSED».

Потребители и активация

После применения результата backend собирает найденных потребителей из reason проверки либо области документа, убирает повторы и вызывает evaluate_requirements. Для каждого потребителя с ok=true вызывается resume_approved_activation.

Это возобновление ранее одобренного процесса. Для ACCESS_REQUEST/NEG_REQUEST оно будит текущий handler, оставляя решение в его Blockly-алгоритме. Для исторической активации через ST_REQUEST допускается повтор канонического gate при DONE/CLOSED. Завершение одной проверки не выдаёт новое одобрение и не обходит оставшиеся обязательные требования.

Backend сохраняет verification_runtime.completed, outcome, details и consumer_evaluations. Успех отдельной проверки не означает, что все потребители готовы к активации. Даже при отрицательных consumer evaluations операция complete может успешно закончиться, а Ticket — закрыться; состояние требований и активации нужно смотреть отдельно.

Повторный вызов и неопределённый сетевой результат

Если marker verification_runtime.completed уже сохранён, backend возвращает записанные outcome/details и ещё не подтверждённое итоговое уведомление. Повторное создание версии документа, применение результата и пересчёт потребителей в этой ветви не выполняются. Это идемпотентность по marker конкретного Ticket, а не разрешение автоматически пересмотреть прежнее решение после переоткрытия.

Между complete, уведомлением и сменой статуса в CLOSED нет одной общей транзакции. При потере ответа backend мог уже сохранить результат, а Ticket ещё оставаться в DONE. Последующий проход использует marker; нельзя считать ошибку HTTP доказательством того, что результата нет. Если требуется новая попытка проверки, её следует оформлять по доменному сценарию с учётом редакции/попытки, а не стирать marker ради повторного исполнения.

Внешнее действие для обычного обращения

Обычный Ticket в DONE ждёт решения пользователя с доступом и правом смены статуса. Текущий lifecycle разрешает CLOSED, REOPENED или WONTFIX; view/API проверяют доступ и допустимость перехода. Авторство само по себе не даёт права закрыть собственную заявку. Таймер лишь повторяет проверку состояния и не выбирает решение за пользователя.

Канонический backend после commit публикует wakeup-события; прежний handler исключает свой снимок по ticket.moved. В каталоге нет отдельного open_st_request_closed: после CLOSED не следует ждать ещё одной бизнес-стадии с таким именем. При переходе в REOPENED или WONTFIX работает соответствующий владелец. Подробная схема внешнего решения и доставки событий приведена в сценарии IN_PROCESS; потерю доставки восстанавливает periodic reconciliation.

Уведомления и интервалы

Итоговое сообщение направляется автору через защищённый API получателей. Backend возвращает ключ; runtime после отправки пытается сохранить ack. Ack означает учёт попытки отправки, а не прочтение человеком; потеря ack допускает повтор сообщения. Неполученное уведомление не отменяет уже сохранённый результат.

Ситуация Ожидание / причина
Обычное обращение ST_REQUEST_DONE_RECHECK_SECONDS; support_closure_confirmation, журнал st_request_done
Ошибка HTTP/разбора complete 300 секунд; verification_completion_error
Ошибка уведомления/перехода вне локального catch DEFERRED_TICKET_RECHECK_SECONDS; processing_error
Сверка состава очереди INTERVAL_TIME_BD_REQ; scoped список

300 секунд — константа изученной версии runtime. Defer хранится в памяти и освобождает worker; срок означает готовность, а не гарантию точного запуска. Новая authoritative revision может снять defer, повтор того же снимка — нет. После рестарта состояние берётся из backend заново.

Диагностика

Для зависшего профильного Ticket различайте: статус Ticket, состояние документа/попытки, marker completed, outcome, consumer evaluations, ack уведомления и переход в CLOSED. Проверьте, не изменился ли черновик, не конфликтует ли терминальное состояние попытки с Ticket, хватает ли ответственного/баллов и работает ли scoped API. Для обычного обращения ожидание подтверждения закрытия является штатным поведением.

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

SHA-256 и параметры моделей сохранены в metadata страницы и documentation BPMN. Источники меняются — повторяется анализ, а не только обновление хешей.

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

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

© 2022 ShariX