# Приёмочный тест liderra.ru — таблица «что мы будем делать» (под имитацию-отчёты)

**Дата:** 20.06.2026. **Кодовая фраза стены:** «роутер-наставник» (на момент составления стена снята).
**Назначение:** зафиксировать ПОЛНЫЙ объём проверок приёмочного теста (свод из всех ранбуков R0–R5 + R3b),
с указанием, **какие разделы портала меняются** на каждой проверке — это то, что снимаем «глазами»
(живые скриншоты Баланс/Сделки/… + список влитых лидов). Под этот свод строятся имитации-отчёты по типам проверок.

**Источники (прочитаны целиком):**
- R0 старт/доступ/безопасность — `docs/superpowers/runbooks/2026-06-18-acceptance-r0-start-access-safety.md`
- R1 провижининг 7/16 — `…/2026-06-18-acceptance-r1-provisioning.md`
- R2 инъекционный стенд — `…/2026-06-18-acceptance-r2-injection-stand.md`
- R3 движок (распределение/деньги/сделки/изоляция + all-pairs) — `…/2026-06-18-acceptance-r3-engine.md`
- R3b онбординг/дайджест/отчёты/импорт — `…/2026-06-18-acceptance-r3b-onboarding-digest.md`
- R4 нагрузка/ёмкость — `…/2026-06-18-acceptance-r4-load-capacity.md`
- R5 финал/teardown/отчёт — `…/2026-06-18-acceptance-r5-finalize-teardown.md`
- Карта логики прода — `…/specs/2026-06-18-prod-logic-map.md`; хартия — `…/specs/2026-06-18-acceptance-test-charter.md`
- Формат показа (телевизор-доказательство) — `…/specs/2026-06-19-acceptance-televizor-proof-design.md`

> **✅ Сверено с ТЕКУЩИМ кодом портала 20.06.2026** (`app/`, до коммита `d041acf1`; деплой **G1–G7** на боевом 19.06). Помимо ранбуков R0–R5/R3b, найдены **3 новые клиентские фичи деплоя 19.06**, которых не было в исходных ранбуках (18.06) — добавлены ниже в **Фазу 3в** (строки 24–26):
> **G7-A «Помощь»**, **G7-B импер­сонизация (клиентская плашка)**, **G6 публичный API сделок + UI API-ключей**.
> ⚠️ Старый список хартии «заведомо сломанное, НЕ тестируем (…G6 API-ключи, G7 impersonation…)» по этим пунктам **устарел** — G6/G7 теперь реализованы и выкачены; их надо тестировать. **G5** (пополнение/счета) — по-прежнему заглушка (ждёт ООО), не тестируем.

> **Деньги нигде не зашиты** — цена берётся из живой `pricing_tiers` (на 19.06: T1 500₽…T7 250₽; планируется ≤65₽ — всегда сверять с БД).
> **Регионы — порядковые 1..89:** Москва=82, СПб=83, **Татарстан=19** (16=Мордовия — конституционный порядок ст.65, НЕ ГИБДД-коды), Москобл=56 (не маппится у поставщика).
> **Безопасность:** не трогать `lkomega`/tenant 2 и живую поставку; rt-проекты у поставщика чистить ДО 21:00 МСК; тест-объекты — маркер `TEST-`.

---

## Фаза 1 — Стенд (R1): кого/что заводим
| Карточка | Что делаем | Ожидаем | Видно глазами |
|---|---|---|---|
| PR1 | завести **7 тест-клиентов** `TEST-C1..C7` (онбординг или SQL); балансы: C1–C3,C5–C7 = 100 000₽, **C4 = 600₽** | 7 тенантов, вход каждым работает | вход в Кабинет |
| PR2 | завести **16 проектов через ПОРТАЛ** (не SQL — иначе нет синка к поставщику) | 16 проектов → **12 rt у поставщика**, pivot заполнен | Проекты, экран Поставщика |
| PR3 | выставить балансы под сценарии (C4 малый; под R4 — поднять до ~10 млн) | балансы выставлены | Баланс |
| PR4 | собрать парный teardown-скрипт | список id для отката готов | — |

