| |
| sharixopen:knowledge:scenarios:service_request_pending [2026/10/28 20:56] – [sharixknowledge] approved package sx_knowledge_api_open | sharixopen:knowledge:scenarios:service_request_pending [2026/10/31 14:26] (текущий) – [sharixknowledge] approved package sx_knowledge_api_open |
|---|
| "ShariXKnowledgeOpenKnowledgeModulesHandlers", | "ShariXKnowledgeOpenKnowledgeModulesHandlers", |
| "ShariXKnowledgeScenarios" | "ShariXKnowledgeScenarios" |
| | ], |
| | "depends_on": [ |
| | "ShariXKnowledgeOpenKnowledgeModulesHandlers", |
| | "ShariXKnowledgeOpenKnowledgeModulesBackenddbsynce" |
| | ], |
| | "verified_by": [ |
| | "ShariXKnowledgeVerification" |
| ] | ] |
| }, | }, |
| "domain": "business_processes", | "domain": "business_processes", |
| "lifecycle": "implemented", | "lifecycle": "implemented", |
| "component": "handlers", | "component": "handlers_examples, handlers_backend, dbsynce", |
| "parents": [ | "parents": [ |
| "ShariXKnowledgeScenarios" | "ShariXKnowledgeScenarios" |
| ], | ], |
| "terms": [ | "terms": [ |
| "SERVICE_REQUEST", | "audience_developer", |
| "PENDING", | "audience_integrator", |
| "provider matching", | "audience_support", |
| "BPMN" | "audience_reviewer", |
| | "audience_ai", |
| | "product_sharix_open", |
| | "material_scenario", |
| | "topic_orders_assignment", |
| | "topic_orders_lifecycle", |
| | "topic_handlers_runtime", |
| | "service_request", |
| | "ticket_pending", |
| | "provider_offer", |
| | "order_round", |
| | "candidate_batch", |
| | "matching_cursor", |
| | "bpmn", |
| | "order", |
| | "ticket", |
| | "blockly", |
| | "generated_python" |
| ] | ] |
| }, | }, |
| "round": "d6ce0c03d3a803364f441d404a510049b35b8c27783c177c34b93113d0f13f0a" | "round": "d6ce0c03d3a803364f441d404a510049b35b8c27783c177c34b93113d0f13f0a" |
| } | } |
| | }, |
| | "classification": { |
| | "schema": "sharix.knowledge.classification.v1", |
| | "products": [ |
| | "sharix_open" |
| | ], |
| | "audiences": [ |
| | "developer", |
| | "integrator", |
| | "support", |
| | "reviewer", |
| | "ai" |
| | ], |
| | "material": "scenario", |
| | "topics": [ |
| | "orders/assignment", |
| | "orders/lifecycle", |
| | "handlers/runtime" |
| | ], |
| | "tag_terms": [ |
| | "audience_developer", |
| | "audience_integrator", |
| | "audience_support", |
| | "audience_reviewer", |
| | "audience_ai", |
| | "product_sharix_open", |
| | "material_scenario", |
| | "topic_orders_assignment", |
| | "topic_orders_lifecycle", |
| | "topic_handlers_runtime", |
| | "service_request", |
| | "ticket_pending", |
| | "provider_offer", |
| | "order_round", |
| | "candidate_batch", |
| | "matching_cursor", |
| | "bpmn", |
| | "order", |
| | "ticket", |
| | "blockly", |
| | "generated_python" |
| | ], |
| | "registry_document": "ShariXKnowledgeClassification", |
| | "state_meaning": "implemented — описана проверенная реализация исходников; серверный runtime отдельно; review — состояние текста" |
| | }, |
| | "editorial_review": { |
| | "date": "2026-10-31", |
| | "scope": "Конкретизация действий, условий, результатов и диагностики; перечисления; исходные BPMN сохранены", |
| | "current_source_records_verified": 27, |
| | "original_source_evidence_recheck": "После git fetch все исходные commits/SHA-256 совпали; дополнительные функциональные источники включены в source_evidence", |
| | "canonical_regeneration": { |
| | "kind": "ticket", |
| | "compared_python_paths": [ |
| | "handlers/open_service_request_pending.py", |
| | "generated_handlers/open_service_request_pending.py" |
| | ], |
| | "generator_sources_verified": 11, |
| | "handler_executed": false |
| | }, |
| | "runtime_checked": false, |
| | "clarification": "Повтор PENDING может использовать cached context; новый GET не гарантируется на каждом проходе; новая authoritative revision и processing_error очищают кэш" |
| } | } |
| }, | }, |
| "content_sha256": "54a1db3ac1b5fc814290e7430b57a43f44bfca8e256f95a195a82cb5221809e8", | "content_sha256": "f11c3292b45e3ab672b8e936cc749fa6d2d38ebd949e17425023043d66b89bed", |
| "schema": 1 | "schema": 1 |
| } | } |
| ~~NOCACHE~~ | ~~NOCACHE~~ |
| |
| **Область:** ShariX Open. **Обработчик:** ''open_service_request_pending'', тип ''SERVICE_REQUEST'' (2), статус ''PENDING''. Опубликованный 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#integrator|Интегратор]] · [[sharixopen:knowledge:classification:audiences#podderzhka|Поддержка]] · [[sharixopen:knowledge:classification:audiences#recenzent_i_prijomschik|Рецензент и приёмщик]] · [[sharixopen:knowledge:classification:audiences#nejroset|Нейросеть]]. |
| | |
| | **Темы:** [[sharixopen:knowledge:classification:topics#naznachenie|Заказы → Назначение]] · [[sharixopen:knowledge:classification:topics#zhiznennyj_cikl|Заказы → Жизненный цикл]] · [[sharixopen:knowledge:classification:topics#runtime|Обработчики → Runtime]]. |
| | |
| | |
| | |
| | **Область:** ShariX Open. **Обработчик:** ''open_service_request_pending'', тип ''SERVICE_REQUEST'' (2), статус ''PENDING''. 31.10.2026 исходники повторно получены из Git. Обе Python-копии совпали с новой канонической генерацией Blockly; проверены 11 исходников генераторов. Сам обработчик и его внешние действия не запускались. Выбранная версия и работающая установка проверяются отдельно. |
| |
| ===== Назначение и границы ===== | ===== Назначение и границы ===== |
| Обработчик ищет исполнителя для заказа без назначенного provider. Backend возвращает одну допустимую партию; runtime отправляет предложения параллельно и выбирает первый допустимый положительный ответ. Затем отдельный канонический backend action проверяет возможность назначения и сохраняет provider вместе с переходом **PENDING→ACCEPTED**. Согласие участника само по себе не переводит заказ в ASSIGNED или PRE_START. | Подбор для заказа без provider: |
| | |
| | - Получить от backend допустимую партию. |
| | - Параллельно отправить предложения. |
| | - Выбрать первый допустимый положительный ответ в раунде. |
| | - Отдельным backend action повторить проверки, сохранить provider и PENDING → ACCEPTED. |
| | |
| | Согласие участника само по себе не переводит заказ в ASSIGNED или PRE_START. |
| |
| Схемы BPMN описательные, ''isExecutable=false''. Исполняется проверенный Python, сгенерированный из Blockly; Wiki не исполняет XML и не заменяет runtime. Внешний человек, доставка сообщений, API и таймеры показаны отдельно от бизнес-решения. | Схемы BPMN описательные, ''isExecutable=false''. Исполняется проверенный Python, сгенерированный из Blockly; Wiki не исполняет XML и не заменяет runtime. Внешний человек, доставка сообщений, API и таймеры показаны отдельно от бизнес-решения. |
| </sharix-bpmn> | </sharix-bpmn> |
| |
| После проверки своего статуса и scoped order context записывается локальная причина ''provider_matching_batch''. Чужой статус запрашивает очистку Ticket и комнаты. 404 scoped context очищает устаревшее локальное состояние; отсутствие/неоднозначность связанного Orders — ошибка API, а не пустой список кандидатов. | В начале processing: |
| | |
| | * проверяется рабочий PENDING; |
| | * берётся current_service_request_order_context, а при отсутствии кэша загружается scoped context; |
| | * записывается provider_matching_batch; |
| | * чужой статус запрашивает очистку Ticket/комнаты; |
| | * 404 context очищает устаревший scope, отсутствие/неоднозначность Orders даёт ошибку API. |
| | |
| | Новый GET не гарантируется на каждом повторе. Кэш очищается, в частности, при новой ревизии/смене статуса authoritative Ticket, processing_error и уборке локального состояния. При изменении дат/заказа важно проверить, какой context и ревизию использует текущая очередь. |
| |
| Сначала проверяется общий предел поиска: для ASAP — ''asap_deadline'', для планового заказа — ''pre_start_at''. Если срок наступил, handler пробует ''move-pending-to-pre-forcemajeur''. При успехе/stale текущая очередь освобождается. При обработанном отрицательном результате выполнение проходит дальше; исключение API прерывает проход и попадает в общий defer. | Сначала проверяется общий предел поиска: для ASAP — ''asap_deadline'', для планового заказа — ''pre_start_at''. Если срок наступил, handler пробует ''move-pending-to-pre-forcemajeur''. При успехе/stale текущая очередь освобождается. При обработанном отрицательном результате выполнение проходит дальше; исключение API прерывает проход и попадает в общий defer. |
| Scoped ''order.candidates'' доступен handler текущего PENDING. Размер партии задаёт **backend** через ''SERVICE_REQUEST_PENDING_BATCH_SIZE''. Параметры cycle/batch/request/TTL в ответе не означают, что backend сохраняет раунды или резервирует кандидатов. | Scoped ''order.candidates'' доступен handler текущего PENDING. Размер партии задаёт **backend** через ''SERVICE_REQUEST_PENDING_BATCH_SIZE''. Параметры cycle/batch/request/TTL в ответе не означают, что backend сохраняет раунды или резервирует кандидатов. |
| |
| Локальный подбор последовательно учитывает услугу и компанию, активность Provider и пользователя, роль ''METASERVICE-PROVIDER'', ресурсные и иные hard eligibility-условия, конфликтующие активные заказы, доступность и корректный JID. До ограничения размера партии остаётся один приоритетный Provider на bare JID, чтобы несколько старых записей одного пользователя не заняли всю партию. | Локальный подбор учитывает: |
| | |
| | * услугу и компанию; |
| | * активность Provider и пользователя; |
| | * роль METASERVICE-PROVIDER; |
| | * ресурсные и другие hard eligibility-условия; |
| | * конфликтующие активные заказы; |
| | * доступность и корректный JID. |
| | |
| | До ограничения размера партии остаётся один приоритетный Provider на bare JID. Несколько старых предложений одного пользователя не должны занимать всю партию. |
| |
| Для ASAP сначала идут непосредственные online-предложения, затем gap-предложения по меньшему оставшемуся ожиданию. В одной ASAP-партии не смешиваются разные dispatch groups. Для планового заказа gap допустим, если исполнитель сможет быть готов не позднее ''time_start''. | Для ASAP сначала идут непосредственные online-предложения, затем gap-предложения по меньшему оставшемуся ожиданию. В одной ASAP-партии не смешиваются разные dispatch groups. Для планового заказа gap допустим, если исполнитель сможет быть готов не позднее ''time_start''. |
| |
| ==== Необязательное ранжирование Platform ==== | ==== Необязательное внешнее ранжирование ==== |
| Публичный integration port может получить порядок кандидатов от Platform. Это подсказка порядка, не разрешение исполнителю и не lease доступности. После попытки внешнего HTTP локальный набор строится заново. Неизвестные, чужие по метасервису или уже недопустимые provider id не становятся допустимыми из-за удалённого ответа. Для ASAP сохраняется порядок локальных dispatch groups; при недоступном/неподходящем ranking действует локальный порядок. Внутренний алгоритм Platform этой страницей не описывается. | Публичный порт может получить порядок кандидатов от подключённого внешнего провайдера: |
| | |
| | * ответ уточняет порядок, но не выдаёт исполнителю разрешение и не резервирует доступность; |
| | * после внешнего HTTP локальный набор строится заново; |
| | * неизвестные, чужие по метасервису и уже недопустимые provider id отбрасываются; |
| | * для ASAP сохраняется порядок локальных dispatch groups; |
| | * при недоступном/неподходящем ranking используется локальный порядок. |
| | |
| | Метка Platform на границе BPMN обозначает внешнего участника. Внутренние алгоритмы закрытого компонента уточняют у ответственных за Platform; здесь описан только публичный контракт ShariX Open. |
| |
| ==== Партии и циклы ==== | ==== Партии и циклы ==== |
| Runtime хранит ''after_provider_id'', номер партии, цикл и ''has_more''. После исчерпания списка начинается новый цикл с нулевым cursor. Если cursor исчез из текущего допустимого порядка, backend возвращает пустой хвост; runtime сбрасывает его и может сделать один дополнительный запрос с начала. Пустой начальный список ведёт к ожиданию RECHECK. | Состояние обхода партий: |
| | |
| | * after_provider_id — cursor; |
| | * номер партии; |
| | * номер цикла; |
| | * has_more — признак продолжения списка. |
| | |
| | После исчерпания списка начинается новый цикл с нулевым cursor. Исчезнувший из допустимого порядка cursor даёт пустой хвост: runtime сбрасывает его и может сделать один дополнительный запрос с начала. Пустой начальный список означает RECHECK. |
| |
| Для непустой партии runtime создаёт новые offer UUID и общий ''expires_at = now + OFFER_TTL''. Cursor и цикл находятся в памяти процесса; отказ от завершённого раунда их не сбрасывает, а рестарт/full cleanup — сбрасывает. Это не постоянный журнал уже уведомлённых исполнителей и не гарантия отсутствия повторных предложений после рестарта. | Для непустой партии runtime создаёт новые offer UUID и общий ''expires_at = now + OFFER_TTL''. Cursor и цикл находятся в памяти процесса; отказ от завершённого раунда их не сбрасывает, а рестарт/full cleanup — сбрасывает. Это не постоянный журнал уже уведомлённых исполнителей и не гарантия отсутствия повторных предложений после рестарта. |
| |
| ==== Повторные backend-проверки ==== | ==== Повторные backend-проверки ==== |
| ''accept-pending-provider'' под блокировкой актуального заказа требует PENDING и отсутствие текущего provider, существование кандидата, hard eligibility, отсутствие конфликтующего активного заказа и готовность обязательных проверок выбранного исполнителя. Подготовка requirements может создать недостающие действия и вернуть ''requirements_pending'', не назначая исполнителя. | Accept-pending-provider под lock проверяет: |
| | |
| | * текущий PENDING и отсутствие уже назначенного provider; |
| | * существование кандидата и hard eligibility; |
| | * отсутствие конфликтующего активного заказа; |
| | * готовность обязательных проверок выбранного исполнителя. |
| | |
| | Подготовка требований может создать недостающие действия и вернуть requirements_pending без назначения. Это не положительный результат по одному winner раунда. |
| |
| При успехе provider сохраняется и выполняется канонический переход ACCEPTED; неуспешный переход очищает только что назначенный provider. Этот action не повторяет буквально весь availability/online-фильтр подбора и не проверяет общий deadline: нельзя приписывать ему такие гарантии. Общий срок проверяет runtime. | При успехе provider сохраняется и выполняется канонический переход ACCEPTED; неуспешный переход очищает только что назначенный provider. Этот action не повторяет буквально весь availability/online-фильтр подбора и не проверяет общий deadline: нельзя приписывать ему такие гарантии. Общий срок проверяет runtime. |
| |
| ===== Диагностика и восстановление ===== | ===== Диагностика и восстановление ===== |
| Разделяйте отсутствие допустимых кандидатов, отсутствие JID, send failure, timeout, отклонение ответа и отказ backend назначить уже выбранного победителя. Для проверки нужны текущие Orders/Ticket/provider, timing context, cursor/cycle/round outcome, capabilities и ответ канонического action. Локальная причина ''provider_matching_batch'' сама по себе не доказывает успешную рассылку. | Порядок диагностики: |
| | |
| | - Прочитать текущие Orders/Ticket/provider и используемый timing context. |
| | - Проверить допустимых кандидатов и их JID. |
| | - Сверить cursor/cycle, TTL партии и общий deadline поиска. |
| | - Разделить send failure, timeout, отклонение ответа и winner. |
| | - Прочитать capabilities и ответ назначения уже выбранного победителя. |
| | |
| | Provider_matching_batch — локальная причина, не доказательство успешной рассылки. При неопределённом ответе назначения сначала перечитать каноническое состояние. |
| |
| API 401/403/5xx и транспортные исключения не равны отказу человека и идут в ''processing_error'' с ''DEFERRED_TICKET_RECHECK_SECONDS''. При 404 scope runtime освобождает устаревшее локальное состояние. После сохранённого перехода нового владельца будит ''ticket.changed'', прежний получает ''ticket.moved''; periodic reconciliation по ''INTERVAL_TIME_BD_REQ'' восстанавливает состав при потере события. Не исправляйте расхождение повторной ручной отправкой старого offer id. | API 401/403/5xx и транспортные исключения не равны отказу человека и идут в ''processing_error'' с ''DEFERRED_TICKET_RECHECK_SECONDS''. При 404 scope runtime освобождает устаревшее локальное состояние. После сохранённого перехода нового владельца будит ''ticket.changed'', прежний получает ''ticket.moved''; periodic reconciliation по ''INTERVAL_TIME_BD_REQ'' восстанавливает состав при потере события. Не исправляйте расхождение повторной ручной отправкой старого offer id. |