Files
portal/app/config/autopodbor.php
T
Дмитрий 06fc4680f4 feat(autopodbor): кэш отрисованных карточек 2ГИС/Яндекс за тумблером
CachingPageFetcher — декоратор над загрузчиком карточек (SelfRenderClient/
XfetchClient): кэширует в общем Cache (Redis/file) по ключу URL на N дней ТОЛЬКО
карточки (/firm/ 2ГИС, /maps/org/ Яндекс). Поиск (/search/) и ленты — всегда мимо
кэша (свежее добывание новых фирм). Пустое не кэшируем — разовый сбой не отравит кэш.

Кэш ОБЩИЙ для шага 1 (поиск) и шага 2 (изучение+разворот) и повторных прогонов:
ключ по URL → любые экземпляры делят один кэш. Вшит в AutopodborServiceProvider
через wrapCache(); 2ГИС-база RoutingBatchFetcher и self-render card reader обёрнуты,
яндекс-Playwright/ленты — нет.

Флаг AUTOPODBOR_RENDER_CACHE (ВЫКЛ по умолчанию) + render_cache_ttl_days (5).
TDD: 8 тестов CachingPageFetcher + 4 теста проводки — зелёные. Живой замер ДСК:
тёплый прогон — 26 карточек из кэша, 0 обращений к 2ГИС/Яндексу, источников 11=11.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 10:52:14 +03:00

113 lines
7.3 KiB
PHP

<?php
return [
/*
|--------------------------------------------------------------------------
| Живой движок поиска конкурентов (шаг 1)
|--------------------------------------------------------------------------
|
| true → findCompetitors использует НАСТОЯЩИЙ движок (ниша → поиск 2ГИС/Яндекс →
| резолв → сборка). false → демо-заглушка FakeCompetitorAgent. По умолчанию ВЫКЛ —
| включается осознанно (локально/за тумблером), т.к. ходит в живые сервисы.
|
*/
'real_find' => env('AUTOPODBOR_REAL_FIND', false),
/*
|--------------------------------------------------------------------------
| Путь к бинарнику node для Playwright-скриптов
|--------------------------------------------------------------------------
|
| Из-под PHP-процесса (очередь, artisan) PATH может отличаться от интерактивного
| шелла. Если 'node' по PATH не находится — пропишите абсолютный путь в .env:
| AUTOPODBOR_NODE_BIN="C:\Program Files\nodejs\node.exe"
|
*/
'node_bin' => env('AUTOPODBOR_NODE_BIN', 'node'),
/*
|--------------------------------------------------------------------------
| Глубокий шаг 2 (движок «глобального сбора источников»)
|--------------------------------------------------------------------------
|
| true → studyCompetitor сам доищет след (EXA → площадки → якорный фильтр →
| 2ГИС по имени → Яндекс Playwright). false → старый путь по site_url +
| directory_urls из шага 1. По умолчанию ВЫКЛ — включается осознанно.
|
*/
'deep_study' => env('AUTOPODBOR_DEEP_STUDY', false),
/*
|--------------------------------------------------------------------------
| Разворот по телефонам (сайты проектов застройщика)
|--------------------------------------------------------------------------
|
| true → на шаге 2 по каждому личному телефону фирмы делаем обратный поиск в
| 2ГИС и вскрываем связанные карточки (проекты холдинга): забираем их сайты и
| телефоны, цепочкой. Общие номера (у многих фирм) пропускаем. Требует deep_study.
| По умолчанию ВЫКЛ — включается осознанно (ходит в живой 2ГИС).
|
*/
'phone_reverse' => env('AUTOPODBOR_PHONE_REVERSE', false),
/*
|--------------------------------------------------------------------------
| Разворот по телефонам в Яндекс.Картах (рядом с 2ГИС)
|--------------------------------------------------------------------------
|
| true → на шаге 2 номера фирмы разворачиваем ещё и в Яндексе (для застройщиков,
| которые только в Яндексе). Каждая карточка-кандидат открывается и номер на ней
| проверяется (Яндекс отдаёт рыхлый список). Требует phone_reverse. По умолчанию ВЫКЛ.
|
*/
'phone_reverse_yandex' => env('AUTOPODBOR_PHONE_REVERSE_YANDEX', false),
/*
|--------------------------------------------------------------------------
| Параллельный разворот: 2ГИС и Яндекс одновременно
|--------------------------------------------------------------------------
|
| true → 2ГИС-разворот и Яндекс-разворот запускаются РАЗОМ (двумя процессами,
| Concurrency), итог по времени = max(2ГИС, Яндекс), а не сумма. Оба источника
| отрабатывают полностью — ничего не режется. false → последовательный композит.
| Безопасно: два разных провайдера, каждый одно-поточный, виртуалка держит потолок.
| Требует phone_reverse_yandex. По умолчанию ВЫКЛ.
|
*/
'phone_reverse_parallel' => env('AUTOPODBOR_PHONE_REVERSE_PARALLEL', false),
/*
|--------------------------------------------------------------------------
| Свой рендер-канал (self-render) вместо платного xf4
|--------------------------------------------------------------------------
|
| true → 2ГИС+Яндекс тянутся через свой рендер-сервис на виртуалке (SelfRenderClient
| + прокси; 2ГИС отдаёт initialState → TwoGisJsonReader). false → текущий путь xf4.
| Мгновенный откат тумблером. Требует services.self_render.endpoint/.key (в .env).
| Гранулярные тумблеры (для безопасной раскатки) наследуют master, если не заданы явно:
| self_render_2gis — только 2ГИС на свой рендер;
| self_render_yandex — только Яндекс на свой рендер+прокси.
| По умолчанию ВСЁ ВЫКЛ.
|
*/
'self_render' => env('AUTOPODBOR_SELF_RENDER', false),
'self_render_2gis' => env('AUTOPODBOR_SELF_RENDER_2GIS', env('AUTOPODBOR_SELF_RENDER', false)),
'self_render_yandex' => env('AUTOPODBOR_SELF_RENDER_YANDEX', env('AUTOPODBOR_SELF_RENDER', false)),
/*
|--------------------------------------------------------------------------
| Кэш отрисованных карточек 2ГИС/Яндекс (снизить нагрузку и ускорить)
|--------------------------------------------------------------------------
|
| true → загрузчик карточек оборачивается CachingPageFetcher: отрисованные карточки
| (2ГИС `…/firm/…`, Яндекс `…/maps/org/…`) кладутся в Redis по ключу URL на N дней и
| повторно берутся из кэша — без обращений к 2ГИС/Яндекс/прокси. Кэш ОБЩИЙ для шага 1
| (поиск) и шага 2 (изучение) и для повторных прогонов. Поиск (`…/search/…`) и ленты —
| всегда свежие (мимо кэша), поэтому повторный сбор всё равно находит новые фирмы.
| Пустой ответ не кэшируется (сбой не отравит кэш). По умолчанию ВЫКЛ — откат тумблером.
|
*/
'render_cache' => env('AUTOPODBOR_RENDER_CACHE', false),
'render_cache_ttl_days' => (int) env('AUTOPODBOR_RENDER_CACHE_TTL_DAYS', 5),
];