| Предыдущая версия справа и слеваПредыдущая версия | |
| sharixopen:knowledge:scenarios:access_request_pending [2026/10/28 21:46] – [sharixknowledge] approved package sx_knowledge_api_open | sharixopen:knowledge:scenarios:access_request_pending [2026/10/31 11:50] (текущий) – [sharixknowledge] approved package sx_knowledge_api_open |
|---|
| "ShariXKnowledgeSTRequestInProcessBPMN", | "ShariXKnowledgeSTRequestInProcessBPMN", |
| "ShariXKnowledgeScenarios" | "ShariXKnowledgeScenarios" |
| | ], |
| | "depends_on": [ |
| | "ShariXKnowledgeOpenKnowledgeModulesHandlers" |
| | ], |
| | "verified_by": [ |
| | "ShariXKnowledgeVerification" |
| ] | ] |
| }, | }, |
| "domain": "business_processes", | "domain": "business_processes", |
| "lifecycle": "implemented", | "lifecycle": "implemented", |
| "component": "handlers", | "component": "handlers_examples, handlers_backend, tickets, dbsynce", |
| "parents": [ | "parents": [ |
| "ShariXKnowledgeScenarios" | "ShariXKnowledgeScenarios" |
| ], | ], |
| "terms": [ | "terms": [ |
| "ACCESS_REQUEST", | "audience_developer", |
| "PENDING", | "audience_administrator", |
| "Permissions", | "audience_support", |
| "BPMN" | "audience_reviewer", |
| | "audience_ai", |
| | "product_sharix_open", |
| | "material_scenario", |
| | "topic_handlers_permissions", |
| | "topic_security_permissions", |
| | "topic_handlers_runtime", |
| | "access_request", |
| | "ticket_pending", |
| | "permissions", |
| | "bpmn", |
| | "ticket", |
| | "blockly", |
| | "generated_python" |
| ] | ] |
| }, | }, |
| "path": "services/handler_wakeup.py", | "path": "services/handler_wakeup.py", |
| "sha256": "c9fdc62a18301fd7c075395c697d5b1c738c77713aa71fcbb5ab097e173d98de" | "sha256": "c9fdc62a18301fd7c075395c697d5b1c738c77713aa71fcbb5ab097e173d98de" |
| | }, |
| | { |
| | "repository": "sharix-open-tickets", |
| | "commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14", |
| | "path": "models/ticket.py", |
| | "sha256": "4768d9ef47b61bf3ae98bf2749ed142adc477978b44de29177363ba9664baa43" |
| } | } |
| ], | ], |
| "utility": "tools/expand_bpmn_view_bounds.py", | "utility": "tools/expand_bpmn_view_bounds.py", |
| "utility_sha256": "f878658b0115773e34f6c3eec72eba5984d873e60d8e2a4336b3dfb2a8026d87" | "utility_sha256": "f878658b0115773e34f6c3eec72eba5984d873e60d8e2a4336b3dfb2a8026d87" |
| | }, |
| | "classification": { |
| | "schema": "sharix.knowledge.classification.v1", |
| | "products": [ |
| | "sharix_open" |
| | ], |
| | "audiences": [ |
| | "developer", |
| | "administrator", |
| | "support", |
| | "reviewer", |
| | "ai" |
| | ], |
| | "material": "scenario", |
| | "topics": [ |
| | "handlers/permissions", |
| | "security/permissions", |
| | "handlers/runtime" |
| | ], |
| | "tag_terms": [ |
| | "audience_developer", |
| | "audience_administrator", |
| | "audience_support", |
| | "audience_reviewer", |
| | "audience_ai", |
| | "product_sharix_open", |
| | "material_scenario", |
| | "topic_handlers_permissions", |
| | "topic_security_permissions", |
| | "topic_handlers_runtime", |
| | "access_request", |
| | "ticket_pending", |
| | "permissions", |
| | "bpmn", |
| | "ticket", |
| | "blockly", |
| | "generated_python" |
| | ], |
| | "registry_document": "ShariXKnowledgeClassification", |
| | "state_meaning": "implemented — описана проверенная реализация исходников; серверный runtime отдельно; review — состояние текста" |
| | }, |
| | "editorial_review": { |
| | "date": "2026-10-31", |
| | "scope": "Конкретизация шагов, участников, условий, результатов и диагностики; перечисления; BPMN сохранены побайтово", |
| | "current_source_records_verified": 19, |
| | "original_source_evidence_recheck": "Все исходные commits и SHA-256 повторно совпали после git fetch; дополнительные функциональные источники включены в source_evidence", |
| | "canonical_regeneration": { |
| | "both_python_copies_match": true, |
| | "generator_sources_verified": 11, |
| | "handler_executed": false |
| | }, |
| | "runtime_checked": false, |
| | "correction": "Из PENDING доступны только ACCEPTED и DECLINED; прежнее упоминание прямого CLOSED исправлено по LIFE_CYCLE_DICT" |
| } | } |
| }, | }, |
| "content_sha256": "4cfe0ead08ebc26633d2e42c010a332f3f349c9da167dedb1197f9ec90bef4af", | "content_sha256": "a03738eda1548ff824a05a8bf6c3d33cda5b8e1366db1027013d6820cacb0d6d", |
| "schema": 1 | "schema": 1 |
| } | } |
| ~~NOCACHE~~ | ~~NOCACHE~~ |
| |
| **Область:** ShariX Open. **Обработчик:** ''open_access_request_pending'', тип ''ACCESS_REQUEST'' (3), рабочий статус ''PENDING'' (320). Опубликованный встроенный Python на 28.10.2026 побайтово совпадает с канонической генерацией из Blockly workspace. Состояние выбранной версии конкретного сервера проверяется отдельно. | **Назначение:** [[sharixopen:knowledge:classification:materials#scenarij_processa|Сценарий процесса]]. **Продукт:** [[sharixopen:knowledge:classification:products#sharix_open|ShariX Open]]. |
| | |
| | **Для кого:** [[sharixopen:knowledge:classification:audiences#razrabotchik|Разработчик]] · [[sharixopen:knowledge:classification:audiences#administrator|Администратор]] · [[sharixopen:knowledge:classification:audiences#podderzhka|Поддержка]] · [[sharixopen:knowledge:classification:audiences#recenzent_i_prijomschik|Рецензент и приёмщик]] · [[sharixopen:knowledge:classification:audiences#nejroset|Нейросеть]]. |
| | |
| | **Темы:** [[sharixopen:knowledge:classification:topics#access_request|Обработчики → ACCESS_REQUEST]] · [[sharixopen:knowledge:classification:topics#polnomochija|Доступ → Полномочия]] · [[sharixopen:knowledge:classification:topics#runtime|Обработчики → Runtime]]. |
| | |
| | |
| | |
| | **Область:** ShariX Open. **Обработчик:** ''open_access_request_pending'', тип ''ACCESS_REQUEST'' (3), рабочий статус ''PENDING'' (320). 31.10.2026 исходники повторно получены из Git: обе Python-копии совпали с новой канонической генерацией Blockly, проверены 11 исходников генераторов. Сам handler не исполнялся. Выбранная серверная версия, её настройки и работающие API/XMPP проверяются отдельно. |
| |
| ===== Назначение и границы ===== | ===== Назначение и границы ===== |
| Обработчик сопровождает запрос на предоставление права до решения. Он не создаёт Permissions, не проверяет все требования и не активирует право. При автоматическом режиме запрашивается стадия ''ACCEPTED'' и Ticket передаётся следующему handler; активация остаётся отдельной операцией с доменными проверками. | Обработчик сопровождает запрос на право до решения: |
| | |
| | * при ручном режиме сообщает о заявке и ждёт; |
| | * при автоматическом режиме запрашивает ACCEPTED и передаёт Ticket следующему handler; |
| | * не создаёт Permissions, не активирует право и не подтверждает выполнение всех требований. |
| | |
| | Принятие запроса и фактическая активация права — разные операции. |
| | |
| | Порядок первых проверок: |
| | |
| | - Проверить рабочий PENDING. |
| | - Если assigned_to is not None — запросить удаление локального Ticket и комнаты и закончить проход. |
| | - Только для неназначенной заявки читать ACCREQ_AUTOACCEPT и выбирать ручную/автоматическую ветвь. |
| |
| Первый фильтр после рабочего статуса — ''assigned_to is not None''. Если Ticket уже назначен, текущий проход запрашивает его удаление из локальной очереди и удаление комнаты. Это не положительное решение и не передача в ACCEPTED: статус не меняется. Scoped список PENDING фильтруется по типу и статусу, поэтому при сохранении PENDING такая карточка может снова попасть из periodic reconciliation и вновь быть исключена. Назначение пользователя и решение по заявке следует различать. | Исключение назначенного Ticket не меняет бизнес-статус. Если он остаётся PENDING, scoped список по типу и статусу может вернуть его при следующей периодической сверке. Это не автоматическое принятие и не устойчивый перевод в следующую стадию. |
| |
| Следующая развилка использует ''ACCREQ_AUTOACCEPT'', а не настройку ST_REQUEST. Значение берётся при создании HandlerContext. Изменение окружения не следует считать уже применённым к работающему процессу без проверки его конфигурации/перезапуска. | Следующая развилка использует ''ACCREQ_AUTOACCEPT'', а не настройку ST_REQUEST. Значение берётся при создании HandlerContext. Изменение окружения не следует считать уже применённым к работающему процессу без проверки его конфигурации/перезапуска. |
| * Неназначенный Ticket, autoaccept включён — запросить ''ACCEPTED'' через scoped Ticket API, явно передать в ''open_access_request_accepted'' и убрать текущий Ticket с сохранением комнаты после успешной передачи. | * Неназначенный Ticket, autoaccept включён — запросить ''ACCEPTED'' через scoped Ticket API, явно передать в ''open_access_request_accepted'' и убрать текущий Ticket с сохранением комнаты после успешной передачи. |
| |
| 404 перехода означает устаревший scope и запрашивает локальную очистку. Иная ошибка API/отправки попадает в общий ''processing_error'' и defer по ''DEFERRED_TICKET_RECHECK_SECONDS''. Уже committed ACCEPTED не откатывается из-за ошибки прямой XMPP-передачи: backend wakeup и periodic reconciliation позволяют следующему владельцу получить сохранённое состояние. | Различать ответы перехода и последующие ошибки: |
| | |
| | * **404 scoped transition:** Ticket вышел из доступного контекста, запрашивается локальная очистка. |
| | * **Ошибка API либо уведомления:** общий processing_error и DEFERRED_TICKET_RECHECK_SECONDS. |
| | * **ACCEPTED сохранён, прямая XMPP-передача не удалась:** сохранённое решение не откатывается; wakeup и periodic reconciliation позволяют следующему владельцу восстановить очередь. |
| |
| ===== Ручное решение и внешние участники (BPMN) ===== | ===== Ручное решение и внешние участники (BPMN) ===== |
| </sharix-bpmn> | </sharix-bpmn> |
| |
| В текущем lifecycle из ''PENDING'' разрешены ''ACCEPTED'', ''DECLINED'' или ''CLOSED''. Основное решение о доступе — принятие либо отказ; закрытие без перехода в профильный handler не является подтверждением активации права. Схема показывает рассмотрение и эти два профильных исхода. Чтение Ticket и право менять его статус проверяются отдельно; авторство само по себе не даёт права принять собственный запрос. | Текущий LIFE_CYCLE_DICT разрешает из PENDING (320) ровно два перехода: |
| | |
| | * **ACCEPTED (321):** запрос принят, профильный handler продолжает требования и активацию. |
| | * **DECLINED (359):** запрос отклонён, далее действует отдельный сценарий отказа. |
| | |
| | Прямого PENDING → CLOSED в текущем коде нет; прежнее упоминание такого исхода здесь исправлено. BPMN уже показывает ACCEPTED/DECLINED. Право читать заявку и право принять решение проверяются отдельно; авторство не даёт права одобрить собственный запрос. |
| |
| Уведомление или ответ текстом в XMPP-комнате не являются реализованным действием смены статуса в этом handler. Пользователь выполняет решение через разрешённую карточку/API; backend проверяет права и lifecycle, сохраняет статус и Event, после commit отправляет ''ticket.changed'' новому владельцу и ''ticket.moved'' прежнему. Ошибка доставки не отменяет сохранённое решение. Прежний in-flight worker учитывает pending discard после завершения прохода. | Уведомление или ответ текстом в XMPP-комнате не являются реализованным действием смены статуса в этом handler. Пользователь выполняет решение через разрешённую карточку/API; backend проверяет права и lifecycle, сохраняет статус и Event, после commit отправляет ''ticket.changed'' новому владельцу и ''ticket.moved'' прежнему. Ошибка доставки не отменяет сохранённое решение. Прежний in-flight worker учитывает pending discard после завершения прохода. |
| |
| ===== Как устроено уведомление в этой реализации ===== | ===== Как устроено уведомление в этой реализации ===== |
| ''notify_admins'' здесь использует комнату ''ticket_<id>_type_3'' через ejabberd API. Участники формируются из активных пользователей группы ''METASERVICE-ADMIN'', имеющих XMPP-реквизиты, JID текущего bot и report JID; повторы убираются. Локальный helper использует Django-контекст для поиска участников. | notify_admins отправляет сообщение в комнату ticket_<id>_type_3 через ejabberd API. Состав комнаты: |
| | |
| | * активные пользователи METASERVICE-ADMIN с XMPP-реквизитами; |
| | * JID текущего bot; |
| | * report JID. |
| | |
| | Повторяющиеся JID исключаются. Этот локальный helper получает пользователей через Django-контекст. |
| |
| Поле ''decision_maker_group'' входит в текст уведомления, но в этом пути не является фильтром участников комнаты. Это отличается от адресного reviewer API профильных ST_REQUEST-проверок: нельзя автоматически переносить его правила получателей на данный handler. Участие в комнате не выдаёт права на Ticket. | Поле ''decision_maker_group'' входит в текст уведомления, но в этом пути не является фильтром участников комнаты. Это отличается от адресного reviewer API профильных ST_REQUEST-проверок: нельзя автоматически переносить его правила получателей на данный handler. Участие в комнате не выдаёт права на Ticket. |
| Helper пытается создать members-only комнату, добавить/подписать/пригласить участников. Часть ошибок подготовки ловится и логируется, затем комната попадает в локальный cache; это не доказательство успешной доставки всем участникам. Само сообщение отправляется отдельно. В этом пути нет durable ack ключа, как у verification notifications: при повторных проходах ручной ветви сообщение может отправляться снова. Уведомление не гарантирует прочтение человеком. | Helper пытается создать members-only комнату, добавить/подписать/пригласить участников. Часть ошибок подготовки ловится и логируется, затем комната попадает в локальный cache; это не доказательство успешной доставки всем участникам. Само сообщение отправляется отдельно. В этом пути нет durable ack ключа, как у verification notifications: при повторных проходах ручной ветви сообщение может отправляться снова. Уведомление не гарантирует прочтение человеком. |
| |
| Формирование сообщения использует ''AccessRequestTicket'' из JSON payload: в нём должны присутствовать обязательные реквизиты, включая ''requested_role''. Пустой или несовместимый JSON не превращается в корректную заявку и может привести к общему retry до исправления данных. Промокод и комментарий существуют в payload, но этот handler не валидирует промокод и не использует его как основание автоматической выдачи права. | Сообщение формируется из AccessRequestTicket и JSON payload: |
| | |
| | * requested_role — обязательный реквизит конструктора; |
| | * decision_maker_group — реквизит текста, а не фильтр участников этой комнаты; |
| | * promocode и comment могут присутствовать, но промокод здесь не валидируется и не даёт основания для автоматического права. |
| | |
| | Несовместимый или пустой JSON может приводить к общему retry; сам повтор не исправляет структуру заявки. |
| |
| ===== Таймеры и восстановление ===== | ===== Таймеры и восстановление ===== |
| |
| ===== Что проверить при отсутствии движения ===== | ===== Что проверить при отсутствии движения ===== |
| Различайте назначение ''assigned_to'', решение PENDING→ACCEPTED/DECLINED и фактическую активацию permission. Проверьте выбранный Python/workspace, ''ACCREQ_AUTOACCEPT'', JSON заявки, состав и доступность MUC-комнаты, права рассматривающего, scoped Ticket API и доставку commit-событий. Если Ticket уже ACCEPTED, диагностику требований и права продолжайте в следующей стадии, а не повторным принятием запроса. | Порядок диагностики: |
| | |
| | - Прочитать статус и assigned_to: назначение пользователя не равно решению. |
| | - Для PENDING сверить выбранную версию, ACCREQ_AUTOACCEPT и корректность JSON. |
| | - В ручном режиме проверить подготовку MUC-комнаты, сообщение и участников. |
| | - Проверить права рассматривающего, scoped transition API и доставку commit-событий. |
| | - Если Ticket уже ACCEPTED, продолжить проверку требований и активации в следующем сценарии. |
| | |
| | Не следует повторно принимать запрос только потому, что право ещё не стало active. |
| |
| ===== Проверенные источники ===== | ===== Проверенные источники ===== |