df70a78e17
Затык был ровно один — routes/web.php: главная добавила ручку суточного итога сторожей с машины робота, ветка добавила приёмник статусов Билайна. Ручки независимые, оставлены обе. Попутно поправлено примечание в config/services.php: оно говорило «заявка подана, срок до десяти рабочих дней», а имя `Liderra.ru` было ОДОБРЕНО обеими сетями 10.08.2026 в тот же день — проверено глазами в кабинете. Примечание, которое врёт, хуже отсутствующего: следующая смена прочла бы его и не стала поднимать выключатель. Замер на сведённом коде: - модуль СМС 575/575, 7151 проверка (опора ветки была 548 — главная принесла 27); - фронтенд 2205 из 2210. Пять падений — ЧУЖИЕ и приехали из главной: KoshelyokZakladkiPoKanalam.spec.ts, экран AdWalletMoneyColumn.vue спотыкается об отсутствующее поле frozen_breakdown. Доказано отпечатками: и тест, и экран байт в байт совпадают с gitea/main, моя правка их не касалась; - Pint и PHPStan — чисто.
282 lines
19 KiB
Bash
282 lines
19 KiB
Bash
APP_NAME=Liderra
|
||
APP_ENV=local
|
||
APP_KEY=
|
||
APP_DEBUG=true
|
||
APP_URL=http://localhost
|
||
|
||
APP_LOCALE=ru
|
||
APP_FALLBACK_LOCALE=ru
|
||
APP_FAKER_LOCALE=ru_RU
|
||
APP_TIMEZONE=Europe/Moscow
|
||
|
||
APP_MAINTENANCE_DRIVER=file
|
||
# APP_MAINTENANCE_STORE=database
|
||
|
||
# PHP_CLI_SERVER_WORKERS=4
|
||
|
||
BCRYPT_ROUNDS=12
|
||
|
||
LOG_CHANNEL=stack
|
||
LOG_STACK=single
|
||
LOG_DEPRECATIONS_CHANNEL=null
|
||
LOG_LEVEL=debug
|
||
|
||
DB_CONNECTION=pgsql
|
||
DB_HOST=127.0.0.1
|
||
DB_PORT=5432
|
||
DB_DATABASE=liderra
|
||
DB_USERNAME=postgres
|
||
DB_PASSWORD=
|
||
|
||
# Supplier Sync (Plan 3 Task 3) — crm_supplier_worker BYPASSRLS connection.
|
||
# На production указывают на роль crm_supplier_worker (создана db/00_create_roles.sql v1.1).
|
||
# Если не заданы — fallback на DB_USERNAME / DB_PASSWORD (dev: postgres superuser, BYPASSRLS implicit).
|
||
DB_SUPPLIER_USERNAME=crm_supplier_worker
|
||
DB_SUPPLIER_PASSWORD=
|
||
|
||
# Supplier Portal credentials (Playwright login — Task 5)
|
||
SUPPLIER_LOGIN=
|
||
SUPPLIER_PASSWORD=
|
||
SUPPLIER_PORTAL_URL=https://crm.bp-gr.ru
|
||
|
||
# Supplier alerts (email через Unisender Go relay)
|
||
SUPPLIER_ALERT_EMAIL=
|
||
|
||
# Сторожа машины робота (З-0.10). Машина 51.250.1.97 раз в сутки гоняет своих
|
||
# сторожей и стучится сюда с итогом. Тревога уходит на MONITORING_ALERT_EMAIL
|
||
# (он же падает на SUPPLIER_ALERT_EMAIL, тот — на ops@liderra.ru).
|
||
# 🔴 LENA_STOROZHA_SLOVO — тайное слово подписи тела. Короче 32 знаков или
|
||
# пусто = дорога закрыта совсем. То же слово кладётся на машину в файл
|
||
# /home/ubuntu/lena-golos/nastroyki-obhoda (права 600), в хранилище его нет.
|
||
LENA_STOROZHA_SLOVO=
|
||
# Кому позволено стучать: адреса/подсети через запятую. Пусто на бою = закрыто.
|
||
LENA_STOROZHA_ADRESA=
|
||
# Сколько сторожей ждём в итоге. Прибавили сторожа на машине — прибавьте здесь.
|
||
LENA_STOROZHA_SKOLKO=3
|
||
# Сколько часов итог считается свежим (обход ходит раз в сутки).
|
||
LENA_STOROZHA_SVEZHEST_CHASOV=26
|
||
|
||
# SaaS-admin fail-closed гейт (M-1). Логины nginx basic-auth (.htpasswd-admin),
|
||
# допущенные в /api/admin/*. CSV; дефолт совпадает с прод-.htpasswd.
|
||
ADMIN_ALLOWED_USERS=admin
|
||
# ADMIN_GATE_ENFORCED=true # авто: true вне local/testing; задать явно для override
|
||
# Системный admin-id для audit-trail (FK saas_admin_audit_log). На проде crm_app_user
|
||
# не имеет прав на saas_admin_users → задать id сид-стаба. dev/test — оставить пустым.
|
||
ADMIN_AUDIT_SYSTEM_USER_ID=
|
||
|
||
# Капча самозаписи (M-2). driver=null (dev) | yandex (prod). Для yandex нужен server-key.
|
||
CAPTCHA_DRIVER=null
|
||
YANDEX_SMARTCAPTCHA_SERVER_KEY=
|
||
|
||
SESSION_DRIVER=database
|
||
SESSION_LIFETIME=120
|
||
SESSION_ENCRYPT=false
|
||
SESSION_PATH=/
|
||
SESSION_DOMAIN=null
|
||
|
||
BROADCAST_CONNECTION=log
|
||
FILESYSTEM_DISK=local
|
||
QUEUE_CONNECTION=redis
|
||
|
||
CACHE_STORE=database
|
||
# CACHE_PREFIX=
|
||
|
||
MEMCACHED_HOST=127.0.0.1
|
||
|
||
REDIS_CLIENT=predis
|
||
REDIS_HOST=127.0.0.1
|
||
REDIS_PASSWORD=null
|
||
REDIS_PORT=6379
|
||
|
||
MAIL_MAILER=log
|
||
MAIL_SCHEME=null
|
||
MAIL_HOST=127.0.0.1
|
||
MAIL_PORT=2525
|
||
MAIL_USERNAME=null
|
||
MAIL_PASSWORD=null
|
||
MAIL_FROM_ADDRESS="hello@example.com"
|
||
MAIL_FROM_NAME="${APP_NAME}"
|
||
SUPPORT_EMAIL=support@liderra.ru
|
||
BOT_TOURS_ENABLED=false
|
||
YANDEX_GPT_API_KEY=
|
||
YANDEX_GPT_FOLDER_ID=
|
||
|
||
AWS_ACCESS_KEY_ID=
|
||
AWS_SECRET_ACCESS_KEY=
|
||
AWS_DEFAULT_REGION=us-east-1
|
||
AWS_BUCKET=
|
||
AWS_USE_PATH_STYLE_ENDPOINT=false
|
||
|
||
VITE_APP_NAME="${APP_NAME}"
|
||
|
||
# Клиентский ключ Yandex SmartCaptcha (M-2). Пусто → fallback-чекбокс (dev).
|
||
# На проде — клиентский ключ ysc1_… (для виджета на странице регистрации).
|
||
VITE_YANDEX_SMARTCAPTCHA_SITEKEY=
|
||
|
||
# Автоподбор шаг2: обход антибота справочников (2ГИС/Яндекс). Ключ — в .env, не в гите.
|
||
XFETCH_API_KEY=
|
||
|
||
# Автоподбор шаг1: модель ИИ-фильтра «поставщик или площадка-агрегатор».
|
||
# ОБЯЗАТЕЛЬНО gpt-4o (сильная): слабая gpt-4o-mini наугад штампует живые
|
||
# федеральные МФО (Екапуста/Webbankir/СрочноДеньги…) как «агрегаторы» и режет
|
||
# их из подбора. Пусто → фолбэк на gpt-4o-mini (баг «режет федералов», 07.07.2026).
|
||
AITUNNEL_AGGREGATOR_MODEL=gpt-4o
|
||
|
||
# Счётчик «полного пути» — тот же, что стоит на лендинге liderra.ru.
|
||
# Без него путь клиента в Вебвизоре рвётся между лендингом и кабинетом.
|
||
METRIKA_PATH_COUNTER_ID=
|
||
|
||
# СМС-маршрутизация по операторам (реестр — config/services.php services.sms.providers).
|
||
# Песочница по умолчанию ВКЛ — живые каналы не вызываются, деньги не уходят.
|
||
SMS_SANDBOX=true
|
||
SMS_FAILOVER_TO_UNIVERSAL=false
|
||
SMS_SMSC_ENABLED=false
|
||
SMS_SMSC_PRICE_KOP=0
|
||
# Имя отправителя универсального канала — им подписываемся, когда своего имени
|
||
# у клиента для сети получателя нет. Пусто = уйдёт без имени.
|
||
SMSC_NAMING=
|
||
SMS_MTS_ENABLED=false
|
||
SMS_MTS_TOKEN=
|
||
SMS_MTS_PRICE_KOP=0
|
||
# Канал Теле2 («SMS-Таргет», target.t2.ru). Логин и пароль берутся в кабинете:
|
||
# Профиль → API-рассылки → Настроить подключение. Там же заявляется IP боевого
|
||
# сервера — без этого t2 отвечает 403 wrong_ip. Имя отправителя — согласованное.
|
||
SMS_T2_ENABLED=false
|
||
SMS_T2_LOGIN=
|
||
SMS_T2_PASSWORD=
|
||
SMS_T2_NAMING=
|
||
SMS_T2_PRICE_KOP=0
|
||
# Обратный звонок t2 о судьбе: /api/webhook/t2-delivery/{секрет}?id=&status=&parts=
|
||
# Секрет — не короче 32 знаков; пустой = приёмник ЗАКРЫТ (судьбу доберёт опрос).
|
||
# 🪤 t2 ответа не проверяет и повторов не делает: пропущенный звонок потерян.
|
||
# Адреса отправителя — через запятую, можно подсетями; пусто = не проверяем.
|
||
SMS_T2_WEBHOOK_SECRET=
|
||
SMS_T2_WEBHOOK_IPS=
|
||
# Канал Билайна (платформа прямых A2P-рассылок a2p-sms.beeline.ru, метод JSON).
|
||
# Вход двух видов, довольно любого:
|
||
# • логин с паролем от кабинета рассылок — работают сразу;
|
||
# • постоянный ключ, он надёжнее. Заводится в кабинете: Карточка пользователя →
|
||
# API токены, создать может только Суперпользователь, значение показывается
|
||
# ОДИН раз. Ключ задан → логин с паролем не передаются вовсе, иначе отказ.
|
||
# 🔑 Билайн доставляет в девять сетей, НО имя отправителя согласуется с каждым
|
||
# оператором отдельно (в кабинете: Имена отправителей). Пока имя одобрено только
|
||
# Билайном — в реестре каналов serves держим ['beeline'], иначе отказ 20230.
|
||
SMS_BEELINE_ENABLED=false
|
||
SMS_BEELINE_LOGIN=
|
||
SMS_BEELINE_PASSWORD=
|
||
SMS_BEELINE_TOKEN=
|
||
SMS_BEELINE_NAMING=
|
||
SMS_BEELINE_PRICE_KOP=0
|
||
# 🔴 Сеть Мотива. Имя отправителя заказано у Билайна сразу и на неё — галка в
|
||
# форме заявки прибита намертво, снять нельзя. Поднимать выключатель ТОЛЬКО
|
||
# после того, как кабинет Билайна покажет имя согласованным (заявка 10.08.2026,
|
||
# срок до десяти рабочих дней): отправка раньше вернёт 20230 «имя не одобрено
|
||
# оператором» — отказ окончательный, повтора нет, сообщение умрёт.
|
||
# Пока выключатель опущен, номера Мотива уходят универсальным каналом.
|
||
SMS_BEELINE_SERVES_MOTIV=false
|
||
# 6,24 ₽ без НДС по прайсу × 1,23464 (НДС 22% + надбавка тарифа 1,2%) = 7,70 ₽.
|
||
# Пакетов на Мотив у Билайна нет вовсе — дешевле не станет.
|
||
SMS_BEELINE_PRICE_MOTIV_KOP=770
|
||
# Обратный звонок Билайна о судьбе: POST /api/webhook/beeline-delivery/{секрет}
|
||
# с полями ORDID, CNRID, RESCOUNT, STATUS, FINALTIME. Секрет — не короче 32 знаков;
|
||
# пустой = приёмник ЗАКРЫТ (судьбу доберёт опрос). Сам адрес надо заявить в кабинете:
|
||
# Настройки → Дополнительно → «Приём статусов отправленных сообщений».
|
||
# 🪤 Повторяет ли платформа неудавшийся звонок — в её описании не сказано ни слова:
|
||
# считаем, что пропущенный звонок потерян.
|
||
# Адреса отправителя — через запятую, можно подсетями; пусто = не проверяем.
|
||
SMS_BEELINE_WEBHOOK_SECRET=
|
||
SMS_BEELINE_WEBHOOK_IPS=
|
||
|
||
# Реклама в Телеграме по своей базе (клиентский модуль, робот-в-браузере — у МТС нет API).
|
||
# Песочница по умолчанию ВКЛ — робот доводит только до черновика, деньги не списываются.
|
||
# TG_SANDBOX=false открывается осознанно (Сессия 6) после проверки в песочнице.
|
||
TG_SANDBOX=true
|
||
# Node-робот кабинета МТС (bots/mts-telegram-ads). Воркер живёт на Windows-машине с сессией МТС.
|
||
TG_ROBOT_NODE=node
|
||
TG_ROBOT_SCRIPT=
|
||
TG_ROBOT_CWD=
|
||
TG_ROBOT_TIMEOUT=300
|
||
# Канал робота-грузчика креативов в веб-кабинет Яндекса. Пусто → канал закрыт.
|
||
CREATIVE_ROBOT_TOKEN=
|
||
|
||
# ── Поиск клиентов: свой рендер-сервис на виртуалке (решение владельца Р126) ──
|
||
# Портал просит виртуалку отрисовать страницу 2ГИС/Яндекса и вернуть данные. Тайный ключ
|
||
# едет заголовком X-Render-Key в КАЖДОМ запросе. Пока адрес или ключ пусты — дверь закрыта:
|
||
# наружу не ходим, поиск отдаёт пусто и говорит об этом в журнал. Ошибками не сыплет.
|
||
# 🔴 Р126: только https://. По http:// ключ поехал бы открытым текстом и молча. Адрес без
|
||
# шифрования портал не принимает. Единственное исключение — разработчик на СВОЁМ компьютере:
|
||
# при APP_ENV=local (или testing) И адресе на петлю этой же машины (127.0.0.0/8, ::1,
|
||
# localhost) http:// разрешён — такой запрос компьютер физически не покидает. Тумблера
|
||
# «можно без шифра» нет намеренно: он и был бы той опечаткой, ради которой запрет заведён.
|
||
# Боевое значение сегодня: SELF_RENDER_ENDPOINT=https://51-250-1-97.sslip.io/render
|
||
SELF_RENDER_ENDPOINT=
|
||
# Тайный ключ портал↔виртуалка (тот же RENDER_KEY, что на самой виртуалке). Только здесь,
|
||
# в код и в гит НЕ попадает.
|
||
SELF_RENDER_KEY=
|
||
# Сколько страниц просим отрисовать ОДНОВРЕМЕННО (браузерная параллельность — внутри виртуалки).
|
||
SELF_RENDER_CONCURRENCY=8
|
||
# Ручка проверки живости виртуалки. Пусто → пингуем сам endpoint.
|
||
SELF_RENDER_HEALTH_URL=
|
||
# 🔴 Куда порталу ВООБЩЕ разрешено ходить с тайным ключом рендера (хосты через запятую).
|
||
# Опечатка в SELF_RENDER_ENDPOINT увела бы ключ чужому человеку молча и навсегда. Хост не
|
||
# из списка = дверь закрыта, запрос не отправлен. Пусто = закрыто всё.
|
||
# 🔴 Если эту строку не задать, берётся умолчание из config/services.php — тот же список.
|
||
# Пустым его делать НЕЛЬЗЯ: на боевом строки нет, а поиск работает — пустое умолчание
|
||
# остановило бы его в момент выката.
|
||
# 🪤 Разрешённый хост — это ещё не безопасная дорога: http:// к разрешённому хосту всё
|
||
# равно закрыт. Два запрета независимы, и снимать их надо по отдельности.
|
||
SELF_RENDER_ALLOWED_HOSTS=51.250.1.97,51-250-1-97.sslip.io,127.0.0.1,localhost
|
||
|
||
# ── Прокси автоподбора (Proxy.Market): плитка «Прокси автоподбора» в админке ──
|
||
# Логин/пароль прокси лежат на ТОЙ ЖЕ виртуалке-рендере. Портал спрашивает её ручку
|
||
# /proxy-check и предъявляет ТОТ ЖЕ тайный ключ SELF_RENDER_KEY заголовком X-Render-Key.
|
||
# 🔴 Р126, третья дверь (07.08.2026): адрес проходит ту же проверку, что SELF_RENDER_ENDPOINT —
|
||
# только https:// и только хост из SELF_RENDER_ALLOWED_HOSTS. Своего списка машин у прокси НЕТ
|
||
# намеренно: ключ один, значит и список, куда его разрешено везти, обязан быть один.
|
||
# Дверь закрыта = плитка СЕРАЯ («не проверяем, причина такая-то»), а НЕ красная: красный на
|
||
# этой плитке значит «прокси кончились» и гонит владельца их продлевать. Врать красным нельзя.
|
||
# Боевое значение сегодня: PROXY_MARKET_CHECK_URL=https://51-250-1-97.sslip.io/proxy-check
|
||
PROXY_MARKET_CHECK_URL=
|
||
# Срок действия купленных прокси — руками при продлении. Пусто/не дата = плитка серая.
|
||
PROXY_MARKET_EXPIRES_AT=
|
||
# За сколько дней до конца срока плитка желтеет.
|
||
PROXY_MARKET_AMBER_DAYS=7
|
||
# Куда ведёт кнопка «Пополнить» на плитке.
|
||
PROXY_MARKET_TOPUP_URL=https://proxy.market/
|
||
|
||
# ── Обзвон: шов «портал зовёт голосового робота» (З-0.3, решение владельца Р84) ──
|
||
# Робот живёт на отдельной машине и делит железо с боевым рендером «Поиска клиентов».
|
||
# Пока адрес или ключ пусты — дверь закрыта: портал наружу не ходит, звонков не будет,
|
||
# и он говорит об этом вслух. Ошибками не сыплет.
|
||
# БАЗОВЫЙ адрес приёмника заданий, без хвоста ручки (портал сам добавит /pozvonit и др.).
|
||
# 🔴 Р123: только https://. Тайный ключ едет заголовком в каждом запросе — по http:// он
|
||
# поехал бы открытым текстом и молча. Адрес без шифрования портал не принимает: дверь
|
||
# закрыта, звонков нет. Живой робот 51.250.1.97 слушает 443 уже сегодня.
|
||
# Единственное исключение — разработчик на СВОЁМ компьютере: при APP_ENV=local (или
|
||
# testing) И адресе на петлю этой же машины (127.0.0.0/8, ::1, localhost) http:// разрешён,
|
||
# потому что такой запрос компьютер физически не покидает. Тумблера «можно без шифра»
|
||
# нет намеренно: он и был бы той опечаткой, ради которой запрет заведён.
|
||
# Пример для своей машины: OBZVON_ENDPOINT=http://127.0.0.1:8080/lena
|
||
OBZVON_ENDPOINT=
|
||
# Тайный ключ портал↔робот. Только здесь, в код и в гит НЕ попадает.
|
||
OBZVON_KEY=
|
||
# Сколько обращений к роботу разрешено ОДНОВРЕМЕННО. Предел общий на машину (замки кэша),
|
||
# а не у каждого работника очереди свой — иначе двое дали бы двойную нагрузку на чужой
|
||
# боевой рендер. 🪤 Живые разговоры этим НЕ ограничены: место освобождается сразу после
|
||
# ответа «принял», а разговор идёт минуты.
|
||
OBZVON_CONCURRENCY=4
|
||
# Сколько секунд лишнее задание ждёт свободного места. Не дождалось → «робот занят»
|
||
# (наружу не ходили, звонка точно не было, повторить позже безопасно).
|
||
OBZVON_WAIT_SECONDS=10
|
||
# Два предела времени. Первый — дозвониться до машины; второй — весь обмен целиком,
|
||
# вместе с чтением. Второй нужен против «робот отдаёт ответ по байту бесконечно»:
|
||
# соединение установилось, а чтение висит и держит работника очереди.
|
||
OBZVON_CONNECT_TIMEOUT=5
|
||
OBZVON_TIMEOUT=15
|
||
# 🔴 Куда порталу ВООБЩЕ разрешено ходить с тайным ключом (хосты через запятую).
|
||
# Опечатка в OBZVON_ENDPOINT увела бы ключ чужому человеку молча. Хост не из списка =
|
||
# дверь закрыта. Пусто = закрыто всё. Переезд робота — осознанная правка в двух местах.
|
||
# 🪤 Разрешённый хост — это ещё не безопасная дорога: http:// к разрешённому хосту всё
|
||
# равно закрыт (Р123). Два запрета независимы, и снимать их надо по отдельности.
|
||
OBZVON_ALLOWED_HOSTS=51.250.1.97,51-250-1-97.sslip.io,127.0.0.1,localhost
|