# Route Executor Contracts ## 1. Общий контракт Каждый route executor возвращает результат в unified-формате: ```json { "fragment_id": "F1", "route": "store_feature_risk", "status": "ok | empty | partial | error", "result_type": "list | summary | object | chain | ranking", "items": [], "summary": {}, "evidence": [], "errors": [] } ``` Реализация: - raw execution: `backend/src/services/assistantDataLayer.ts` - normalizer: `backend/src/services/retrievalResultNormalizer.ts` ## 2. Вход executor’ов Вызов выполняется через: `executeRoute(route: string, fragmentText: string)` Входы: - `route`: выбранный маршрут из route planner. - `fragmentText`: текст фрагмента после нормализации/декомпозиции. Источник данных текущего MVP: - snapshot-пакет `docs/ARCH/2020экспорт/*.json` ## 3. Route: `hybrid_store_plus_live` Назначение: - causal/cross-entity цепочки; - связь документов с контрагентами; - поиск разрывов связности. Result: - `result_type = "chain"` - `items`: агрегаты по контрагенту (`operations_count`, `document_refs_count`, `relation_types`, `samples`) - `summary`: `checked_records`, `matched_counterparties`, `route_focus` ## 4. Route: `store_feature_risk` Назначение: - anomaly/rule-check; - риск-признаки в проблемных записях. Result: - `result_type = "list"` - `items`: записи с `risk_score`, `reasons`, техническими индикаторами - `summary`: `checked_records`, `risky_records`, `average_risk_score` ## 5. Route: `batch_refresh_then_store` Назначение: - обзорные и ranking-задачи; - top/приоритизация проверки. Result: - `result_type = "ranking"` - `items`: `rank`, `entity`, `records_count` - `summary`: `checked_records`, `ranked_entities` ## 6. Route: `store_canonical` Назначение: - канонический factual path по документам. Result: - `result_type = "list"` - `items`: документные записи (`source_entity`, `source_id`, `period`, `counterparty_id`, `recorder`) - `summary`: `checked_records`, `returned_records` ## 7. Route: `live_mcp_drilldown` Назначение: - точечный drilldown по GUID/объекту. Result: - `result_type = "object"` - `items`: найденные совпадения по GUID - `summary`: `query_guids`, `matched_records` ## 8. Ошибки и no-route Если fragment получает `route=no_route`, backend не вызывает executor, а формирует skipped-result: - `status = "empty"` - `result_type = "summary"` - `summary.skipped = true` - `summary.no_route_reason` Если executor падает: - `status = "error"` - `errors[]` содержит текст ошибки.