Перейти к содержанию

Маршрутизация по матрице полномочий (T18)

routing.py решает, кто принимает решение по заявке: автоматика, андеррайтер или комитет (SPEC §11). Маршрут нужен дважды: он попадает в Decision.route и задаёт стоимость обработки в цене каждого предложения (LIMITS.md, OFFERS.md).

route_application(amount, grade=..., flags=..., data_quality=..., stop_factors=..., unavailable_sources=...) -> Routing
route_for(grade, flags, data_quality) -> RouteFor  # amount -> Route, для generate_offers
  • grade — грейд основной модели (Scoring.score.grade). Грейд модели-претендента в маршрут не входит. None — скоринг отказался считать признаки (FeatureSetMismatch, SCORING.md).
  • flags, stop_factors — из evaluate_stop_factors (T14, STOP_FACTORS.md).
  • data_quality — из того же вызова, что и лимит (T09).
  • unavailable_sources — Enrichment.unavailable_required (T07).

Routing содержит маршрут, причины (Decision.route_reasons) и маршрут, которого требует каждая причина (routes, в том же порядке).

Матрица

Проверки идут по порядку:

  1. Стоп-фактор → auto, причина route_stop_factor. Отказ автоматический, остальные условия не важны.
  2. Обязательный источник недоступен после всех повторов → underwriter, причина route_source_unavailable со списком источников.
  3. Иначе каждое сработавшее условие даёт свою причину, маршрут — самый строгий из них:
Условие Маршрут Код
Сумма больше 15 млн ₽ комитет route_amount_over_15m
Сумма больше 5 млн ₽ (до 15 млн ₽) андеррайтер route_amount_over_5m
Грейд D или E и сумма больше 5 млн ₽ комитет route_grade_over_5m
Грейд D или E андеррайтер route_grade
Скоринг не рассчитан андеррайтер route_score_unavailable
Каждый флаг T14 андеррайтер route_flag_<код флага>
Данные THIN андеррайтер route_data_thin
Данные PARTIAL и сумма больше 1 млн ₽ андеррайтер route_data_partial_over_1m
Качество данных не рассчитано андеррайтер route_data_quality_missing
Лимит и качество данных учитывают выписки других банков (T23) андеррайтер route_statement_upload

Если ничего не сработало — auto с причиной route_auto («Грейд B, флагов нет, данные FULL, сумма до 5 млн ₽»). Границы включительные: 5 млн ₽ при данных FULL — ещё автомат, 15 млн ₽ — ещё андеррайтер.

Выписка из другого банка — документ клиента, он надёжнее заявленного, но менее надёжен, чем наши данные и госисточники (SPEC §5.1). Поэтому заявку, в которой выписка повлияла на уровень данных и лимит, всегда проверяет андеррайтер, даже если с выпиской данные стали FULL (STATEMENTS.md).

Грейд E в SPEC §11 не упомянут; он маршрутизируется как D. На практике у грейда E ставка обычно выше потолка 30%, и предложений нет.

Тексты

  • Сотрудник видит в staff_text каждое условие с числами. У флага — Флаг: и текст самого флага, код флага сохранён в коде причины.
  • Клиент видит в client_text только то, кто и как долго рассматривает заявку: «Заявку проверит специалист банка — обычно в течение рабочего дня», «Заявку рассмотрит кредитный комитет банка — обычно до 2 рабочих дней». Текст флага клиенту не показываем (например, транзитные операции относятся к ПОД/ФТ); клиентский текст флага остаётся в Decision.flags.
  • Причины по качеству данных показывают клиенту DataQuality.client_message («мы видим только часть оборотов вашего бизнеса»).
  • Одинаковые клиентские тексты повторяются у нескольких причин; интерфейс показывает их без повторов.

Срок рассмотрения андеррайтером по SPEC §6 — 4 рабочих часа для микробизнеса и 1 день для малого. Сегмент маршрутизация не знает, поэтому клиенту обещаем рабочий день.

Маршрут предложений

route_for замыкает грейд, флаги и уровень данных одной заявки и возвращает маршрут любой суммы. Генератор предложений считает по нему стоимость обработки каждого варианта: при данных PARTIAL предложение на 1 млн ₽ идёт автоматически (3 тыс. ₽), а на 1,2 млн ₽ — андеррайтеру (25 тыс. ₽).

Упрощения

  • # SIMPLIFICATION: пороги матрицы (1, 5 и 15 млн ₽, грейды A–C) — константы RoutingPolicy в коде, а не config/. В реальном банке матрица полномочий — нормативный документ кредитной политики с версиями; её перенос в config/credit_policy.json — отдельный PR в общую папку (docs/v2/NOTES.md, Unassigned). RoutingPolicy можно передать параметром, например в симулятор политики (T36).
  • Комитет — это две подписи: андеррайтер и риск-менеджер (SPEC §15); подписи собирает T20.
  • Сегмент (микро / малый) в маршруте не учитывается: SPEC §11 задаёт матрицу только по сумме, грейду, флагам и данным.