Commit Graph

5 Commits

Author SHA1 Message Date
Дмитрий dee2ebbcf8 feat(автоподбор): второй справочник канала А — Яндекс.Карты через локальный Playwright + слияние
Firecrawl Яндекс.Карты не рендерит (0-2 орг) — по §12.2 Яндекс берём локальным Playwright.
render-yandex-list.cjs скроллит ленту результатов → 113 орг за ~18с (быстрее xfetch-2ГИС).
YandexDirectory (граница) + PlaywrightYandexDirectory (живой, Process→node). Яндекс = имя+карточка
(сайта в списке нет — только на карточке, не открываем). Оркестратор: канал А = 2ГИС(сайт)+Яндекс,
слияние (mergeCompetitors union-find) схлопывает одного конкурента из обоих справочников в одну
карточку с двумя directory_urls; сайт из 2ГИС. Провайдер подключает живой Яндекс. listingHtml →
общий хелпер tests/Pest.php. Модуль 136 unit + 74 feature зелёные. За флагом; на проде не меняется.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 04:53:58 +03:00
Дмитрий 5d40de664e feat(автоподбор): лёгкий канал А — имя+сайт+карточка из списка 2ГИС без захода в карточку
Шаг 1 = только имя+сайт+ссылка на справочник (телефоны/описание = шаг 2). Убраны медленные
per-card открытия: со страницы категории 2ГИС берём по фирме имя + ссылку карточки + САЙТ сразу
(CategoryListingParser: сайт из редиректа «Перейти на сайт», firmId в пути = id фирмы; мусор
avito/max.ru/трекеры/иностр.TLD отсеиваем). CategoryScraper отдаёт строки {name,card_url,site}
с пагинацией. LiveFindCompetitors упрощён: канал А из списка (без резолва), канал В — имена →
сайт EXA, без сайта (нет якоря) выкидываем. Живой канал А на новом ключе xfetch: 48 реальных
фирм Красноярска, 17 с сайтом, ~4.5 мин, без per-card. Филиалы схлопывает merge (union-find).
Модуль 135 unit + 74 feature зелёные. За флагом autopodbor.real_find; на проде не меняется.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 03:31:16 +03:00
Дмитрий 5a65165114 feat(автоподбор): движок шага 1 пересобран под финал v4 (каналы А+В, EXA)
Замена вырожденного «одна фраза → одна страница» на §12/§11.3 финал:
- Шаг АНАЛИЗ (ChannelA\AitunnelQueryAnalyzer): описание → запросы-рубрики (мелкая модель).
- Канал А (ChannelA\CategoryScraper): скрейп категории 2ГИС с пагинацией → резолв карточек.
- Канал В (ChannelB\*): ОДНА модель sonar-reasoning-pro × 2 прохода → ТОЛЬКО имена
  федералов; стоп-лист = имена из А + примеры; сайт федерала через EXA (ExaSiteFinder),
  т.к. у федерала нет карточки в 2ГИС/Яндексе на регион.
- Оркестратор LiveFindCompetitors переписан: АНАЛИЗ→А→В→слияние→отсев→дедуп→похожесть→DTO.
- Провайдер перепрошит; config services.php +research_model/exa.
Похожесть — эмбеддер-модель (математически), резолвер/дедуп — без изменений.
Всё за тонкими границами, офлайн-тесты на фикстурах: модуль 130 unit + 74 feature зелёные.
Провайдер за флагом autopodbor.real_find; на проде не меняется.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 21:06:10 +03:00
Дмитрий adc3590ab6 fix(автоподбор): живой резолв Яндекса (город в заголовке не на фикс. месте) + ретрай флакующей выдачи
Найдено живым прогоном по нише «ломбард/Красноярск»:
1) Яндекс-заголовок «Имя, рубрика, ГОРОД, улица, дом» — город НЕ последний сегмент; брал «дом»
   как город → все карточки отбраковывались. Теперь YandexResolver: имя=первый сегмент, город —
   по НАЛИЧИЮ в заголовке (DirectoryFields::titleName/titleHasCity). 2ГИС (город последний) — без изменений.
2) ResolvingAgent (ручной resolveByName) теперь берёт ГОРОД центра субъекта (RegionCity), не имя региона.
3) Страница выдачи 2ГИС/Яндекс флакует (капча/пустой layout) → LiveFindCompetitors повторяет поиск,
   пока не появятся фирмы (searchRetries).

Тесты: модуль Автоподбора unit 99/99 + live 4/4; Pint чисто.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 18:44:27 +03:00
Дмитрий 84e769e454 feat(автоподбор): шаг1 — живой findCompetitors (канал А: ниша → 2ГИС+Яндекс → резолв → сборка)
LiveFindCompetitors: ниша из формы → поиск 2ГИС (по слагу города) + Яндекс (по «ниша город») →
парсер выдачи → резолв каждой карточки напрямую → FindCompetitorsAssembler (фильтр/слияние/
похожесть → DTO §7.2). Добыча за PageFetcher — обход тестируется офлайн на фикстурах.
RegionCity — слаг/имя города центра субъекта (как RegionAreaCode, только уверенные).

Тесты: live 3/3 (склейка 2ГИС+Яндекс одной фирмы, вычет своего сайта, пустая выдача);
модуль Автоподбора unit 99/99; Pint чисто. Провайдер ещё не флипнут — следующий шаг.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 18:23:29 +03:00