Предодобренный овердрафт (T22)¶
preapproval.py раз в сутки считает для каждого клиента банка «Вам доступно до X»: овердрафт на 12 месяцев без залога (SPEC §4, §6 этап 0). Это «быстрая полоса» для микробизнеса. Сумму показывает баннер на главной кабинета (T29).
Предодобрение — мягкое предложение. Клиент всё равно подаёт заявку, и она рассчитывается заново на данных того дня (WORKFLOW.md). Если данные не изменились, заявка на овердрафт на предодобренную сумму получает автоматическое предложение с той же суммой и ставкой. Это проверяет тест.
Как считается¶
Для каждого клиента проходят те же этапы, что у заявки, но без заявки:
- Обогащение — тот же
enrichи те же адаптеры (T07). Запрос к БКИ идёт по согласию, которое клиент дал при открытии счёта (см. «Упрощения»). - Качество данных —
data_quality(...)без заявленной выручки. Подходит толькоFULL(SPEC §5.1). Если у компании нет выручки в ФНС, покрытие выручки посчитать не с чем, уровень будетTHIN, и предодобрения она не получит. - Стоп-факторы и флаги (T14) — их не должно быть ни одного. Быстрая полоса только для чистого автоматического маршрута.
- Скоринг — только основная модель (T15), модель-претендент не считается.
- Лимит и ставка —
quote(cf, score, OVERDRAFT, 12, Route.AUTO, requested=None)(T16,LIMITS.md). Запрошенной суммы нет, поэтому лимит — минимум из потока, оборотов (50% средних поступлений), долговой нагрузки и максимума продукта, округлённый вниз до 10 000 ₽. - Маршрут этой суммы по матрице полномочий (T18) должен быть
auto. Например, грейд D уходит к андеррайтеру, предодобрения нет.
preapprove(...) — чистая функция: одинаковые входы дают одинаковый результат.
Результат: PreApproval¶
Это не контракт (contracts.py не менялся), его производит только этот модуль.
| Поле | Что |
|---|---|
approved |
Есть ли предодобрение |
amount, rate, binding |
Сумма, ставка и ограничение, которое задало сумму. Без предодобрения — null |
grade, data_quality_tier, model_version, policy_version |
На чём построено |
reasons |
Одна причина: почему нет, или определяющее ограничение лимита |
as_of, computed_at, valid_until |
Дата данных, время расчёта, срок действия (30 дней) |
Коды причин отказа: preapproval_company_not_found, preapproval_source_unavailable, preapproval_data_partial, preapproval_data_thin, preapproval_stop_factor, preapproval_flag, preapproval_not_scored, preapproval_below_product_minimum, preapproval_rate_above_cap, preapproval_not_auto, preapproval_expired. Для предодобрения — preapproval_limit_<ограничение>.
Хранение и запуск¶
- Таблица
preapprovals(миграция0006_preapprovals): одна строка на ИНН с последним результатом. Каждый запуск заменяет строку. - Worker (
worker.py) раз в 0,5 с вызываетpreapproval.tick(). Если последнему расчёту больше суток, расчёт запускается в отдельном потоке, и очередь заявок его не ждёт. Упавший расчёт повторяется не чаще раза в час. - Вручную:
python -m apps.api.preapprovalилиPOST /api/v2/staff/preapproval/run. - На синтетическом мире (зерно 7, 1500 компаний) расчёт идёт около 2 с. Предодобрение получают 16% клиентов (238), медианная сумма — 350 тыс. ₽. Чаще всего предодобрения нет из-за лимита ниже минимума продукта: в мире тонкая маржа (
LIMITS.md, «Что видно на синтетическом мире»). Следом идут уровниPARTIAL/THINи флаги.
API¶
| Метод | Кто | Что |
|---|---|---|
GET /api/v2/preapproval?inn=… |
клиент | Для баннера: {"product", "term_months", "amount", "rate", "valid_until", "client_text"} или null, если предодобрения нет или срок прошёл |
GET /api/v2/preapproval?inn=… |
сотрудник | Весь PreApproval, в том числе причина отказа |
POST /api/v2/staff/preapproval/run |
сотрудник | Запустить расчёт сейчас (202): {"started", "last_run"}. started: false — расчёт уже идёт |
Упрощения¶
# MOCK:согласие на запрос в БКИ (218-ФЗ) считается данным при открытии счёта: за компанию и за основного собственника по ЕГРЮЛ. В банке есть реестр согласий со своими датами и объёмом. Заявка всё равно собирает согласия сама (T25).# MOCK:клиентская база — весь синтетический мир: у каждой компании есть счёт в банке.# MOCK:расчёт опрашивает источники по каждому клиенту, как заявка, только без имитации задержки. Настоящий пакетный расчёт читает хранилище данных банка и пакетный файл из БКИ. Так у заявок и предодобрения один путь в коде.# SIMPLIFICATION:собственник для согласия берётся из повторного запроса в ЕГРЮЛ. В банке он есть в реестре согласий.# SIMPLIFICATION:«ночной» расчёт — это «последний расчёт старше суток», его проверяет worker внутри процесса API. В банке расчёт ставит планировщик заданий на ночь.# SIMPLIFICATION:срок действия (30 дней) и период расчёта — константы в коде, как значения предложений T17.# SIMPLIFICATION:хранится только последний результат по ИНН, без истории расчётов.# SIMPLIFICATION:любой вошедший клиент может спросить предодобрение по любому ИНН, как и подать заявку: связи «пользователь → компания» пока нет (T25).