## Фаза 2 — Инструмент инъекции (R2): как вливаем лид
| Карточка | Что делаем | Ожидаем |
|---|---|---|
| I0 | проверить секрет вебхука ≥32, IP-allowlist, активную дату | стенд готов, иначе 404 |
| I2 | построить слепок активной даты (`snapshot:backfill`) | тест-проекты в слепке |
| I4/I5 | POST вебхук (B-канал `B2_…` / DIRECT) | 202 accepted; повтор vid → 200 already_processed |
| I6/I7 | проверить обработку; влить **пачку** (для шеринга/нагрузки) | сделки созданы, инварианты целы |
| T1 | TOTP-код для 2FA | 6 цифр, вход проходит |

## Фаза 3 — Движок (R3): корректность — «при инъекции меняются Баланс и Сделки»
| # | Тип проверки (карточки) | Что делаем | Ожидаем (по логике) | Видно глазами (разделы) |
|---|---|---|---|---|
| 1 | **Распределение / CAP=3** (D-CAP) | влить 1 лид при 7 клиентах на источнике | ровно ≤3 получателя, по одному на тенант | **Сделки** (у 3), **Баланс** (−цена у 3), Поставщик |
| 2 | **Второй круг** (D-ROUND) | влить серию ~15 лидов | все 7 обслужены, никто > дневного лимита | **Сделки**+**Баланс** всех 7 |
| 3 | **Каскад региона** (D-CASCADE 1/2/3) | лид точного / «вся РФ» / непокрытого региона | фаза1→2→3; при подмене город=реальный регион | **Сделки** (город), БД `region_substituted` |
| 4 | **Лимит/пауза под локом** (D-LIMIT/D-PAUSE) | поток > лимита; пауза «на лету» | лимит не превышен; паузнутый лид не получает | **Сделки**, БД `delivered_today` |
| 5 | **Идемпотентность** (D-IDEMP/DELIV/MERGE) | повтор vid; дубль поставки; merge с CSV-recovery | один лид = одно списание, без дублей | **Баланс** (нет 2-го списания), **Сделки** |
| 6 | **DIRECT/парсинг** (D-DIRECT/PARSE) | лиды `B1/B2/B3` / домен / звонок / смс | площадка/тип определены верно | **Сделки** |
| 7 | **Деньги: списание + тройная запись** (M1) | 1 лид → списание | −цена ступени; 3 записи (charge+txn+cost); копейки сходятся | **Баланс** (лента денег), БД-сверка |
| 8 | **Тариф-ступень** (M-TIER) | лиды через порог ступени | цена падает ровно на нужном по счёту лиде | **Баланс** (лента), БД |
| 9 | **Нехватка → откат** (M-INSUFF/M-BAL0) | лид клиенту с балансом < цены | полный откат + автопауза проекта + письмо (1/час) | **Баланс**, **Проекты** (пауза), письмо |
| 10 | **Два проекта = одно списание** (M-DOUBLEPROJ) | лид клиенту с 2 проектами на источнике | одно списание (DISTINCT по тенанту) | **Баланс**, **Сделки** |
| 11 | **Лента денег = БД + калькуляторы** (M-LEDGER/M-CALC) | открыть кошелёк + выгрузку CSV | строки=БД, остаток монотонно, «хватит на…» верно | **Баланс** |
| 12 | **Денежный аудит** (M-AUDIT) | `audit:verify-chains`; правка ledger | цепочка цела; UPDATE/DELETE заблокированы | БД/аудит |
| 13 | **Сделки: лента/карточка/статусы** (T-LIST/CARD/STATUS) | фильтры, карточка, воронка статусов | число=БД; цена≠0; «won» НЕ списывает повторно | **Сделки** |
| 14 | **Ручная / массовые / экспорт** (T-MANUAL/BULK/EXPORT) | создать вручную, bulk-действия, экспорт CSV/XLSX | ручная не трогает баланс; удаление не возвращает деньги; экспорт=БД, CSV-инъекция экранирована | **Сделки**, **Баланс** |
| 15 | **Удаление проекта со сделками запрещено** (T-DELPROJ) | удалить проект со сделками | **422** «нельзя удалить: есть сделки, поставьте приём на паузу»; удаляется только пустой проект; сделки целы | **Сделки**, **Проекты** |
| 16 | **Изоляция** (ISO-SECTIONS/SHARE/DIRECT/NEG/GLOBAL) | под c1 и c8 смотреть свои/чужие | только своё; шеринг не течёт; чужой ID→404/403; RLS=0 | **все разделы** обоих кабинетов |
| 17 | **All-pairs (27 прогонов)** | S×R×B×Lim×D по матрице R3 Часть E | каждая из 111 пар покрыта | **Сделки**+**Баланс** |

