# Приёмочный тест liderra.ru — пошаговые планы + ОТЧЁТЫ на каждый шаг (подтверждено кодом)

**Дата:** 20.06.2026. **Кодовая фраза стены:** «роутер-наставник».
**Назначение:** на каждый пункт свода [2026-06-20-acceptance-imitation-checks-table.md](../specs/2026-06-20-acceptance-imitation-checks-table.md) — буквальный пошаговый план, и на КАЖДЫЙ шаг **отчёт-доказательство**. Каждая строка привязана к коду портала (`app/`, file:line) — не выдумано.

## ✅ ФОРМАТ ОТЧЁТА ЗАФИКСИРОВАН (одобрен владельцем 20.06)
Каждый шаг = карточка-отчёт: **таблица `было → ожидали → стало`** → **💡 «Что произошло внутри портала» простыми словами** (без программистских слов/SQL/кода) → **📸 живые скриншоты** под объяснением (текст выше, картинки ниже) → зелёный/красный итог **«сошлось / не сошлось»**.
**Живой образец (реальный прогон PR1, настоящие снимки):** `live-demo/rep.html` (открывается на `localhost:8899/rep.html`). На него равняемся для всех пунктов.
Программистские детали (что подтверждено кодом, file:line) остаются «под капотом» в этом плане — владельцу в отчёт НЕ попадают.

## ⛔ Правило отчёта (главное)
Отчёт по шагу — НЕ слово «проверил». Каждый шаг даёт **`было → ожидалось → стало`**, и доказательство по типу данных:

| Тип факта | Чем подтверждаем | Обязательность |
|---|---|---|
| **Видно на экране портала** (Дашборд, баланс, список сделок, карточка, реквизиты, плашка, экран поставщика) | 📸 **СКРИНШОТ** «было» и «стало» | **обязателен** |
| **Внутренний процесс** (строка/счётчик в БД, запись в очередь, джоб, значение, цепочка аудита) | 📝 текст: SQL-вывод / лог / значение | текст достаточно |

Правило: **всё, что можно подтвердить визуально — подтверждаем скриншотом.** Текст — только для внутреннего, что глазами не показать.

**Формат шага:** `🔧 Код-факт (file:line)` · `🎬 Действие (буквально)` · `📋 ОТЧЁТ (таблица было/ожидалось/стало + 📸/📝)` · `❌ Если не так`.
**Где берём снимки:** локальная имитация — портал `:8000` (Playwright), `imitation:seed`; на боевом прогоне — `liderra.ru` живыми снимками в те же слоты. «Стало (факт)» в плане — слот, заполняется на прогоне.

> Готово: **PR1**. Дальше — PR2, PR3 … по списку, тем же форматом.

---

## ПУНКТ 1 — Фаза 1 · PR1: завести 7 тест-клиентов

**Цель:** 7 активных клиентов (`TEST-C1..C7`) с нужными балансами — фундамент для всех проверок.

