{
"id": "ShariXKnowledgeNegRequestDeclinedBPMN",
"page": "sharixopen:knowledge:scenarios:neg_request_declined",
"area": "open",
"type": "procedure",
"title": "NEG_REQUEST в DECLINED: сохранение active Relationship и очистка после срока",
"status": "review",
"schema_version": 1,
"relations": {
"related_to": [
"ShariXKnowledgeNegRequestPendingBPMN",
"ShariXKnowledgeNegRequestAcceptedBPMN",
"ShariXKnowledgeAccessRequestDeclinedBPMN",
"ShariXKnowledgeOpenKnowledgeModulesHandlers",
"ShariXKnowledgeScenarios"
],
"depends_on": [
"ShariXKnowledgeOpenKnowledgeModulesHandlers",
"ShariXKnowledgeOpenKnowledgeModulesBackenddbsynce"
],
"verified_by": [
"ShariXKnowledgeVerification"
]
},
"extensions": {
"taxonomy": {
"domain": "business_processes",
"lifecycle": "implemented",
"component": "handlers_examples, handlers_backend, dbsynce, tickets",
"parents": [
"ShariXKnowledgeScenarios"
],
"terms": [
"audience_developer",
"audience_support",
"audience_reviewer",
"audience_ai",
"product_sharix_open",
"material_scenario",
"topic_handlers_relationships",
"topic_architecture_models",
"topic_handlers_runtime",
"neg_request",
"ticket_declined",
"relationship",
"grace_period",
"bpmn",
"ticket",
"blockly",
"generated_python"
]
},
"diagram": {
"format": "bpmn",
"executable": false
},
"source_evidence": [
{
"repository": "sharix-open-handlers-examples",
"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb",
"path": "handlers/open_neg_request_declined.py",
"sha256": "6813d34df6519db2544c33c365daab408c50abf0c4d7a94d5b4f5ba1289d0355"
},
{
"repository": "sharix-open-handlers-examples",
"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb",
"path": "generated_handler_blocks/open_neg_request_declined.json",
"sha256": "93d5a75a98975fccf560e9a03f2600c166d9eb9acf90dab0256e02a1b9068f95"
},
{
"repository": "sharix-open-handlers-examples",
"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb",
"path": "catalog.py",
"sha256": "e3dcb72b7e620e2837adacd7af053f35b04cdff475789496d9c114e17d57dfde"
},
{
"repository": "sharix-open-handlers-backend",
"commit": "50baf376e224d915a87d63240f3f339b3dda9afa",
"path": "core/blockly_runtime.py",
"sha256": "3e222150cbff315077c6c9b160d46e59856cedf6d6591d213e958c63cb2f2428"
},
{
"repository": "sharix-open-handlers-backend",
"commit": "50baf376e224d915a87d63240f3f339b3dda9afa",
"path": "core/handler_operations.py",
"sha256": "28620658501c375f556e24437871620b84a17a88d0b62b2d1a3cc5deb2f14b1e"
},
{
"repository": "sharix-open-handlers-backend",
"commit": "50baf376e224d915a87d63240f3f339b3dda9afa",
"path": "core/ejabberd_muc.py",
"sha256": "35c2eba89fab36b5c444439a87beaa516b55133991136d5370418d92a18d7bcd"
},
{
"repository": "sharix-open-handlers-backend",
"commit": "50baf376e224d915a87d63240f3f339b3dda9afa",
"path": "core/requesters.py",
"sha256": "965a348cea477722bbaf4c8c6b06023eb238b71664a332f7ea8c90bfe72ea808"
},
{
"repository": "sharix-open-handlers-backend",
"commit": "50baf376e224d915a87d63240f3f339b3dda9afa",
"path": "ticket_blockly_codegen.py",
"sha256": "bce71eab622922f8dd0954222842349799b60e18a0ab6310cc3e5f305603661e"
},
{
"repository": "sharix-open-handlers-backend",
"commit": "50baf376e224d915a87d63240f3f339b3dda9afa",
"path": "ticket_codegen_contract.json",
"sha256": "0bfd2b0ebb07bd380ed3c867386536ab88ef7dfa6e13f1cd8c91d32bb02c1ae9"
},
{
"repository": "sharix-open-tickets",
"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14",
"path": "lib/tickets.py",
"sha256": "0d260c17947f9a186d07af2749159780e3c7354a95b4bafe9d67493663c96883"
},
{
"repository": "sharix-open-tickets",
"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14",
"path": "api/views/handler_workflow.py",
"sha256": "f97c4b467a9a30749f5c4b86b39a833c430e57aaa1f030f70030d9b5c609d368"
},
{
"repository": "sharix-open-tickets",
"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14",
"path": "api/handler_auth.py",
"sha256": "ac76dc45aaa9742e5e1da0b98aae914bb2e287048d33e97b4a245a6997bc8425"
},
{
"repository": "sharix-open-tickets",
"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14",
"path": "utils.py",
"sha256": "a5680205c6522e1d9a74d9d267fe9ee96faf6f06436b00877fc0a93d80234bf5"
},
{
"repository": "sharix-open-tickets",
"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14",
"path": "views/ticket_detail.py",
"sha256": "05d344b0fba14cf895400694d4a18f486c800fef08dd1acb43ea46909b9e7e59"
},
{
"repository": "sharix-open-tickets",
"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14",
"path": "signals.py",
"sha256": "39aad8690a2e7d35cebfb052127a8130a951cbb4eea316c4f767a0a59fc5fa7e"
},
{
"repository": "sharix-open-tickets",
"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14",
"path": "services/handler_wakeup.py",
"sha256": "c9fdc62a18301fd7c075395c697d5b1c738c77713aa71fcbb5ab097e173d98de"
},
{
"repository": "sharix-open-backend",
"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093",
"path": "apiviews/handler_workflow.py",
"sha256": "0f699a4e16760cbbdd09d894093c685ba69073fedf0522852cb1fdc9811636e3"
},
{
"repository": "sharix-open-backend",
"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093",
"path": "lib/dicts.py",
"sha256": "d92ddaa0964324e337303f8de110acf6ff21e15d7b40a6e523ce78ed48b7d8c5"
},
{
"repository": "sharix-open-backend",
"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093",
"path": "models/relationship.py",
"sha256": "873f27666a7d03b8058958b752d0e69d17d3433daf72f901fa88275cf10f43aa"
},
{
"repository": "sharix-open-tickets",
"commit": "fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14",
"path": "models/ticket.py",
"sha256": "4768d9ef47b61bf3ae98bf2749ed142adc477978b44de29177363ba9664baa43"
}
],
"handler_process": {
"handler_id": "open_neg_request_declined",
"source_kind": "git_builtin",
"canonical_python_verified": true,
"reviewed_on": "2026-10-28",
"generator": "tools/generate_handler_bpmn.py",
"generator_sha256": "ca837a7b9e55bf58184bdf408a8035d25667ed9c5d3068ca52380b2ff5682f95",
"models": {
"logic": "858f12a0cfdeb1c6996173fccce19f7b48bfdf22e0df78d1751eb67654fe0f90",
"cleanup": "4e4c6be9971642c1c093e234f1e254db98cd1c7a2c061045f2ecb0e72e05515a"
}
},
"classification": {
"schema": "sharix.knowledge.classification.v1",
"products": [
"sharix_open"
],
"audiences": [
"developer",
"support",
"reviewer",
"ai"
],
"material": "scenario",
"topics": [
"handlers/relationships",
"architecture/models",
"handlers/runtime"
],
"tag_terms": [
"audience_developer",
"audience_support",
"audience_reviewer",
"audience_ai",
"product_sharix_open",
"material_scenario",
"topic_handlers_relationships",
"topic_architecture_models",
"topic_handlers_runtime",
"neg_request",
"ticket_declined",
"relationship",
"grace_period",
"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": 20,
"original_source_evidence_recheck": "После git fetch все исходные commits/SHA-256 совпали; дополнительные функциональные источники включены в source_evidence",
"canonical_regeneration": {
"kind": "ticket",
"compared_python_paths": [
"handlers/open_neg_request_declined.py",
"generated_handlers/open_neg_request_declined.py"
],
"generator_sources_verified": 11,
"handler_executed": false
},
"runtime_checked": false,
"correction": "Из NEG_REQUEST DECLINED доступен только CLOSED; прежнее упоминание ACCEPTED исправлено по LIFE_CYCLE_DICT"
}
},
"content_sha256": "d4bcce947bfddf4d46dae21c976d5688e9f0906bab405f6aa067ef051fc2f0e0",
"schema": 1
}
====== NEG_REQUEST в DECLINED: сохранение active Relationship и очистка после срока ======
~~NOCACHE~~
**Назначение:** [[sharixopen:knowledge:classification:materials#scenarij_processa|Сценарий процесса]]. **Продукт:** [[sharixopen:knowledge:classification:products#sharix_open|ShariX Open]].
**Для кого:** [[sharixopen:knowledge:classification:audiences#razrabotchik|Разработчик]] · [[sharixopen:knowledge:classification:audiences#podderzhka|Поддержка]] · [[sharixopen:knowledge:classification:audiences#recenzent_i_prijomschik|Рецензент и приёмщик]] · [[sharixopen:knowledge:classification:audiences#nejroset|Нейросеть]].
**Темы:** [[sharixopen:knowledge:classification:topics#neg_request|Обработчики → NEG_REQUEST]] · [[sharixopen:knowledge:classification:topics#vladenie_modeljami|Архитектура → Владение моделями]] · [[sharixopen:knowledge:classification:topics#runtime|Обработчики → Runtime]].
**Область:** ShariX Open. **Обработчик:** ''open_neg_request_declined'', тип ''NEG_REQUEST'' (4), рабочий статус ''DECLINED'' (459). 31.10.2026 исходники повторно получены из Git. Обе Python-копии совпали с новой канонической генерацией Blockly; проверены 11 исходников генераторов. Сам обработчик и его внешние действия не запускались. Выбранная версия, настройки и доступность подключений конкретной установки проверяются отдельно.
===== Назначение и границы =====
Handler получает уже отклонённый запрос на публичную dbsynce.Relationship. После контрольного срока:
* **Active:** сохранить Relationship и закрыть только Ticket.
* **Неактивная:** попробовать soft delete со status=2, затем отдельно закрыть Ticket.
* **Связь не найдена при повторном чтении:** удаление становится no-op, после которого возможна попытка CLOSED.
Решение об отказе принято до этой стадии. Политика Permissions на Relationship не переносится.
Это отличается от [[sharixopen:knowledge:scenarios:access_request_declined|ACCESS_REQUEST/DECLINED]], который при active permission отправляет ALERT и остаётся ждать разбора. В NEG/DECLINED active-состояние не блокирует закрытие Ticket после срока. Встроенный алгоритм пишет локальную запись журнала о сохранении active, но не вызывает ''notify_admins'' или ''notify_creator''.
В публичной модели Relationship используются:
* user_who — инициирующая сторона;
* user_whom — связанная сторона;
* neg_type — тип отношения;
* company — контекст компании;
* ticket_status — ссылка на сопровождающий Ticket.
Сохранение active Relationship не является отзывом роли или удалением пользователя. NEGREQ_AUTOACCEPT в этой стадии не используется.
Просмотрщик не исполняет процесс: BPMN имеют ''isExecutable=false'', runtime запускает выбранный проверенный Python из Blockly. End event завершает показанный проход, а не аннулирует действующие отношения сторон.
===== Один проход и ожидание (BPMN) =====
{"notes": ["Git built-in, BPMN isExecutable=false; код handler не выполняется при генерации.", "Сначала grace по Ticket.updated_at, затем проверка Relationship.", "Active Relationship сохраняется: после срока закрывается только Ticket.", "Soft delete неактивной связи — status=2, не физическое удаление."], "sources": [{"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "handlers/open_neg_request_declined.py", "repository": "sharix-open-handlers-examples", "sha256": "6813d34df6519db2544c33c365daab408c50abf0c4d7a94d5b4f5ba1289d0355"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "generated_handler_blocks/open_neg_request_declined.json", "repository": "sharix-open-handlers-examples", "sha256": "93d5a75a98975fccf560e9a03f2600c166d9eb9acf90dab0256e02a1b9068f95"}, {"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/dicts.py", "repository": "sharix-open-backend", "sha256": "d92ddaa0964324e337303f8de110acf6ff21e15d7b40a6e523ce78ed48b7d8c5"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "models/relationship.py", "repository": "sharix-open-backend", "sha256": "873f27666a7d03b8058958b752d0e69d17d3433daf72f901fa88275cf10f43aa"}]}
negdeclined_start
negdeclined_status
negdeclined_age
negdeclined_read
negdeclined_active
negdeclined_log
negdeclined_close
negdeclined_confirmed
negdeclined_remove
negdeclined_end
negdeclined_stale
negdeclined_stale_end
negdeclined_grace
negdeclined_delete
negdeclined_not_found
negdeclined_read_error
negdeclined_delete_error
negdeclined_close_error
negdeclined_retry
negdeclined_wait
negdeclined_timer
negdeclined_revision
negdeclined_ready
negdeclined_Flow_0
negdeclined_Flow_0
negdeclined_Flow_24
negdeclined_Flow_1
negdeclined_Flow_2
negdeclined_Flow_1
negdeclined_Flow_4
negdeclined_Flow_5
negdeclined_Flow_4
negdeclined_Flow_6
negdeclined_Flow_6
negdeclined_Flow_7
negdeclined_Flow_8
negdeclined_Flow_7
negdeclined_Flow_9
negdeclined_Flow_9
negdeclined_Flow_10
negdeclined_Flow_11
negdeclined_Flow_11
negdeclined_Flow_12
negdeclined_Flow_14
negdeclined_Flow_12
negdeclined_Flow_13
negdeclined_Flow_13
negdeclined_Flow_2
negdeclined_Flow_3
negdeclined_Flow_3
min(updated_at+NEG_REQUEST_DECLINED_CLEANUP_GRACE_DAYS, now+DEFERRED_TICKET_RECHECK_SECONDS)
negdeclined_Flow_5
negdeclined_Flow_15
Отсутствующая связь: no-op. Ставшая active при повторном чтении: исключение, не удаление.
negdeclined_Flow_8
negdeclined_Flow_10
negdeclined_Flow_14
negdeclined_Flow_16
negdeclined_Flow_17
negdeclined_Flow_18
negdeclined_Flow_16
negdeclined_Flow_17
negdeclined_Flow_18
negdeclined_Flow_19
negdeclined_Flow_15
negdeclined_Flow_19
negdeclined_Flow_20
negdeclined_Flow_21
negdeclined_Flow_20
negdeclined_Flow_22
deferred_until
negdeclined_Flow_21
negdeclined_Flow_23
negdeclined_Flow_22
negdeclined_Flow_23
negdeclined_Flow_24
* Чужой статус — запросить удаление локального Ticket и комнаты.
* Контрольный срок ещё не наступил — записать ''declined_relationship_grace'', назначить короткий defer и освободить worker. До этого срока Relationship вообще не читается данной бизнес-ветвью.
* Срок наступил, Relationship active — записать в журнал, что active сохраняется, и перейти к запросу CLOSED без soft delete.
* Срок наступил, Relationship не active/не найдена — вызвать ''soft_delete_related_relationship'', затем запросить CLOSED. При успешном переходе убрать локальный Ticket и комнату.
Расчёт контрольного срока:
* начало — Ticket.updated_at;
* интервал — NEG_REQUEST_DECLINED_CLEANUP_GRACE_DAYS;
* минимум настройки — 0 дней;
* новая сохранённая ревизия может сдвинуть дату.
Created_at и отдельная дата отказа вместо updated_at не используются. Фактическое значение сервера здесь не предполагается.
===== Ожидание контрольного срока =====
Граница — ''updated_at + grace_days''. Следующий локальный defer выбирается как минимум этой границы и ''now + DEFERRED_TICKET_RECHECK_SECONDS'': handler периодически сверяется, не занимает worker до конца grace и может получить новую ревизию раньше. Локальная причина и строка журнала defer — ''declined_relationship_grace''.
Если updated_at отсутствует либо не разбирается, проверка возраста возвращает false, а helper расчёта не устанавливает корректный срок. Это не доказательство истёкшего grace и не штатное ожидание по достоверной дате; данные нужно сверить. Новая authoritative revision может снять defer, повтор того же снимка — нет. После рестарта очередь заново получает актуальное состояние.
===== Backend soft delete и отдельное закрытие (BPMN) =====
{"notes": ["Git built-in, BPMN isExecutable=false; код handler не выполняется при генерации.", "Сначала grace по Ticket.updated_at, затем проверка Relationship.", "Active Relationship сохраняется: после срока закрывается только Ticket.", "Soft delete неактивной связи — status=2, не физическое удаление.", "Этот API вызывается только для предполагаемой неактивной связи. Active-ветвь главного handler закрывает Ticket без soft_delete.", "Активность повторно проверяется backend под блокировкой."], "sources": [{"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "handlers/open_neg_request_declined.py", "repository": "sharix-open-handlers-examples", "sha256": "6813d34df6519db2544c33c365daab408c50abf0c4d7a94d5b4f5ba1289d0355"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "generated_handler_blocks/open_neg_request_declined.json", "repository": "sharix-open-handlers-examples", "sha256": "93d5a75a98975fccf560e9a03f2600c166d9eb9acf90dab0256e02a1b9068f95"}, {"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/dicts.py", "repository": "sharix-open-backend", "sha256": "d92ddaa0964324e337303f8de110acf6ff21e15d7b40a6e523ce78ed48b7d8c5"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "models/relationship.py", "repository": "sharix-open-backend", "sha256": "873f27666a7d03b8058958b752d0e69d17d3433daf72f901fa88275cf10f43aa"}]}
relationship_start
relationship_lock
relationship_find
relationship_active
relationship_save
relationship_ok
relationship_end
relationship_reject
relationship_missing
relationship_Flow_0
relationship_Flow_0
relationship_Flow_1
relationship_Flow_1
relationship_Flow_2
relationship_Flow_2
relationship_Flow_3
relationship_Flow_4
relationship_Flow_3
relationship_Flow_5
relationship_Flow_5
relationship_Flow_6
relationship_Flow_6
relationship_Flow_4
{"notes": ["Git built-in, BPMN isExecutable=false; код handler не выполняется при генерации.", "Сначала grace по Ticket.updated_at, затем проверка Relationship.", "Active Relationship сохраняется: после срока закрывается только Ticket.", "Soft delete неактивной связи — status=2, не физическое удаление.", "Этот API вызывается только для предполагаемой неактивной связи. Active-ветвь главного handler закрывает Ticket без soft_delete.", "Активность повторно проверяется backend под блокировкой."], "sources": [{"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "handlers/open_neg_request_declined.py", "repository": "sharix-open-handlers-examples", "sha256": "6813d34df6519db2544c33c365daab408c50abf0c4d7a94d5b4f5ba1289d0355"}, {"commit": "76e0c693b628ed4a1fa34515a3f8abdff26149bb", "path": "generated_handler_blocks/open_neg_request_declined.json", "repository": "sharix-open-handlers-examples", "sha256": "93d5a75a98975fccf560e9a03f2600c166d9eb9acf90dab0256e02a1b9068f95"}, {"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/dicts.py", "repository": "sharix-open-backend", "sha256": "d92ddaa0964324e337303f8de110acf6ff21e15d7b40a6e523ce78ed48b7d8c5"}, {"commit": "778a3280cee115ba0efe3fdff7b0e708b0c10093", "path": "models/relationship.py", "repository": "sharix-open-backend", "sha256": "873f27666a7d03b8058958b752d0e69d17d3433daf72f901fa88275cf10f43aa"}]}
ticket_start
ticket_scope
ticket_change
ticket_wake
ticket_done
ticket_Flow_0
ticket_Flow_0
ticket_Flow_1
ticket_Flow_1
ticket_Flow_2
ticket_Flow_2
ticket_Flow_3
ticket_Flow_3
Эта схема раскрывает только ветвь предполагаемой **неактивной** связи. Active-ветвь основного алгоритма пропускает soft_delete и закрывает Ticket напрямую.
Повторное чтение перед soft delete:
* **Нет связи:** no-op; затем handler пробует CLOSED.
* **Уже active:** исключение, старое решение о неактивности не разрешает удаление.
* **Неактивная связь существует:** выполнить scoped soft_delete; backend повторяет защиту под lock.
Для существующей неактивной связи POST ''dbsynce/api/handler/ticket/{ticket_id}/relationship/'' с ''action=soft_delete'' требует ''related.relationship.status'', текущий Ticket scope и единственную связь. Backend блокирует Ticket/Relationship и ещё раз отвергает удаление ''status=0''. Успех сохраняет ''status=2'' и Event. Это soft delete, а не физическое удаление строки.
Если связь стала active между проверками, запрос может завершиться ошибкой и общим retry. На следующем актуальном проходе главная active-ветвь сохранит связь и закроет только Ticket при соблюдении срока. Нельзя обходить backend guard ради завершения soft delete.
Soft delete и CLOSED подтверждать отдельно:
* первый запрос меняет статус Relationship и создаёт Event;
* второй запрос меняет статус Ticket и создаёт свой Event;
* между запросами может возникнуть ошибка;
* отсутствующая связь позволяет попытку CLOSED без успешного POST soft_delete.
Общего commit этих двух запросов нет. После сохранённого status=2 Ticket ещё может оставаться DECLINED. Стрелка между API-пулами описывает последовательность handler, а не прямой вызов одного endpoint другим.
===== Внешние действия и события =====
Текущий lifecycle для NEG_REQUEST DECLINED (459) допускает один исход:
* **CLOSED (451):** закрыть сопровождающий Ticket при разрешённом доступе.
Прямого возврата DECLINED → ACCEPTED в коде нет; прежнее упоминание исправлено. Доступ к карточке и право смены статуса проверяются отдельно. Само изменение Ticket не активирует Relationship.
Канонический backend публикует события после commit. ''ticket.moved'' исключает прежний локальный снимок, при занятом worker — через pending discard; ''ticket.changed'' будит владельца новой стадии, если он существует. Для CLOSED отдельного NEG handler нет. Потерю доставки восстанавливает scoped periodic reconciliation по ''INTERVAL_TIME_BD_REQ''. Ошибка списка не является подтверждением пустой очереди.
Отдельного ALERT о сохранении active Relationship в этой встроенной ветви нет. Для диагностики смотрят журнал и сохранённые состояния; участие в MUC-комнате не является подтверждением рассмотрения или командой изменить связь.
===== Ошибки и диагностика =====
^ Ситуация ^ Результат ^
| Grace ещё не истёк | ''declined_relationship_grace'', короткий defer до ближайшей проверки |
| Active после grace | Сохранить Relationship, запись журнала, закрыть только Ticket |
| Неактивная связь после grace | Soft delete status=2, затем отдельный CLOSED |
| Связь не найдена при повторном чтении | No-op удаления, затем попытка CLOSED |
| Ошибка read/soft-delete/перехода | ''processing_error'', ''DEFERRED_TICKET_RECHECK_SECONDS'' |
| 404 при переходе CLOSED | Запрос локальной очистки как при устаревшем scope |
Read по связи также может вернуть 404 при выходе Ticket из scope; несколько записей дают 409, а не произвольный выбор. Постоянное расхождение требует разбора данных/identity, а не только ожидания таймера.
Порядок диагностики:
- Прочитать отдельно Ticket.status и Relationship.status.
- Сверить текущие ревизию и updated_at, вычислить deadline.
- Для неактивной связи проверить Event soft delete.
- Отдельно проверить Event CLOSED.
- При неопределённом ответе перечитать сохранённые состояния до повтора.
Active Relationship вместе с CLOSED Ticket может быть штатным результатом. Это не доказательство удаления или деактивации связи.
===== Проверенные источники =====
Git SHA/SHA-256 и параметры моделей закреплены в metadata и documentation BPMN. Код handler при анализе не исполнялся; изменение источников требует повторного сопоставления.
* [[https://git.sharix-app.org/ShariX_Open/sharix-open-handlers-examples/src/commit/76e0c693b628ed4a1fa34515a3f8abdff26149bb/handlers/open_neg_request_declined.py|sharix-open-handlers-examples / handlers/open_neg_request_declined.py]] — Git 76e0c693b628ed4a1fa34515a3f8abdff26149bb.
* [[https://git.sharix-app.org/ShariX_Open/sharix-open-handlers-examples/src/commit/76e0c693b628ed4a1fa34515a3f8abdff26149bb/generated_handler_blocks/open_neg_request_declined.json|sharix-open-handlers-examples / generated_handler_blocks/open_neg_request_declined.json]] — Git 76e0c693b628ed4a1fa34515a3f8abdff26149bb.
* [[https://git.sharix-app.org/ShariX_Open/sharix-open-handlers-examples/src/commit/76e0c693b628ed4a1fa34515a3f8abdff26149bb/catalog.py|sharix-open-handlers-examples / catalog.py]] — Git 76e0c693b628ed4a1fa34515a3f8abdff26149bb.
* [[https://git.sharix-app.org/ShariX_Open/sharix-open-handlers-backend/src/commit/50baf376e224d915a87d63240f3f339b3dda9afa/core/blockly_runtime.py|sharix-open-handlers-backend / core/blockly_runtime.py]] — Git 50baf376e224d915a87d63240f3f339b3dda9afa.
* [[https://git.sharix-app.org/ShariX_Open/sharix-open-handlers-backend/src/commit/50baf376e224d915a87d63240f3f339b3dda9afa/core/handler_operations.py|sharix-open-handlers-backend / core/handler_operations.py]] — Git 50baf376e224d915a87d63240f3f339b3dda9afa.
* [[https://git.sharix-app.org/ShariX_Open/sharix-open-handlers-backend/src/commit/50baf376e224d915a87d63240f3f339b3dda9afa/core/ejabberd_muc.py|sharix-open-handlers-backend / core/ejabberd_muc.py]] — Git 50baf376e224d915a87d63240f3f339b3dda9afa.
* [[https://git.sharix-app.org/ShariX_Open/sharix-open-handlers-backend/src/commit/50baf376e224d915a87d63240f3f339b3dda9afa/core/requesters.py|sharix-open-handlers-backend / core/requesters.py]] — Git 50baf376e224d915a87d63240f3f339b3dda9afa.
* [[https://git.sharix-app.org/ShariX_Open/sharix-open-handlers-backend/src/commit/50baf376e224d915a87d63240f3f339b3dda9afa/ticket_blockly_codegen.py|sharix-open-handlers-backend / ticket_blockly_codegen.py]] — Git 50baf376e224d915a87d63240f3f339b3dda9afa.
* [[https://git.sharix-app.org/ShariX_Open/sharix-open-handlers-backend/src/commit/50baf376e224d915a87d63240f3f339b3dda9afa/ticket_codegen_contract.json|sharix-open-handlers-backend / ticket_codegen_contract.json]] — Git 50baf376e224d915a87d63240f3f339b3dda9afa.
* [[https://git.sharix-app.org/ShariX_Open/sharix-open-tickets/src/commit/fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14/lib/tickets.py|sharix-open-tickets / lib/tickets.py]] — Git fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14.
* [[https://git.sharix-app.org/ShariX_Open/sharix-open-tickets/src/commit/fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14/api/views/handler_workflow.py|sharix-open-tickets / api/views/handler_workflow.py]] — Git fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14.
* [[https://git.sharix-app.org/ShariX_Open/sharix-open-tickets/src/commit/fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14/api/handler_auth.py|sharix-open-tickets / api/handler_auth.py]] — Git fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14.
* [[https://git.sharix-app.org/ShariX_Open/sharix-open-tickets/src/commit/fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14/utils.py|sharix-open-tickets / utils.py]] — Git fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14.
* [[https://git.sharix-app.org/ShariX_Open/sharix-open-tickets/src/commit/fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14/views/ticket_detail.py|sharix-open-tickets / views/ticket_detail.py]] — Git fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14.
* [[https://git.sharix-app.org/ShariX_Open/sharix-open-tickets/src/commit/fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14/signals.py|sharix-open-tickets / signals.py]] — Git fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14.
* [[https://git.sharix-app.org/ShariX_Open/sharix-open-tickets/src/commit/fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14/services/handler_wakeup.py|sharix-open-tickets / services/handler_wakeup.py]] — Git fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14.
* [[https://git.sharix-app.org/ShariX_Open/sharix-open-backend/src/commit/778a3280cee115ba0efe3fdff7b0e708b0c10093/apiviews/handler_workflow.py|sharix-open-backend / apiviews/handler_workflow.py]] — Git 778a3280cee115ba0efe3fdff7b0e708b0c10093.
* [[https://git.sharix-app.org/ShariX_Open/sharix-open-backend/src/commit/778a3280cee115ba0efe3fdff7b0e708b0c10093/lib/dicts.py|sharix-open-backend / lib/dicts.py]] — Git 778a3280cee115ba0efe3fdff7b0e708b0c10093.
* [[https://git.sharix-app.org/ShariX_Open/sharix-open-backend/src/commit/778a3280cee115ba0efe3fdff7b0e708b0c10093/models/relationship.py|sharix-open-backend / models/relationship.py]] — Git 778a3280cee115ba0efe3fdff7b0e708b0c10093.
===== Связанные материалы =====
* [[sharixopen:knowledge:scenarios:neg_request_pending|NEG/PENDING]]
* [[sharixopen:knowledge:scenarios:neg_request_accepted|NEG/ACCEPTED]]
* [[sharixopen:knowledge:scenarios:access_request_declined|ACCESS/DECLINED: отличающаяся политика active]]
* [[sharixopen:knowledge:scenarios:start|Все сценарии]]
~~SHARIX_KNOWLEDGE_RELATED~~