Фундамент legal_entities/payment_gateways/saas_transactions + драйвер
ЮKassa, поток create->redirect->webhook->автозачисление, рубильник-флаг
billing_yookassa_enabled в админке, чек 54-ФЗ заложен и выключен. Часть 3
счёт на безнал - следующим циклом. Прод на заглушке до ООО Б-1.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Новый сводный документ: что сделано (на проде / в gitea ждёт наката), какие
ключи нужны от владельца (Sentry DSN, Jivo widget ID, Slack webhook, ЮKassa,
Yandex SSO), решения владельца, ООО-блокеры, снятое. JivoSite-виджет отмечен
встроенным; Slack-ошибки — готовы в коде.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Раздел B (~25 «непокрытых» тест-путей) — переоценка: большинство уже покрыто,
реальные гапы закрыты +9 целевыми TDD-тестами (b9184a6a, d7b5f2c1). Помечено
закрытым в owner-decisions и round2-DONE-handoff, чтобы не всплывало в остатках.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- ReportsView.onCancel снимает submitSuccess — success-баннер больше не висит после отмены отчёта. TDD: тест «отмена задачи сбрасывает зелёный» (RED→GREEN), весь ReportsView.spec 22/22, eslint 0.
- docs: ui-audit-round2 — минор тоста помечен исправленным (открытых пунктов не осталось); stage5-checklist — supplier:rekey-orphans dry-run проверен на проде 22.06 («No orphan»), разовая миграция не нужна.
- На прод не выкачено.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- NewProjectDialog.submit(): обязательны название и источник (домен/номер/отправители по типу сигнала); ошибка показывается сразу, без обращения к серверу. +2 TDD-теста, два существующих теста обновлены под новый гейт. Полный фронт-сьют — без новых падений; проверено глазами в браузере на локалке.
- docs: пометки находок приёмки/UI/impersonation/ADR-018 приведены к фактическому прод-статусу (M-1, M-2 капча Yandex, FN-RESET/2/3/ENC, F-CSV, apiv1-rate, N-4, F-T1, F-P1 — на проде; failed_jobs очищены 494191->0; tenant 24 удалён soft-delete).
- решение владельца 22.06: admin-area доделки (saas-admin SSO, two-person approval, role-guard супер-админа, supplier fallback, обезличенный admin_user_id) сняты как отдельные задачи — доделать единым пакетом вместе с подключением Yandex SSO после ООО.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Один невалидный UTF-8-байт в выгрузке лидов crm.bp-gr.ru ронял весь импорт на
INSERT (PG: invalid byte sequence for encoding UTF8, SQLSTATE 22021). str_getcsv
пропускает любые байты, и невалидная последовательность доходила до БД.
CsvLeadsParser::parse теперь чистит невалидный UTF-8 через mb_convert_encoding
до парсинга — битый байт заменяется, строка импортируется, очередь не падает.
TDD CsvLeadsParserUtf8Test, проверено руками на PG.
Также зафиксирован вывод по FN-RLS-CTX: no-action — путь projects уже под
tenant-middleware, старый no-auth endpoint заменён, не воспроизводится.
Прод не трогался. Накат — позже вместе с остальным.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
FN-3: онбординг-confirm не ставил users.email_verified_at — поле вне fillable,
mass-assign его гасил. RegistrationService::confirm теперь forceFill is_active +
email_verified_at. TDD ConfirmSetsEmailVerifiedAtTest.
FN-2: миграция 2026_06_19_130000 дропнула таблицу reminders, но забыла
ALTER COLUMN notification_preferences SET DEFAULT — реальный DB-дефолт оставался
с мёртвым ключом reminder, расходясь с каноном schema.sql v8.45. Новая миграция
2026_06_22_120000 метаданные-only выравнивает дефолт под канон. squawk 0 issues,
применено dev+testing, проверено psql. CHANGELOG v8.50 + шапка schema.sql.
TDD NotifPrefsDefaultNoReminderTest.
FN-1 переоценён как не-баг кода: resolvePlatforms даёт B2+B3 корректно, B3-miss —
supplier-side Doubles, джоба сама ретраит. Зафиксировано в отчёте приёмки.
Прод не трогался. Накат — позже вместе с остальным.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
FN-RESET: письмо сброса строило именованный роут password.reset которого нет в SPA.
ResetPassword::createUrlUsing → /reset/{token}?email= в AppServiceProvider boot.
FN-LOGIN-ROUTE: гость без Accept json на auth:sanctum уводил в именованный роут
login которого нет → 500. redirectGuestsTo /login + render AuthenticationException
→ 401 JSON для api/*.
FN-SESSION: chromium.launch стоял вне try/catch — отказ запуска браузера маскировался
unhandled-rejection в opaque exit 1 двойник login-rejected. launch в try + top-level
catch → чистый exit 4 + JSON stderr в refresh-session.js и manage-project.js.
Тесты: PasswordResetUrlTest, UnauthenticatedApiResponseTest, node:test launch-failure
в обоих playwright-скриптах. Разбор FN-SESSION + ops-долг playwright install под
www-data + поправки отчёта приёмки + новая находка FN-INN-LOOKUP.
Прод не трогался. Накат — позже вместе с остальным.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Read-only разбор логов 22.06: FN-SESSION (заход к поставщику Playwright валится
121×/день → CsvReconcile down, зацепка к «лиды не идут»), FN-LOGIN-ROUTE
(route login не определён, класс FN-RESET), FN-FAILEDJOBS-PILE (490k мёртвых
B1+SMS, майский шторм, корень починен). Основной шум — исторический.
Добавлен промт новой сессии для сведения находок и старта правок.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Найдено владельцем post-run: forgotPassword → дефолтное Laravel-уведомление
строит URL через route('password.reset'), которого нет (SPA-роут /reset/:token).
Клиент видит «ошибка», письмо не уходит; побочно ломает анти-перебор.
Клиент-видимо, чинить до передачи продажникам. Вердикт GO формально не меняет.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Полный прогон R1–R5 на боевом liderra.ru: деньги сходятся до копейки,
изоляция 0 утечек, аудит-цепочки зелёные после teardown, нагрузка ~37x
запас, живой онбординг через реальную капчу + дайджест-email доставлен.
Омега не тронута: 1835400.00 / 1013 сделок. Критдефектов нет.
Находки FN-AUDIT / FN-1 / FN-2 / FN-3 — разработчику, на продажу не влияют.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
R3b + launch-промт: 6-значный код приходит письмом на ящик владельца (в ответе
API на проде его нет, в чужую почту исполнитель не зайдёт) → владелец читает код
и передаёт исполнителю для шага ONB-CODE. На живом онбординге владелец даёт две
вещи: решение капчи + код.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
§4.5: efir.html как телевизор владельца, формат карточки было→ожидали→стало
+ 📸 живой скриншот, пульт ▶/⏸, автопродолжение, два параллельных выхода
(техкарточка + эфир). Добавлен в список чтения и Шаг 0.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Пуленепробиваемый вход: железные запреты (омега/секреты/21:00/критдефект),
состояние прода (только омега, реальная капча, playwright ок, бэкап), что взять
у владельца, порядок R0-R5 с поправками (Татарстан=19, vid-диапазон, teardown
без name/auth_log, онбординг через ручную капчу), анти-ошибка ритуал, вердикт.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
R3b §A: капча на проде реальная (Yandex, test=false) — два способа пройти
онбординг (владелец сам регистрируется ИЛИ решает капчу в видимом Playwright);
массовый провижининг — SQL (R1). Удалённые ящики kdv1@/stels_info@ убраны из текста.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
N-4: пометка digest_sent ПОСЛЕ отправки (mark-after-send) — повтор не
дублирует И сбой джоба до отправки не теряет дайджест. TDD-тест GREEN 6/6.
N-2: инъекции R2 с TEST-диапазоном vid 9e12..1e13 → R5 чистит 4 orphan-таблицы
детерминированно по vid/lead_id, без ручного манифеста.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
N-4: SendNewLeadsDigestJob выбирал сделки received_at>now()-30min без маркера
отправки → ручной/повторный прогон (R3b велит дёргать вручную) дублировал
письмо-дайджест. Окно «непересекается» только при ровно-30-мин прогонах.
Фикс без схемы: идемпотентность по сделке через Redis SETNX
(Cache::add 'digest_sent:<id>', TTL 1 сутки) — паттерн как rate-limit
ZeroBalancePausedMail. Уже отправленная сделка в дайджест повторно не входит.
TDD: тест «повторный прогон НЕ дублирует» (RED 2 письма → GREEN 1), сюит 5/5.
R3b DIGEST-ON + owner-decisions + NEW-статус обновлены (N-4 → закрыто).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Ревью раунда 1 (полнота): инвариант §20.2 не имел шага ни в одном плане.
Добавлен Шаг 9-4: вечерний BalancePreflightSweepJob @18:00 смотрит на ЗАВТРА
(тенант мёрзнет с «+» балансом), разморозка снимает только наши паузы
(paused_at >= frozen_at_was), ручные паузы клиента сохраняются. Код-факты
сверены по BalancePreflightSweepJob.php:62/70-85/97-108 + routes/console.php.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
R5 teardown/сверки (сверено по db/schema.sql):
- N-1 (CRITICAL): TD3 падал — supplier_lead_costs БЕЗ tenant_id (→ через deal_id,
до deals) + DELETE FROM reminders по дропнутой таблице (убрано). Прежде вся
транзакция откатывалась → тест-данные оставались на боевом.
- N-2: + DELETE pd_processing_log/tenant_operations_log (по tenant_id) + нота про
orphan-таблицы инъекции без tenant_id (чистить по манифесту R2).
- N-3: нота — НЕ удалять глобальные auth_log/saas_admin_audit_log (разрыв
hash-цепочки → F3 красный); per-tenant цепочки рвутся безопасно.
- N-8: F4 маржа — supplier_lead_costs.cost_kopecks→cost_rub + JOIN deals;
lead_charges.price_kopecks→price_per_lead_kopecks (ревьюер ошибся, сверено).
R2: N-5 — предупреждение про snapshot:rebuild (DELETE без фильтра тенанта/транзакции,
снесёт слепок дня вкл. lkomega); по умолчанию backfill с явной --date.
R1: N-7 — предусловие PR2: гейт реквизитов (422 requisites_required) + preflight
баланса (409) ДО создания проектов через портал.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Закрыты doc-находки двух ревью-сессий (точность планов перед прод-прогоном):
- GAP-1: Татарстан 16→19 (16=Мордовия, конституц. порядок ст.65, НЕ ГИБДД) —
свод, план №3 (C-2), PR2 (сноска: P5 [16]=Мордовия, не Татарстан). Сверено
по RussianRegions.php.
- M-2/GAP-3: капча = NullCaptchaVerifier БЕЗУСЛОВНО (не только local) — план №18.
- lpimp-status: lpimp_ → 401 на биллинг/api-keys (не 403), 403 только на admin,
/api/billing/charges читается — план №25.
- N-6: воронка статусов НЕ форсится (любой валидный slug, нет state-machine) — план №13.
- №23-tx: импорт пишет 1 нулевую historical_import строку; сверять баланс/lead_charges,
не число balance_transactions — план №23.
- append-only: lead_charges защищён GRANT'ом (prod/crm_app_user), не триггером →
на dev-superuser правка пройдёт (ложный GREEN); гонять на проде — план №12.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Read-only разбор: код-факты денег/изоляции/распределения сверены построчно.
Блокеры до старта: Татарстан=16 неверно (19), корпус untracked, капча-Null.
Новые HIGH вне реестра: админ fail-open (=F-T2), капча отключена.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Мастер-документ точки входа для свежей сессии: тест на боевом liderra.ru,
порядок R1-R5, карта 26 планов, безопасность, эфир, вердикт GO/NO-GO.
Планы 24 помощь, 25 имперсонизация, 26 публичный API.
Поправка: F-DIGEST снята — была ошибкой чтения устаревшего комментария,
не отставанием локалки (она байт-в-байт с боевым 01a9029c). Канон-схема
db/schema.sql:796 new_lead.email:true — дайджест вкл по умолчанию. План 20
и реестр обновлены. Тесты — только на проде.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Реестр находок (сверка свода с кодом под планы):
F-CSV экспорт без защиты от CSV-инъекции (безопасность, под фикс),
F-DELPROJ удаление проекта со сделками запрещено (свод неточен),
F-DIGEST дефолт email-дайджеста по схеме выключен,
F-PDF штатность PDF-формата не подтверждена,
F-REMIND фронт-хвосты снятой фичи напоминаний,
F1-F5 прежние прогонные (F3 закрыта).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Пошаговые планы было→ожидали→стало с код-фактами file:line для пунктов:
PR2 проекты, PR3 балансы, 01 распределение CAP3, 03 каскад региона,
05 идемпотентность, 07 тройная запись, 08 тариф-ступень,
09 нехватка→откат, 10 два проекта одно списание,
13 сделки лента/карточка/статусы, 14 ручная/массовые/экспорт.
NB 14: защита экспорта от CSV-инъекции в коде не найдена — помечено как находка под проверку на прогоне.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>