### 🔧 Код-факты (подтверждено чтением 20.06)
- Старт-баланс самозаписи = **300.00 ₽** — [RegistrationService.php:38](../../../app/app/Services/Auth/RegistrationService.php#L38).
- Код: **6 цифр** [:216](../../../app/app/Services/Auth/RegistrationService.php#L216); **TTL 15 мин** [:34]; **5 попыток** [:36]; на проде код **только письмом** (dev-код лишь local/testing) [:231](../../../app/app/Services/Auth/RegistrationService.php#L231).
- `register` → тенант `status='pending_email_confirm'`, `balance_rub=0`, юзер `is_active=false`; письмо в очередь после commit, сбой почты не валит — [:179-245](../../../app/app/Services/Auth/RegistrationService.php#L179-L245).
- `confirm` атомарно → `verified_at`, `is_active=true`, тенант `status='active'`, `balance_rub=300.00` — [:110-117](../../../app/app/Services/Auth/RegistrationService.php#L110-L117).
- **Гейт первого проекта без реквизитов → 422** — [ProjectController.php:131-133](../../../app/app/Http/Controllers/Api/ProjectController.php#L131-L133).
- Минимум реквизитов: `subject_type+contact_name+contact_phone` (+`inn` для ЮЛ/ИП) — [RequisitesService.php:31-44](../../../app/app/Services/Requisites/RequisitesService.php#L31-L44).
- Локальный засев: `imitation:seed` (тенант factory, баланс **100000₽**, проект Москва82/лимит1000/дни127, обходит гейт через factory) — [ImitationSeedCommand.php:72-96](../../../app/app/Console/Commands/Imitation/ImitationSeedCommand.php#L72-L96).

### Популяция (R1)
| Клиент | Старт-баланс | Почта | Назначение |
|---|---|---|---|
| C1 | 100 000 ₽ (R4: ~10 млн) | kdv1@bk.ru (живой) | основной |
| C2 | 100 000 ₽ | dummy | основной |
| C3 | 100 000 ₽ | dummy | каскад СПб |
| C4 | **600 ₽** | stels_info@bk.ru (живой) | заморозка/ноль |
| C5–C7 | 100 000 ₽ | dummy | каскад/мультирегион/Москобл |

---

### Шаг A1 — Регистрация C1 (самозапись)
**🔧 Код:** [RegistrationService::register :45-77](../../../app/app/Services/Auth/RegistrationService.php#L45-L77).
**🎬 Действие:** браузером на `…/register` (лок `http://localhost:8000/register`): email `kdv1@bk.ru` + пароль + капча → отправить.

**📋 ОТЧЁТ:**
| Что | Было | Ожидалось | Стало (факт) | Чем подтверждаем |
|---|---|---|---|---|
| Экран регистрации | форма пустая | после отправки — экран «Введите код из письма» | _(слот прогона)_ | 📸 **скриншот** до (форма) и после (экран кода) |
| Тенант+юзер в БД | нет строки на этот email | `pending_email_confirm \| 0 \| f` | _(слот)_ | 📝 SQL: `SELECT t.status,t.balance_rub,u.is_active FROM tenants t JOIN users u ON u.tenant_id=t.id WHERE u.email='kdv1@bk.ru'` |
| Код подтверждения | — | строка `email_verifications` (`verified_at IS NULL`, `expires_at`≈+15м) | _(слот)_ | 📝 SQL `email_verifications` (внутр.) |
| Письмо с кодом | — | поставлено в очередь | _(слот)_ | 📝 лог/очередь (внутр.; глазами — только письмо в ящике, опц. 📸) |

**❌ Если не так:** тенант сразу `active` / баланс ≠ 0 / 2 тенанта на email → СТОП, дефект онбординга.

### Шаг A2 — Подтверждение кодом → активация + 300₽
**🔧 Код:** [RegistrationService::confirm :79-120](../../../app/app/Services/Auth/RegistrationService.php#L79-L120).
**🎬 Действие:** ввести 6-зн. код из письма (лок: из `dev_code`/лога) → подтвердить.

**📋 ОТЧЁТ:**
| Что | Было | Ожидалось | Стало (факт) | Чем подтверждаем |
|---|---|---|---|---|
| Дашборд клиента | вход недоступен | вход в кабинет, на дашборде баланс **300 ₽** | _(слот)_ | 📸 **скриншот** Дашборда с балансом 300₽ |
| Статус/баланс в БД | `pending \| 0 \| f` | `active \| 300.00 \| t` | _(слот)_ | 📝 SQL (та же строка) |
| Код погашен | `verified_at IS NULL` | `verified_at` проставлен | _(слот)_ | 📝 SQL `email_verifications` (внутр.) |

**❌ Если не так:** активация без кода / баланс ≠ 300 / частичная активация → СТОП.

### Шаг A3 — То же для C4 (`stels_info@bk.ru`)
Повтор A1+A2; баланс позже опустим до 600₽ (Шаг C1). **📸** скриншот Дашборда C4 (300₽ до правки).

### Шаг B1 — Остальные 5 (C2,C3,C5,C6,C7) служебно
**🔧 Код:** [ImitationSeedCommand :72-96](../../../app/app/Console/Commands/Imitation/ImitationSeedCommand.php#L72-L96) (лок) / SQL-INSERT (прод, owner-escape).
**🎬 Действие (лок):** `cd app && php artisan imitation:seed --clients=7 --leads=1` → печатает логин первого клиента.
**🎬 Действие (прод):** SQL-INSERT `tenants`(`TEST-C…`, `active`, баланс)+`users`(bcrypt, `is_active=true`).

**📋 ОТЧЁТ:**
| Что | Было | Ожидалось | Стало (факт) | Чем подтверждаем |
|---|---|---|---|---|
| Клиенты в БД | 0 тест-клиентов | 7 тенантов, баланс по таблице | _(слот)_ | 📝 SQL `SELECT id,organization_name,balance_rub,status FROM tenants WHERE … ORDER BY id` |
| Вход в кабинет | — | вход каждым работает | _(слот)_ | 📸 **скриншот** Дашборда хотя бы одного засеянного клиента |

**❌ Если не так:** seed упал на prod-гварде (он local-only) / Postgres не поднят → проверить env=local, `:5432`. Вход не идёт → bcrypt/`is_active`.

### Шаг C1 — Балансы под сценарии (PR3)
**🎬 Действие:** C4 → **600 ₽**; для R4 поднять C1–C3,C5–C7 до ~10 млн (`UPDATE tenants SET balance_rub=…`; прод — админ append-only/escape).

**📋 ОТЧЁТ:**
| Что | Было | Ожидалось | Стало (факт) | Чем подтверждаем |
|---|---|---|---|---|
| Баланс C4 на дашборде | 300 ₽ | 600 ₽ | _(слот)_ | 📸 **скриншот** Дашборда C4 (600₽) |
| Балансы в БД | старые | целевые | _(слот)_ | 📝 SQL `SELECT id,balance_rub FROM tenants WHERE …` |

---

### Verification PR1 (выход из пункта)
- [ ] 📸 7 кабинетов: вход работает (скрин Дашборда каждого или сводный).
- [ ] 📸 C1/C4 через самозапись — баланс **300₽** на дашборде заскринен (Путь A).
- [ ] 📸 C4 после правки — **600₽**.
- [ ] 📝 SQL: 7 тенантов с верными балансами/статусами.
- [ ] (для PR2) перед первым проектом каждого — заполнить реквизиты (иначе гейт 422).

### 📸 vs 📝 в этом пункте — что снимаем, что текстом
- **📸 Скриншот (визуально):** экран Регистрации (форма → экран кода), **Дашборд с балансом** (300₽ онбординг / 100000₽ factory / 600₽ C4), вход в кабинет.
- **📝 Текст (внутренний процесс):** строки `tenants/users/email_verifications`, постановка письма в очередь, погашение кода — глазами в портале не видны → SQL/лог.

### Грабли (troubleshooting R1/R3b)
- Капча на проде реальная → самозапись руками; масса — Путь B.
- Письмо с кодом — в очереди, нужен живой воркер `liderra-queue`; на проде кода в ответе API нет.
- 2 живых ящика → онбординг-путь только 2 клиента, остальные служебно.

---

> **Следующие пункты** (PR2 проекты+12 rt у поставщика, PR3, Фаза 2 инъекция, проверки #1…#26, Фаза 4–5) — дописываются этим же форматом: каждый шаг = отчёт `было→ожидалось→стало` с 📸 для визуального и 📝 для внутреннего.