## Фаза 3б — Онбординг и UI (R3b, после деплоя G1/G2/G3 — уже на проде)
| # | Тип проверки (карточки) | Что делаем | Ожидаем | Видно глазами |
|---|---|---|---|---|
| 18 | **Онбординг-самозапись** (ONB-REG/CODE/ATTEMPTS/RESEND/CAPTCHA) | почта+пароль+капча+код из письма | тенант `pending_email_confirm`→`active`, старт **300₽**; лимит 5 попыток/TTL 15м | экран регистрации, Дашборд (300₽), письмо |
| 19 | **Гейт реквизитов + ИНН** (ONB-REQ-GATE/INN/FULL) | создать первый проект без реквизитов; ИНН по DaData | `requisites_required`; после ИНН/ФИО+тел гейт снят; чип «Готово к оплате» | вкладка Реквизиты, Проекты |
| 20 | **Колокольчик + дайджест** (BELL/DIGEST/PUSH-DEAD) | влить лиды → кабинет/почта | колокольчик на каждый лид; письмо-**дайджест** раз в 30 мин (вкл. по умолч.); push мёртв | Уведомления, письмо |
| 21 | **Напоминания убраны** (REM-GONE) | искать раздел/URL/таблицу `reminders` | нет нигде (меню/URL/эндпоинт/таблица) | меню, URL |
| 22 | **Отчёты** (RPT-TYPES/QUEUE/DOWNLOAD/ISO) | 4 типа × 3 формата; квота 3; signed-URL | числа=БД; PDF→`failed` штатно; изоляция; ссылка 24ч | Отчёты |
| 23 | **Импорт CSV** (IMP-OK/IDEMP/STATUS/VALID/ISO) | загрузить тест-CSV | сделки появились; **баланс НЕ списан**; без дублей; мастер статусов | **Сделки**, **Баланс** |

## Фаза 3в — Новые клиентские фичи деплоя 19.06 (G6/G7) — НЕ были в исходных ранбуках
> Найдены сверкой с текущим кодом 20.06. Подтверждены файлами в `app/` (контроллеры/Vue/миграции/тесты).

| # | Тип проверки | Что делаем | Ожидаем (по коду) | Видно глазами (разделы) |
|---|---|---|---|---|
| 24 | **«Помощь» — заявка в поддержку** (G7-A) | в кабинете раздел **«Помощь»** → заполнить форму (Имя/Контакт/Сообщение, предзаполнены из профиля) → отправить | `201`, запись в `support_requests` (tenant_id=свой) **создаётся всегда**; письмо на `support.email` — best-effort (сбой почты не валит заявку); валидация (пусто→422); JivoSite-чат виден, если задан `JIVO_WIDGET_ID`; RLS — клиент видит только свои | раздел **Помощь** (форма, алерт «Заявка отправлена»), письмо поддержке, чат-виджет |
| 25 | **Импер­сонизация — клиентская сторона** (G7-B) | админ/ИИ входит в кабинет: запрос (`reason≥30`) → клиенту **письмо с 6-зн. кодом** (TTL 15 мин) → ввод кода → вход; ИИ получает машинный ключ `lpimp_…` | у клиента в кабинете — **красная плашка** «Вы в кабинете… режим поддержки [Выйти]» (из `/api/auth/me .impersonation.active`); кнопка **Выйти** завершает сессию; **письма** «код-согласие» и «сессия завершена»; авто-истечение **1 час**; ключ `lpimp_` НЕ пускает в биллинг/`/api/api-keys`/`/api/admin/*` (403); чужой/битый Bearer → 401 | **плашка** в кабинете, кнопка Выйти, 2 письма клиенту; (для безопасности — БД `impersonation_tokens`, аудит) |
| 26 | **Публичный API сделок + API-ключи** (G6) | в **Настройки → «API и Webhook»** перегенерировать ключ (`lpkapi_…`, показывается один раз, TTL 365д, один активный) → запрос `GET /api/v1/deals` с `Authorization: Bearer lpkapi_…` | UI отдаёт ключ один раз + префикс; API → JSON `{data:[{id,received_at,phone,contact_name,city,status,project}], next_cursor}`; cursor-пагинация (limit 1–500), фильтр `since`; **только свои сделки** (RLS+явный where); без/битый/просроченный ключ → 401, нет scope `read` → 403; `last_used_at/ip` пишутся; rate-limit пока НЕТ | **Настройки → API** (создание/копирование/маска ключа), ответ API (JSON), **Сделки** (сверка чисел с UI) |

