| Предыдущая версия справа и слеваПредыдущая версияСледующая версия | Предыдущая версия |
| sharixopen:knowledge:scenarios:access_request_declined [2026/10/28 21:46] – [sharixknowledge] approved package sx_knowledge_api_open | sharixopen:knowledge:scenarios:access_request_declined [2026/10/31 11:25] (текущий) – [sharixknowledge] approved package sx_knowledge_api_open |
|---|
| "domain": "business_processes", | "domain": "business_processes", |
| "lifecycle": "implemented", | "lifecycle": "implemented", |
| "component": "handlers", | "component": "handlers_examples, handlers_backend, dbsynce", |
| "parents": [ | "parents": [ |
| "ShariXKnowledgeScenarios" | "ShariXKnowledgeScenarios" |
| ], | ], |
| "terms": [ | "terms": [ |
| "ACCESS_REQUEST", | "audience_developer", |
| "DECLINED", | "audience_administrator", |
| "Permissions", | "audience_support", |
| "grace", | "audience_reviewer", |
| "BPMN" | "audience_ai", |
| | "product_sharix_open", |
| | "material_scenario", |
| | "topic_handlers_permissions", |
| | "topic_security_permissions", |
| | "access_request", |
| | "ticket_declined", |
| | "permissions", |
| | "grace_period", |
| | "bpmn", |
| | "ticket", |
| | "blockly", |
| | "generated_python" |
| ] | ] |
| }, | }, |
| "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" |
| | ], |
| | "tag_terms": [ |
| | "audience_developer", |
| | "audience_administrator", |
| | "audience_support", |
| | "audience_reviewer", |
| | "audience_ai", |
| | "product_sharix_open", |
| | "material_scenario", |
| | "topic_handlers_permissions", |
| | "topic_security_permissions", |
| | "access_request", |
| | "ticket_declined", |
| | "permissions", |
| | "grace_period", |
| | "bpmn", |
| | "ticket", |
| | "blockly", |
| | "generated_python" |
| | ], |
| | "registry_document": "ShariXKnowledgeClassification", |
| | "state_meaning": "lifecycle относится к описываемому коду, а status к редакции документа; implemented не означает успешный runtime тест" |
| | }, |
| | "classification_review": { |
| | "date": "2026-10-31", |
| | "source": "Содержание текущей страницы и проверенный словарь классификации", |
| | "body_scope": "rewrite" |
| | }, |
| | "source_review_20261031": { |
| | "kind": "source_analysis_not_runtime_acceptance", |
| | "evidence_field": "extensions.source_evidence", |
| | "checked_on": "2026-10-31", |
| | "all_original_evidence_hashes_match_fresh_git": true, |
| | "canonical_generation": "Both runnable and generated copies match; no handler executed." |
| } | } |
| }, | }, |
| "content_sha256": "5ceb0649ec197cc666ea9d12a6d2f861b45357be9c5ee83c6923fac7d271d497", | "content_sha256": "5b48697fc7f4f539e205ee8b690a47c4557bfc715688a0dfe7d5f0d70a0919ed", |
| "schema": 1 | "schema": 1 |
| } | } |
| ~~NOCACHE~~ | ~~NOCACHE~~ |
| |
| **Область:** ShariX Open. **Обработчик:** ''open_access_request_declined'', тип ''ACCESS_REQUEST'' (3), рабочий статус ''DECLINED'' (359). Опубликованный 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|Доступ → Полномочия]]. |
| | |
| | |
| | |
| | **Область:** ShariX Open. **Обработчик:** ''open_access_request_declined'', тип ''ACCESS_REQUEST'' (3), рабочий статус ''DECLINED'' (359). 31.10.2026 опубликованные исходники повторно получены из Git. Обе Python-копии заново сопоставлены с результатом генерации Blockly; проверены 11 исходников генераторов. Сам handler не исполнялся. Выбранную версию, конфигурацию и внешние подключения сервера проверяют отдельно. |
| |
| ===== Назначение и границы ===== | ===== Назначение и границы ===== |
| Обработчик сопровождает уже отклонённую заявку. Он не принимает решение об отказе, не отзывает active permission и не удаляет строку Permissions физически. Неактивное право после контрольного срока может получить ''status=2'' (deleted), затем Ticket переводится в ''CLOSED''. ''ACCREQ_AUTOACCEPT'' в этом handler не используется. | Обработчик сопровождает уже отклонённую заявку: |
| | |
| | * не принимает новое решение об отказе; |
| | * не отзывает active permission; |
| | * не удаляет строку Permissions физически; |
| | * после контрольного срока может пометить неактивное право status=2 (deleted); |
| | * отдельно переводит Ticket в CLOSED. |
| | |
| | ACCREQ_AUTOACCEPT здесь не используется. |
| | |
| | Для расчёта срока важно: |
| | |
| | * начало отсчёта — **Ticket.updated_at**; |
| | * дата создания и отдельная дата решения не используются вместо него; |
| | * новая сохранённая ревизия Ticket может сдвинуть срок; |
| | * на каждом проходе заново проверяются статус Ticket и permission. |
| |
| Срок отсчитывается от **Ticket.updated_at**, а не даты создания заявки и не отдельно сохранённой даты решения. Новая сохранённая ревизия Ticket может сдвинуть контрольный срок. Одно лишь наступление таймера не гарантирует очистку: на каждом проходе снова проверяются текущий статус и состояние permission. | Наступление таймера само по себе не гарантирует очистку. |
| |
| Схемы имеют ''isExecutable=false'' и не запускают код. Runtime исполняет выбранный проверенный Python из Blockly. End event — завершение показанной операции, а не физическое удаление права или пользователя. | Схемы имеют ''isExecutable=false'' и не запускают код. Runtime исполняет выбранный проверенный Python из Blockly. End event — завершение показанной операции, а не физическое удаление права или пользователя. |
| </sharix-bpmn> | </sharix-bpmn> |
| |
| Runtime перед очисткой ещё раз читает permission. Если её не удалось найти, ''soft_delete_related_permission'' заканчивается без удаления, после чего handler всё равно переходит к запросу ''CLOSED''. Если повторное чтение уже показывает active, возникает ошибка, и Ticket автоматически не закрывается этой ветвью. | Повторное чтение permission перед очисткой даёт разные пути: |
| | |
| | * **Permission не найдена:** soft_delete_related_permission возвращается без удаления; handler затем пробует CLOSED. |
| | * **Permission стала active:** возникает ошибка; эта ветвь автоматически Ticket не закрывает. |
| | * **Неактивная permission найдена:** выполняется scoped soft_delete, backend повторяет защиту. |
| |
| Для существующей неактивной permission запрос идёт на ''dbsynce/api/handler/ticket/{ticket_id}/permission/'' с действием ''soft_delete''. Backend требует capability ''related.permission.status'', текущий Ticket scope и единственную связь, блокирует Ticket/permission и повторно проверяет сохранённый статус. Если право стало active между чтениями и записью, операция отклоняется. Такая гонка не разрешает удалить active право по устаревшему снимку. | Для существующей неактивной permission запрос идёт на ''dbsynce/api/handler/ticket/{ticket_id}/permission/'' с действием ''soft_delete''. Backend требует capability ''related.permission.status'', текущий Ticket scope и единственную связь, блокирует Ticket/permission и повторно проверяет сохранённый статус. Если право стало active между чтениями и записью, операция отклоняется. Такая гонка не разрешает удалить active право по устаревшему снимку. |
| |
| Успешный soft delete сохраняет ''status=2'' и Event. Это не SQL DELETE, не удаление пользователя и не отзыв произвольных других прав. Затем runtime отдельным scoped Ticket API запрашивает ''CLOSED''. Право уже могло получить deleted, а Ticket ещё оставаться DECLINED из-за ошибки второго запроса: общего commit этих двух операций нет. | Успехи двух операций подтверждают отдельно: |
| | |
| | * **Soft delete:** сохранены status=2 и Event; это не SQL DELETE, не удаление пользователя и не отзыв иных прав. |
| | * **Закрытие Ticket:** следующий scoped запрос перевёл его в CLOSED. |
| | |
| | Общего commit для этих двух запросов нет. Permission уже может быть deleted, а Ticket ещё DECLINED из-за ошибки второго запроса. |
| |
| Техническая стрелка между двумя API-пулами показывает последовательность запросов handler после ответа первой операции, а не прямой серверный вызов одного API другим. Случай отсутствующей permission является no-op на стороне runtime и не требует успешного POST soft_delete перед попыткой закрытия; он описан отдельно выше. | Техническая стрелка между двумя API-пулами показывает последовательность запросов handler после ответа первой операции, а не прямой серверный вызов одного API другим. Случай отсутствующей permission является no-op на стороне runtime и не требует успешного POST soft_delete перед попыткой закрытия; он описан отдельно выше. |
| Defer хранится в памяти и освобождает worker; новая authoritative revision может его снять, повтор того же снимка — нет. При рестарте состояние заново читается из backend. Ошибку API-списка нельзя считать пустой очередью. | Defer хранится в памяти и освобождает worker; новая authoritative revision может его снять, повтор того же снимка — нет. При рестарте состояние заново читается из backend. Ошибку API-списка нельзя считать пустой очередью. |
| |
| При диагностике различайте Ticket.status, его актуальный updated_at, рассчитанный deadline, фактический permission.status, связь с Ticket, Event soft delete и отдельный Event CLOSED. После неопределённого ответа сначала проверьте фактические состояния; не снимайте защиту active ради повторного запуска очистки. Долгое ожидание active permission является предусмотренной остановкой для разбора несогласованности. | При диагностике записать: |
| | |
| | * Ticket.status и актуальный updated_at; |
| | * рассчитанный deadline; |
| | * permission.status и связь с Ticket; |
| | * Event soft delete; |
| | * отдельный Event CLOSED. |
| | |
| | После неопределённого ответа сначала сверяют фактическое состояние. Защиту active не снимают ради повторной очистки. Ожидание при active permission — предусмотренная остановка для разбора несогласованности. |
| |
| ===== Проверенные источники ===== | ===== Проверенные источники ===== |