# 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[]` содержит текст ошибки.