## Фаза 4 — Нагрузка (R4): сервер и канал к поставщику
| Карточка | Что делаем | Ожидаем | Видно глазами |
|---|---|---|---|
| L0/LD1 | базовая линия; стоимость одной операции | один воркер; запас памяти (2 ГБ!) | Сервер |
| LD2 | влить 500–1000 лидов спокойным темпом | гистограмма раздачи по 7; списания по ступеням; кто заблокирован | **Сделки/Баланс 7**, Сервер |
| LD3/LD4 | адаптивный ramp темпа + правки проектов разом, до SAFETY-стопа | кривая темп→нагрузка; потолок; узкое место (воркер/БД/память/канал) | Сервер + канал |
| M-METRICS/SAFETY | снимать метрики (очередь/CPU/память/БД/канал); пороги стопа | не уронить прод (lkomega спит рядом) | Сервер |
| D-SUMMARY | вывод по ёмкости | «X лидов/сут безопасно; 10k=Y%; рекомендация по железу» | отчёт |

## Фаза 5 — Финал (R5): сверки + уборка + вердикт
| Карточка | Что делаем | Ожидаем |
|---|---|---|
| F1 | Σ списаний = (старт − текущий) по копейкам, на каждом тенанте | сходится |
| F2 | финальная изоляция (повтор разделов + ISO-NEG) | 0 утечек |
| F3 | `audit:verify-chains` | зелёно по 6 audit-таблицам |
| F4 | маржа: выручка (`lead_charges`) vs себестоимость (`supplier_lead_costs`) | сводка владельцу |
| TD1 | убрать тест rt-проекты у поставщика **ДО 21:00 МСК** | у поставщика тест-rt нет |
| TD2–TD4 | слепки → тест-тенанты (trigger-bypass под postgres) → Redis | тест-данные удалены |
| TD5 | проверка чистоты + сохранность tenant 2 (lkomega) | 0 тест-объектов, tenant 2 цел |
| REPORT | итоговый отчёт + вердикт **GO/NO-GO** | GO = 0 расхождений деньги+изоляция, ядро проходит сквозь |

---

## Открытые решения (зафиксировать перед сборкой имитаций)
1. **Формат скриншотов:** рисованные двойники (быстро, сейчас) ИЛИ живые снимки локального портала (надо поднять локальный прогон: `imitation:seed` создаёт клиентов+вливает лиды → реальные Баланс/Сделки). Владелец хочет **живые снимки** разделов **Баланс** и **Сделки** + **список влитых лидов**.
2. **Порядок сборки имитаций-отчётов:** по фазам (3 → 3б → 4) или сначала самые денежно-критичные типы (распределение, деньги, нехватка→откат, изоляция).
3. **Объём демонстрации одновременно:** все 7 кабинетов реальными снимками (нужен поднятый сервер/прогон) — предел имитации.

## Связанные артефакты
- Прототип «телевизора»-плеера и образец отчёта по типу проверки — `live-demo/` (player.html, proof.html), localhost:8899.
- Локальный портал готов: Laravel 13.15 на `:8000`, Postgres 5432 + Redis 6379; команда `php artisan imitation:seed --clients=N --leads=M` (local-only) — создаёт клиентов и реально вливает лиды через `RouteSupplierLeadJob`.
