Узкие центрированные модалки на телефоне резали содержимое (ряды кнопок,
вкладки, дни недели, сетку регионов — контент вылезал за края, текст обрезался
слева и справа). Диалоги с богатым содержимым теперь на телефоне открываются
на весь экран (:fullscreen по useLayoutTier + scrollable):
- Проект (создание/редактирование) — NewProjectDialog
- Новая сделка — NewDealDialog
- Пополнение баланса — TopupDialog
- Дни оптом — DaysBulkDialog (те же кнопки дней)
- Регионы оптом — RegionsBulkDialog
- Импорт: сопоставление статусов — UnknownStatusesDialog
Десктоп/планшет — прежний центрированный модал, без изменений.
Тесты диалогов 59/59 (+2 skip) зелёные.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
В карточках «На актуализацию» три кнопки (Добавить/Заменить/Отказаться)
были шире контента и заезжали за правый край карточки (на ~18px, «Отказаться»
упиралась в бортик). На телефоне (media <600px) кнопки теперь во всю ширину
карточки поровну (flex:1) — держатся внутри паддинга. Десктоп без изменений.
Проверено сканом всех 39 карточек: заездов за паддинг больше нет.
Тесты 71/71 зелёные.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
На телефоне (media <600px):
- Плашка «Лидерра подготовила N предложений… Разобрать предложения →»
раскладывается в столбик: текст переставал крошиться по слову, а ссылка
«Разобрать предложения →» больше не вылезает за край (была nowrap).
- Строка «Выбрать всех/все предложения» — flex-wrap: подсказка падает на
новую строку во всю ширину, не жмётся в узкую колонку.
Правки в общем field-shared.css — покрывают и «В поле», и «Предложения».
Тесты «Поля» 71/71 зелёные. Десктоп/планшет без изменений.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Сегмент-контрол «Тип лица» (Физическое лицо/ИП/Юридическое лицо) на телефоне
не влезал в строку и наезжал; теперь раскладывается в столбик во всю ширину
(media <600px, скруглены верх/низ группы). Остальные поля реквизитов уже
адаптивны. Десктоп/планшет — горизонтальный переключатель, без изменений.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
На телефоне фильтры (Тип/Статус/Регион/День/Сортировка/Поиск) перестали
обрезаться («Р…», «Д…») — раскладываются в столбик во всю ширину
(перебит inline max-width через media <600px). Десктоп/планшет без изменений;
карточки проектов уже адаптивны.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
На телефоне 5 колонок больше не листаются вбок: сверху горизонтальный
переключатель этапов (чипсы со счётчиками), ниже — выбранная колонка на всю
ширину. Смена этапа сделки на телефоне — тапом по карточке через drawer
(drag вбок на узком экране неудобен). Планшет/десктоп — прежняя доска со всеми
колонками и перетаскиванием, без изменений.
Тесты Канбана 23/23 зелёные. Проверено на 390 и 1440px (+ переключение этапов).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Те же выпадашки региона (новый проект, фильтр списка, массовое
add/remove регионов, карточка проекта) переведены на REGIONS_ALPHA —
единый порядок с автоподбором, республики по своему имени, а не кучей.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Регионы выводились в конституционном порядке (республики → края →
области), из-за чего список выглядел кашей (Дагестан → Донецкая
Народная → Ингушетия → Кабардино-Балкарская). Добавлен REGIONS_ALPHA:
сортировка по «настоящему» имени, слова-типы (Республика/область/край/
автономный округ) отбрасываются — Татарстан на «Т», Адыгея на «А».
Подставлен во все 7 выпадашек автоподбора. Тест regionsAlpha.spec.ts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Кнопка на актуализации переименована «Удалить»→«Отказаться» (чтобы клиент не путал с удалением конкурента).
- CSV-выгрузка «Списаний» теперь включает автоподбор-строки (отдельным блоком, «Автоподбор конкурентов»);
тест на export. charges 11/11.
- schema.sql canon-sync v8.63: +колонка dismissed_actualize_keys у autopodbor_competitors + CHANGELOG
(заодно в цепочку шапки вписана пропущенная v8.62 CHECK autopodbor_charge).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Кнопка «Удалить» на карточках «На актуализацию» рядом с Добавить/Заменить.
Отклоняет ТОЛЬКО находку (новый сайт/адрес): фирма поля остаётся, находка → архив,
её новые ключи запоминаются у фирмы поля (новая колонка dismissed_actualize_keys jsonb).
Классификатор вычитает отклонённые ключи → та же находка больше не всплывает; реально
другой новый сайт даст новый ключ → покажется. Не глушим по имени, конкурента не убираем.
Бэк: миграция + модель-каст + ProposalClassifier (вычитание) + эндпоинт dismissActualize
+ роут. Фронт: api + store + кнопка «Удалить». Тесты: классификатор 8/8, ветка 185/185,
фронт 30/30. Canon-sync schema.sql (v8.62) — follow-up (миграция idempotent-guarded).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- «Списания» (TenantChargesController.index) теперь union lead_charges + autopodbor_charge
(balance_transactions) — клиент видит списания за прогоны, не только в «Истории транзакций».
Автоподбор-строки: kind=autopodbor, метка вместо сделки, «—» для tier. Фильтр charge_source
автоподбор не подмешивает. 2 теста, всего charges 10/10.
- Плашки «Предложений» разъезжались за экран на длинных URL (utm/рекламные хвосты): grid-элементы
min-width:auto не сжимались. Фикс: .ld-grid>* min-width:0 + перенос длинных ссылок.
- Фронт 16/16.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Групповое и одиночное создание теперь ТРЕБУЮТ регион (vsyaRf=false по умолчанию;
«Вся РФ» — явная галочка, дефолта больше нет — подтверждено владельцем). Тесты
были под старый дефолт «Вся РФ» → doCreate бэйлился на гейте региона. Добавлен
явный выбор «Вся РФ» перед doCreate. Плюс requisites_required теперь открывает
форму реквизитов (reqGate), а не тост — тест переведён на новое поведение,
reqGate добавлен в defineExpose для наблюдаемости. Спек 6/6 зелёный.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Клик «Удалить» у предложения открывает окно со всеми предложениями,
найденными в том же месте (совпал url карточки/сайта в «где нашли»), с
галочками. По умолчанию отмечена только нажатая строка; клиент выбирает,
какие связанные строки удалить. «В работе» — прежнее окно. Массовое
удаление предложений — подтверждение со списком выбранных.
Только показ и порядок «сначала выбери, потом удали»; БД/бэкенд не тронуты.
Тесты: пул по url, строгое совпадение, дефолт-галочка, удаление отмеченных.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Разворот по телефонам 2ГИС и Яндекс больше не уходит цепочкой «до талого»:
по умолчанию берём только фирмы с ЛИЧНЫМ номером фирмы — глубина 1. Именно
неограниченная цепочка уводила в чужие фирмы, давая мусорные сайты в
предложениях холдинга. Многошаговый разворот сохранён за параметром maxDepth,
по умолчанию 1. Изолировано: работает только под флагом phone_reverse, основной
пул сбора не затрагивается. Бэкенд автоподбора 430 из 430.
Фронт: на вкладке «Предложения» добавлена кнопка массового удаления выбранных
источников — bulkDeleteProps через removeSource, покрыта тестами.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Слияние конкурентов больше не «чёрная дыра» (баг «САПС/Метрополис»: карточка
исчезла без следа, вернуть было нечем). Теперь каждое слияние пишет событие в
autopodbor_merge_events со СНИМКОМ поглощённых карточек (имя/сайт/телефоны/
справочники), кто и когда слил.
- Таблица autopodbor_merge_events (+RLS tenant_isolation, паттерн 1:1 с sources,
rls-ревью OK; nullOnDelete на survivor_id/user_id — история не рушится).
- AutopodborCompetitorMerger::merge($tenantId,$ids,$name,$userId) пишет событие.
- GET /field/merge-events — история; POST /field/merge-events/{id}/restore —
возврат поглощённых как предложения (защита от повторного возврата).
- Фронт: панель «🕘 История слияний» + «↩ Вернуть карточку».
Бэк 428/428, фронт 12/12, Pint чистый, build ок. schema.sql канон-синк всех
таблиц автоподбора — предвыкатный TODO (вся фича migration-only в этой ветке).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Баг «САПС/Метрополис»: клиент переименовал свежую карточку и слил — а выжила
ДРУГАЯ (с проектами/в поле), имя переименованной затёрлось вслепую, карточка
пропала. Теперь окно «Найти дубли» помечает карточку, которая ОСТАНЕТСЯ
(«· останется»), и берёт ЕЁ имя как имя объединённого по умолчанию — клиент
видит исход до подтверждения и не теряет карточку случайно.
Бэкенд (survivor-метка в duplicate-groups + AutopodborCompetitorMerger::survivorId)
уже в 853c5a00; здесь фронт: api-тип, окно, метка, тест. Фронт 11/11.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Кнопка «Найти и объединить дубли» на экране поля теперь ловит и предложения,
дублирующие карточки поля (scope=cross): счётчик учитывает их, окно помечает
«· предложение», объединение сливает предложение в карточку поля (выживает поле,
merger не трогали). Бэкенд оставляет только группы с ≥1 карточкой поля — пары
чисто-предложений на экране поля не мусорят.
Файл-статус сессии — docs/superpowers/findings/2026-07-05-avtopodbor-session-status.md.
Feature 154/154, фронт 32/32, Pint чистый, билд собран.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1. Разворот по телефонам запускается ТОЛЬКО при наличии своего сайта (seedDomain).
Без сайта имя размыто (напр. «Южный берег» → автосервисы/гостиницы), сеедные
телефоны грязные, а разворот их лишь умножает. Доказано вживую: ДСК/СМ-сити
(сайт есть) — чисто; «Южный берег» (нет) — 70% мусора.
2. Поиск дублей научился кросс-ящик поле↔предложения (scope=cross): предложение-
дубль карточки поля теперь всплывает (merge кросс-ящик уже умеет). В выдаче
виден box каждой фирмы. Без scope — прежнее поведение (один ящик).
3. На кнопке «Найти и объединить дубли» показывается число найденных групп-дублей
(считается на загрузке, обновляется после слияния/«это разные»).
Юнит 267/267, feature 153/153, фронт 15/15.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ошибка создания проекта показывается заметно прямо в окне (красный блок), а не тихим
тостом внизу. При дубле источника — подсказка «проверьте на дубли» и кнопка, которая
перекидывает в «Конкурентное поле» и сразу открывает окно объединения дублей.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Клиент ушёл со страницы во время сбора и вернулся — индикатор пропадал (жил только
на опросе в памяти браузера), казалось, что процесс исчез.
- competitor-эндпоинт отдаёт active_run (идущий по конкуренту сбор) — тест
- loadCompetitor подхватывает active_run в currentRun (не затирая итог завершённого)
- onMounted возобновляет опрос, если сбор ещё идёт → индикатор оживает, дожидаемся итога
- тесты: active_run (бэк), loadCompetitor подхват/сохранение, подхват опроса на экране
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
У клиента включено «уменьшить движение» (Windows/браузер) — глобальное правило
motion.css гасило ВСЕ анимации (animation-iteration-count: 1 !important), поэтому
любой кружок замирал после одного оборота и казался зависшим.
Спиннеры-загрузчики (.ld-spin, .ld-collecting__spin) — законное исключение (WCAG
допускает индикатор загрузки): возвращаем медленное непрерывное вращение. Чинит
все кружки в приложении разом, не только автоподбор.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Клиент жаловался: кружок «завис» и прогресс не видно, когда окно сбора закрыл.
- CollectingIndicator: собственный гарантированно крутящийся кружок (старый ld-spin
из @import в scoped не анимировался — известный баг Vue) + текст очередь/этап.
- Индикатор ставится прямо на экран (конкурент и «поле») — виден, даже если окно закрыли:
«вы в очереди №N» / «этап N из M» / «идёт сбор…».
- В окнах сбора заменил статичный кружок на этот индикатор.
- 4 теста компонента + тест экрана.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Кнопка «🔄 Собрать источники ещё раз» вместо мёртвой «✓ Источники собраны».
Окно предупреждает, что повтор платный (даже если нового нет). Честный итог
после сбора (N новых / M ранее удалённых). Блок «ранее удалённые — вернуть?»
с кнопкой «Вернуть» (box archived→proposal).
- RunDto.result + collectResultMessage (чистый хелпер) + тесты
- store.restoreSource + тест
- компонент RefoundDeletedSources + тест
- FieldCompetitorScreen: кнопка-повтор, честный итог, блок «вернуть», текст окна
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
#1 requisites_required — показываем короткую форму реквизитов прямо в экране
Конкурентного поля и повторяем создание проекта после сохранения.
#4 дубль источника — при добавлении проверяем, нет ли такого же источника у другого
конкурента или уже созданного по нему проекта. Отдаём клиенту выбор: убрать дубль или
перенести проект к новому источнику по идентификатору. Проект не пересоздаётся.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Компонент RunCollectStatus: «вы в очереди №N» (пока прогон ждёт) или «этап N
из M: подпись» (пока идёт). Встроен в оба окна сбора (конкуренты/источники) и
экран загрузки ручного изучения. RunDto получил queue_position и progress.
Никаких фейковых процентов — только реальные этапы движка. 4 теста Vitest.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Диалог дублей: селект имени среди выбранных к слиянию, по умолчанию первое.
Merger и ручка принимают опциональное имя. Обе экрана.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
В группе из 3+ клиент отмечает, кого объединить. По умолчанию выбраны все
(группа из 2 - как раньше). Слить можно любое подмножество >=2. На обоих экранах.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Бэк: хелпер CompetitorElements нормализует элементы и выводит легаси site_url/directory_urls
из ВСЕХ карточек. Ручки manual/update принимают elements.
Фронт: компонент CompetitorElementsEditor встроен в формы создания и правки на экранах
Поле и Предложения. Прежний баг - пересбор directory_urls из двух полей - закрыт.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- стор removeSource чистит store.sources - карточка конкурента обновляется без reload
- 8 оверлеев на экранах Поле/Предложения переведены на useOverlayDismiss
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
FieldCompetitorScreen:
1) метки ✓ настоящий номер / 🎭 рекламный подменный + плейн-язык «где нашли»
+ легенда «как читать» (данные в БД и сверка с ЭТАЛОНом НЕ тронуты — перевод только в показе);
2) регион «впечатывается» — свой тайп-ахед в стиле экрана (без Vuetify, чтобы не ломать тесты)
в окнах «Создать проект» и «Настройки проекта»; чипы для мультивыбора, подпись округа;
3) галка «Вся РФ (все регионы)» даёт баннер-объявление;
4) групповое создание проектов из всех выбранных источников без проекта (source_ids пачкой),
заголовок/текст под «несколько». +тест на групповое создание. Фронт-спеки 24/24 зелёные.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Шаг 1 «Конкурентное поле» — чекпоинт:
- Финальный проход «Найти и объединить дубли» на поле и предложениях; клиент решает по каждой группе, ничего не склеиваем молча.
- Тихая склейка только по сайту и коду справочника; телефон и людный номер у более чем 4 фирм — на решение клиента.
- Колонка phones jsonb; телефон-дубли видны уже на «Предложениях».
- Sonar даёт только имя и тип, сайт всегда через EXA; вскрываем все карточки без гейта «есть сайт».
- Яндекс-карточки через локальный Playwright параллельно; рубрика из заголовка идёт в описание.
- Фикс рекламных номеров: 2ГИС-парсер разбирает телефоны пообъектно и выкидывает рекламные кнопки с platforms/caption чужих фирм.
Тесты: автоподбор 224/224 unit, 105/105 feature; фронт-спеки зелёные. Времянки app/scripts/diag-*/probe-* в гит не входят.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ядро фичи для обычных проектов (без автоподбора): единый LaunchBalanceGate под
lockForUpdate(Tenant), ProjectService::create($launch)+setActive, bulk resume
«сколько влезло», ProjectController store/update/toggle, config/billing.php,
ProjectResource.preflight_blocked_at + фронт экранов проектов (сообщения в рублях,
метка «не запущен», группы). Схема БД не менялась (preflight_blocked_at уже был).
Cherry-pick ТОЛЬКО ядра поверх main 73b56042; автоподбор НЕ выкатывается.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Фронт для правила «баланс блокирует запуск, а не создание»:
- ProjectLimitOverloadDialog переформулирован в «Проект не запущен — пополните
~X ₽ или уменьшите объём» (сумма в рублях topup_rub).
- NewProjectDialog: создание всегда успешно; при launch.deferred показывает
сообщение (не блок). Update-лимита 409 → тот же диалог.
- Возобновление (toggle-active) ловит 409 balance_insufficient (стор не
переключает is_active), показывает диалог; постоянная метка «Не запущен —
не хватает баланса» на карточке/в панели по preflight_blocked_at/balance_blocked.
- BulkActionsBar: сводка «Запущено N, отложено M — не хватает баланса» на resume.
- Автоподбор: CreateScreen показывает сводку запуска (рубли); FieldCompetitor
массовые pause/resume через общий POST /api/projects/bulk (наследует BULK_MAX,
слепок-защиту, балансовый гейт).
- ProjectResource отдаёт preflight_blocked_at.
Новые/обновлённые фронт-тесты зелёные. Пред-существующий красный baseline
фронт-набора (ErrorView/Settings/Legal/… + ProjectsView v-show) не трогался.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Мини-плашка теперь показывает деньги (или —) И слово статуса (жив/выключено/ok)
рядом, как в детализации. Убрана мёртвая serviceValue.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Баланс/статус различаем по типу сервиса (LIVENESS_ONLY_KEYS), не по null-балансу
(денежный Поставщик с сорванным автологином больше не показывается «выключено»).
Мини-плитка переименована «Балансы сервисов»→«Внешние сервисы».
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Статус-текст для сервисов без денежного баланса (жив/не отвечает/выключено),
метки и иконки почты/ЮKassa/Jivo/капчи, обновлённые подписи плитки и дрилла.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Секция «На актуализацию»: дельта-карточка показывает текущие сайты и карточки фирмы поля + новый сайт кликабельными ссылками, кнопки Добавить и Заменить ведут через подтверждение «Создать проект?» в существующую форму CreateScreen с подставленным новым источником. Имя фирмы берётся из поля, не перезатирается.
Бэкенд: endpoint POST /competitors/{id}/actualize action=add|replace new_site. add заводит сайт-источник рядом со старым, replace архивирует старые сайт-источники и заводит новый, при активном проекте по старому сайту возвращает 409 manage_via_project. /proposals обогащён полем matched с текущими сайтами и карточками совпавшей фирмы.
По TDD. Бэкенд автоподбора 254/254, фронт автоподбора 64/64, ESLint чисто, Pint чисто.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Stage 1: опознавалка фирмы по сайту/карточкам, ProposalClassifier new/actualize/archived/hidden, box=archived, bulk удалить всех ранее удалённых. Backend 249/249, front autopodbor 61/61.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Экран FieldCompetitorScreen:
- «где нашли» теперь кликабельные ссылки на источники (where_found из DTO),
адреса филиалов 2ГИС видны и кликабельны под номером;
- сортировка источников: больше подтверждений — выше, подменные — вниз;
- строка адреса офиса, счётчик подтверждений.
DTO SourceDto расширен полями where_found/confirmations/office (опциональны —
обратная совместимость: без них падаем на старое provenance_label).
Histoire-стори с живыми данными КрасЛомбарда (рендер настоящего компонента).
TDD: +2 теста, autopodbor-экраны 24/24. Бэкенд-провод where_found — отдельно (Plan C).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Сверка прототипа с реализацией показала расхождения — закрыты по TDD (dev, фронт):
- F1: экран «Предложения» (FieldProposalsScreen) переписан под вид «Поля» —
карточки-плитки field-shared, тип+«предложение», крупная похожесть, Сайт +
Справочник 2ГИС·Яндекс, править/удалять в карточке, массовый перенос; кнопка
«Собрать конкурентов» открывает единое окно сбора 300 ₽ вместо старого autoform.
- F2: новый дружелюбный админ-экран AdminAutopodborPricingView (правка цен
доп.услуг через PUT /api/admin/system-settings/{key} с обоснованием для аудита,
сетка лидов для справки) + маршрут /admin/autopodbor-pricing + пункт меню.
- F3: колонка «когда списывается» в панели доп.услуг биллинга.
- M2: удалён мёртвый экран FieldManualCompetitorScreen (+ спека) — на него не
было переходов; ручное добавление живёт окном на «Поле».
Тесты автоподбор+админ 43/43 зелёные, продакшен-вёрстка eslint-чистая, vite build ✅.
НЕ на проде. M1 (18:00/21:00 МСК) — не баг, реальный инвариант продукта, не трогал.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Фича «Конкурентное поле» на dev до уровня прототипа 2026-06-29-konkurentnoe-pole-proto.html.
Данные: box (proposal|field) на competitors+sources; phone_type city/mobile/tollfree рядом
с phone_kind (вариант C). 3 миграции, дефолты тарифов 300/50.
API (AutopodborController): GET /field (+счётчики), GET /proposals, PATCH/DELETE competitors
и sources с гвардами активного проекта, переключение box, POST /competitors/manual (+directory_urls),
competitor(id) обогащён box+project-статусом; projectStatus отдаёт limit/delivered/days/regions.
Смена источника проекта = PATCH /api/projects/{id} (реальный гвард слепка §14.10).
Фронт: FieldWorkspaceScreen/FieldCompetitorScreen/FieldProposalsScreen/FieldManualCompetitorScreen
+ field-shared.css (Forest) + AutopodborServicesPanel в Биллинге. Дословно по прототипу: подзаголовки,
баннер предложений, баннер правил времени 18:00 МСК, Справочник 2ГИС·Яндекс, статус проекта
5/день·заявки, окна сбора с ценами 300/50 + «что известно», полные формы. Пункт меню «Конкурентное поле».
Тесты: backend автоподбор 80/80, фронт автоподбор 49/49. Движок шага 2 = заглушка FakeCompetitorAgent.
OmegaDemoFieldSeeder — только для визуальной проверки (НЕ на прод).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Настройки→Реквизиты и диалог проекта: «Физлицо»→«Физическое лицо», «Юрлицо»→«Юридическое лицо» (ключи value не тронуты)
- У физлица скрыт блок «Реквизиты для оплаты» (банковских реквизитов нет; оплата по счёту — только для юр/ИП)
- Диалог проекта: выбранные дни недели залиты зелёным #0f6e56 как в ProjectDetailsDrawer
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>