# Приёмка liderra.ru — ПУНКТ №2: Второй круг (серия заявок раздаётся всем честно)

> **Для исполнителя:** формат PR1 (одобрен 20.06). Каждый шаг = `🔧 Код-факт (file:line)` · `🎬 Действие` · `📋 ОТЧЁТ (было→ожидали→стало + 📸/📝)` · `❌ Если не так`. Техника «под капотом»; владельцу — человеческие карточки.

**Цель:** показать, что на **серии** заявок (не одной, а потоком) раздача честная: со временем заявки достаются **всем** подходящим клиентам (не одни и те же снимают всё), и **никто не получает больше своего дневного лимита**. Портал отдаёт предпочтение тем, у кого больше свободных слотов — поэтому очередь выравнивается.

**Что снимаем глазами:** **Сделки** и **Баланс** всех 7 клиентов — у каждого появились заявки, ни у кого не больше лимита. Живые 📸.

**Источник сценария:** свод проверок №2 (D-ROUND); R3 «движок».

---

## 🔧 Код-факты (подтверждено чтением 20.06)

- **Жребий выравнивает по остатку лимита** — кандидаты сортируются `ORDER BY (snap.daily_limit − projects.delivered_today) DESC` — [LeadRouter.php:154-157](../../../app/app/Services/LeadRouter.php#L154-L157); взвешенный отбор: вероятность ∝ остатку лимита, мелкие не отрезаются — [weightedPick :171](../../../app/app/Services/LeadRouter.php#L171).
- **Дневной лимит не превышается** — в отбор попадают только `delivered_today < daily_limit` — [:145](../../../app/app/Services/LeadRouter.php#L145).
- **CAP=3 на каждую заявку** — [LeadDistributor.php:22](../../../app/app/Services/LeadDistributor.php#L22): за серию из N заявок суммарно до N×3 доставок, распределённых по 7 клиентам в рамках их лимитов.
- Счётчик `delivered_today` растёт при каждой доставке — снижает шанс «перегруженного» клиента в следующих заявках.

---

## Шаг 2-1 — Влить серию (~15 заявок) на источник всех 7

**🔧 Код:** отбор/жребий — [LeadRouter :104-171](../../../app/app/Services/LeadRouter.php#L104-L171); CAP — [LeadDistributor :22-43](../../../app/app/Services/LeadDistributor.php#L22-L43).
**🎬 Действие (лок):** влить ~15 заявок подряд на источник, где подходят все 7 клиентов (это сценарий засева `imitation:seed --clients=7 --leads=15`).

**📋 ОТЧЁТ:**
| Что | Было | Ожидалось | Стало (факт) | Чем подтверждаем |
|---|---|---|---|---|
| Получили заявки | 0 | **все 7 клиентов** обслужены (никто не пустой) | _(слот прогона)_ | 📸 Сделки каждого из 7 (есть заявки) |
| Распределение | — | примерно равномерно (жребий по остатку лимита) | _(слот)_ | 📸 сводка по 7 (близкие числа) |
| Всего доставок | — | ≈ 15×3 = 45 (по 3 на заявку) | _(слот)_ | 📝 SQL `COUNT deals` за серию |

**💡 Что внутри:** когда заявки идут потоком, портал следит, чтобы они доставались всем по очереди, а не оседали у первых. Он отдаёт предпочтение тем, у кого ещё много свободных мест на сегодня — поэтому отстающие догоняют, и через серию заявки получают все семеро примерно поровну.

**❌ Если не так:** часть клиентов осталась без заявок при свободном лимите → перекос раздачи.

---

## Шаг 2-2 — Никто не получил больше своего дневного лимита

**🔧 Код:** фильтр лимита — [LeadRouter :145](../../../app/app/Services/LeadRouter.php#L145).
**🎬 Действие (лок):** у каждого из 7 сверить число полученных за день с его дневным лимитом.

**📋 ОТЧЁТ:**
| Что | Было | Ожидалось | Стало (факт) | Чем подтверждаем |
|---|---|---|---|---|
| Доставлено за день каждому | — | **≤ дневного лимита** у всех | _(слот)_ | 📸 Сделки/счётчик дня; 📝 SQL `delivered_today ≤ daily_limit` |
| Клиент у лимита | — | по достижении лимита больше не получает | _(слот)_ | 📸 его список перестал расти |

**💡 Что внутри:** у каждого клиента есть дневной потолок — сколько заявок в день он готов взять. Портал его соблюдает: как только клиент набрал свой лимит, новые заявки идут другим, а не сверх оплаченного объёма.

**❌ Если не так:** кто-то получил сверх лимита → дефект (клиент платит за лишнее).

---

## Шаг 2-3 — Деньги по серии сходятся у всех

**🔧 Код:** списание — [LedgerService :53-95](../../../app/app/Services/Billing/LedgerService.php#L53-L95).
**🎬 Действие (лок):** у нескольких клиентов сверить: число сделок × цена = уменьшение баланса.

**📋 ОТЧЁТ:**
| Что | Было | Ожидалось | Стало (факт) | Чем подтверждаем |
|---|---|---|---|---|
| Баланс vs сделки | — | у каждого: списано = (число сделок × цена ступени) | _(слот)_ | 📸 Баланс + Сделки клиента |

**❌ Если не так:** баланс не бьётся с числом сделок → денежный дефект (связка с №7).

---

## Verification №2 (выход из пункта)
- [ ] 📸 Все 7 клиентов получили заявки (никто не пустой при свободном лимите).
- [ ] 📸 Распределение примерно равномерное (жребий по остатку лимита).
- [ ] 📸/📝 Никто не превысил дневной лимит.
- [ ] 📸 Деньги сходятся у каждого (сделки × цена = списано).

## 📸 vs 📝 в этом пункте
- **📸 Скриншот:** Сделки и Баланс всех 7 (или сводка), счётчик дня у клиента-у-лимита.
- **📝 Текст:** `COUNT deals`, `delivered_today` vs `daily_limit` — частично текстом.

## Грабли
- Жребий случайный — равномерность приблизительная, не точная; смотрим, что все обслужены и лимиты целы, а не идеальное равенство.
- Дневной лимит — отдельная страховка; «пауза на лету» — пункт №4.
- Связка с №1 (CAP на одну заявку) — здесь проверяем поведение на серии.
