diff --git a/docs/observer/STATUS.md b/docs/observer/STATUS.md index 76996eec..37f58fcc 100644 --- a/docs/observer/STATUS.md +++ b/docs/observer/STATUS.md @@ -1,6 +1,6 @@ # Brain Status (auto-generated) -Last updated: 2026-06-21T11:34:36.544Z +Last updated: 2026-06-22T01:29:09.831Z | Контролёр | Состояние | Детали | |---|---|---| @@ -46,22 +46,22 @@ Last updated: 2026-06-21T11:34:36.544Z | Время | Действие | Причина | |---|---|---| -| 2026-06-21T11:20:27.250Z | write:c:/моя/проекты/claude-brain | разговорный режим: только думать/спрашивать (реализация — после печати артефакта и плана) | -| 2026-06-21T11:20:18.178Z | write:c:/users/administrator/.claude/projects/c--------------claude-brain/dbbe0ee2-5c67-4b7f-87c5-7f47f8bd14bd.jsonl | path «C:/Users/Administrator/.claude/projects/c--------------claude-brain/dbbe0ee2-5c67-4b7f-87c5-7f47f8bd14bd.jsonl» pr | -| 2026-06-21T11:20:10.771Z | bash:cat "$TEMP/claude-economy-dbbe0ee2-5c67-4b7f-87c5-7f47f8bd14bd.json" 2>/dev/null \|\| echo "FILE_NOT_FOUND" | разговорный режим: только думать/спрашивать (реализация — после печати артефакта и плана) | -| 2026-06-21T11:20:10.641Z | bash:cat "$TEMP/claude-economy-dbbe0ee2-5c67-4b7f-87c5-7f47f8bd14bd.json" 2>/dev/null \|\| echo "FILE_NOT_FOUND" | floor: опасная по содержанию команда без аварийного выхода — блок (правило 8); FLOOR-ESCAPE: bash:cat "$TEMP/claude-econ | -| 2026-06-21T11:19:59.051Z | write:c:/моя/проекты/claude-brain | разговорный режим: только думать/спрашивать (реализация — после печати артефакта и плана) | -| 2026-06-21T11:19:48.786Z | write:c:/users/administrator/.claude/projects/c--------------claude-brain/dbbe0ee2-5c67-4b7f-87c5-7f47f8bd14bd.jsonl | path «C:/Users/Administrator/.claude/projects/c--------------claude-brain/dbbe0ee2-5c67-4b7f-87c5-7f47f8bd14bd.jsonl» pr | -| 2026-06-21T11:19:43.736Z | bash:cat "$TEMP/claude-economy-dbbe0ee2-5c67-4b7f-87c5-7f47f8bd14bd.json" 2>/dev/null \|\| echo "FILE_NOT_FOUND" | разговорный режим: только думать/спрашивать (реализация — после печати артефакта и плана) | -| 2026-06-21T11:19:43.631Z | bash:cat "$TEMP/claude-economy-dbbe0ee2-5c67-4b7f-87c5-7f47f8bd14bd.json" 2>/dev/null \|\| echo "FILE_NOT_FOUND" | floor: опасная по содержанию команда без аварийного выхода — блок (правило 8); FLOOR-ESCAPE: bash:cat "$TEMP/claude-econ | -| 2026-06-21T11:10:44.290Z | write:c:/моя/проекты/claude-brain | разговорный режим: только думать/спрашивать (реализация — после печати артефакта и плана) | -| 2026-06-21T11:10:36.250Z | bash:ls "$TEMP/claude-economy-dbbe0ee2-5c67-4b7f-87c5-7f47f8bd14bd.json" 2>/dev/null && cat "$TEMP/claude-economy-dbbe0e | разговорный режим: только думать/спрашивать (реализация — после печати артефакта и плана) | +| 2026-06-22T01:24:53.653Z | write:c:/моя/проекты/claude-brain/docs/superpowers/plans/2026-06-22-secretary-commit-plan-v3.md | [судья] замечание (нужно учесть и переписать): — [heavy] verifiability: шаг 2 (verify) не привязан к условию остановки п | +| 2026-06-22T01:12:24.845Z | bash:node --version | разговорный режим: только думать/спрашивать (реализация — после печати артефакта и плана) | +| 2026-06-21T18:19:28.116Z | write:c:/моя/проекты/claude-brain | разговорный режим: только думать/спрашивать (реализация — после печати артефакта и плана) | +| 2026-06-21T18:19:08.658Z | write:c:/users/administrator/.claude/projects/c--------------claude-brain/42e79641-ee05-4ee7-97ea-3a545ea2a538.jsonl | path «C:/Users/Administrator/.claude/projects/c--------------claude-brain/42e79641-ee05-4ee7-97ea-3a545ea2a538.jsonl» pr | +| 2026-06-21T18:19:04.016Z | bash:cat "$TEMP/claude-economy-42e79641-ee05-4ee7-97ea-3a545ea2a538.json" 2>/dev/null \|\| echo "FILE_NOT_FOUND" | разговорный режим: только думать/спрашивать (реализация — после печати артефакта и плана) | +| 2026-06-21T18:19:03.911Z | bash:cat "$TEMP/claude-economy-42e79641-ee05-4ee7-97ea-3a545ea2a538.json" 2>/dev/null \|\| echo "FILE_NOT_FOUND" | floor: опасная по содержанию команда без аварийного выхода — блок (правило 8); FLOOR-ESCAPE: bash:cat "$TEMP/claude-econ | +| 2026-06-21T18:18:51.308Z | write:c:/моя/проекты/claude-brain | разговорный режим: только думать/спрашивать (реализация — после печати артефакта и плана) | +| 2026-06-21T18:18:40.831Z | bash:ls "C:/Users/Administrator/.claude/projects/c--------------claude-brain/" \| head -20 | разговорный режим: только думать/спрашивать (реализация — после печати артефакта и плана) | +| 2026-06-21T18:18:21.063Z | write:c:/users/administrator/.claude/projects/c--------------claude-brain/42e79641-ee05-4ee7-97ea-3a545ea2a538.jsonl | path «C:/Users/Administrator/.claude/projects/c--------------claude-brain/42e79641-ee05-4ee7-97ea-3a545ea2a538.jsonl» pr | +| 2026-06-21T18:16:55.088Z | powershell:npx vitest run tools/secretary-flag.test.mjs tools/secretary-protocol.test.mjs tools/secretary-slice.test.mjs | разговорный режим: только думать/спрашивать (реализация — после печати артефакта и плана) | ## Метрики (информационные, не алерты) - Observer evidence: 2353 episodes this month, 0 observer_error markers, 65 PII matches before filter - Legacy v1 episodes (not in factor analysis): 2353 -- Last /brain-retro: 25 day(s) ago +- Last /brain-retro: 26 day(s) ago - Использование узлов: см. `/brain-retro` (раз в спринт). missed_activations: 0. **Неиспользованные узлы — не алерт, если профильной задачи не было** (Pravila §16.4 v1.36; capability-readiness; см. memory `feedback_brain_unused_tools_not_problem` — outside-repo memory store). ## Метрики дисциплины @@ -135,7 +135,14 @@ Episodes since last run: 542 / threshold: 10 ## System Health -Долго работающих процессов нет (порог CPU > 1ч). +Топ-3 процессов с CPU > 1ч: + +| PID | Имя | CPU-время | Возраст | +|---|---|---|---| +| 1084 | Code | 1.71ч | NaNч | +| 3448 | MsMpEng | 1.53ч | 0.0ч | + +⚠️ Проверь, не «осиротевшие» ли это процессы от завершённых Claude-сессий. ## Очередь обучения роутера @@ -149,7 +156,7 @@ Episodes since last run: 542 / threshold: 10 ## Целостность журналов действий -🔴 Битые цепочки (3 из 102): +🔴 Битые цепочки (3 из 104): | session | broken at seq | |---|---| diff --git a/docs/superpowers/specs/2026-06-21-acceptance-RUN-report.md b/docs/superpowers/specs/2026-06-21-acceptance-RUN-report.md new file mode 100644 index 00000000..7e18ed46 --- /dev/null +++ b/docs/superpowers/specs/2026-06-21-acceptance-RUN-report.md @@ -0,0 +1,104 @@ +# Результат приёмочного теста боевого liderra.ru — 22.06.2026 + +**Прогон:** 22.06.2026, ~05:46–07:30 МСК, на боевом `liderra.ru`. Кодовая фраза стены: «роутер-наставник». +**Исполнитель:** сессия-исполнитель по `2026-06-21-acceptance-EXECUTOR-LAUNCH-prompt.md`. +**Метод:** провижининг тест-популяции (SQL + портал), контролируемые инъекции вебхука с прод-сервера (vid TEST-диапазон `9e12..9.99e12`), сверка в боевой БД (read-only), живой онбординг владельцем (реальная капча + код из письма), нагрузка с safety-стопом, полный teardown. + +--- + +## 🟢 ВЕРДИКТ: **GO** + +Деньги сходятся копейка-в-копейку, изоляция без утечек, аудит-цепочки зелёные после уборки, ядро (раздача→списание→сделка→изоляция) проходит сквозь на боевом, критдефектов нет. **Омега (tenant 2, «Компания 1») за весь прогон не тронута: 1 835 400.00 ₽ / 1013 сделок — до и после.** UX/мелкие находки GO не блокируют (список ниже). + +--- + +## Сводка по пунктам + +| Этап / пункт | Статус | Заметка | +|---|---|---| +| R1 провижининг (7 клиентов / 16 проектов / 14 rt у поставщика) | PASS | rt созданы у crm.bp-gr.ru (реальные external_id, sync ok) | +| R2 инъекционный стенд (секрет/allowlist/слепок/вебхук) | PASS | инъекция с прод-сервера 127.0.0.1, vid TEST-диапазон | +| R3 CAP=3 (раздача ≤3 разным) | PASS | московский лид → ровно 3 региона-82 | +| R3 идемпотентность (повтор vid) | PASS | already_processed, без новых сделок/списаний | +| R3 лимит под локом + перелив фаза-2 | PASS | лимит 10 не пробит; перелив на всяРФ-клиента | +| R3 M-DOUBLEPROJ (клиент с 2 проектами) | PASS | 12 лидов = 12 списаний (не 24); субдомен→корень | +| R3 каскад фаза-1/2/3 + подмена | PASS | точный→всяРФ→подмена; город = РЕАЛЬНЫЙ (Краснодарский край) при subject_code=82 | +| R3 DIRECT (bare project) | PASS | platform=DIRECT, матч по типу+идентификатору | +| R3 M1 тройная запись + копейки | PASS | lead_charges+balance_transactions+supplier_lead_costs согласованы | +| R3 M-TIER (тарифная ступень) | PASS | 101-й лид → T2 65₽ (живой тариф сменился сегодня) | +| R3 M-INSUFF (нехватка → откат+автопауза) | PASS | баланс 50₽: 0 сделок, 0 списаний, проект на автопаузе | +| R3 изоляция (портал 404 + RLS-роль + негатив) | PASS | C1 не видит C2 (404); crm_app_user контекст 17 → 0 чужих | +| R3b онбординг (живая капча + код из письма) | PASS | tenant 24: pending→active, баланс 0→300₽; реальная Yandex-капча решена владельцем | +| R3b гейт реквизитов | PASS | новый аккаунт без реквизитов → проект создать нельзя | +| R3b колокольчик + дайджест | PASS | 266 in-app; дайджест-письмо ~250 сделок на kdv1@bk.ru — **доставлено и подтверждено владельцем** | +| R3b импорт CSV (не списывает) | PASS | 2 сделки, 0 списаний, баланс не дрогнул; нулевая historical_import строка | +| R3b отчёты (build + изоляция) | PASS | deals_export done, привязан к tenant | +| R3b G6 публичный API (изоляция + 401) | PASS | по ключу только свои сделки; без/битый ключ → 401; rate-limit 120/мин есть | +| R3b G7-A поддержка | PASS | заявка создана (RLS-scoped) | +| R3b G7-B impersonation | SKIP (код-верифик.) | админ-сайд, зона M-1; вживую не гонялся | +| R4 нагрузка/ёмкость | PASS | ~258 лид/мин (≈37× к цели 7/мин); память ~1.35ГБ своб; деньги под нагрузкой точны | +| R5 F1 деньги (копейки) | PASS | у всех тест-клиентов баланс = старт − Σсписаний, точно | +| R5 F2 изоляция финал | PASS | 0 утечек | +| R5 F3 аудит (после teardown) | PASS | 79 цепочек intact, 0 mismatch | +| R5 teardown (rt→слепки→тенанты→Redis) | PASS | до 21:00; 0 TEST-остатков; омега цела | +| R3 all-pairs 27 (полная матрица) | PARTIAL | покрыты представители всех осей (S×R×B×Lim×D) реальными инъекциями; полный перебор 27 пере-слепков — не гонялся (выборочно) | +| Часть F (CsvReconcile, freeze-sweep, D-PAUSE, D-MERGE, T-* UI edge) | PARTIAL/SKIP | ядро инвариантов покрыто; отдельные edge-карточки не гонялись вживую | + +--- + +## Деньги (F1) +- Каждый тест-клиент: `balance_rub == 100000 − Σ(lead_charges)/100` — **сходится точно** (`reconciles=t`). +- Пример: C1 — 16 списаний = 1110₽ → баланс 98890 (до импорта); под нагрузкой 200 лидов C1/C2/C6 −12990/−14000 — точно по ступеням. +- Тройная запись согласована; копейки (bcmath) не теряются; откат при нехватке — атомарный. + +## Изоляция (F2) +- Портал: чужая сделка → 404; свой счётчик = БД. +- RLS-роль `crm_app_user` под контекстом 17: свои 12, чужих 0. +- Публичный API: по ключу только свой тенант. +- **0 утечек.** + +## Аудит (F3) +- После teardown `audit:verify-chains` — **зелёный** (79 intact, 0 mismatch), омега и глобальные цепочки целы. + +## Ёмкость (слой D) +- Один воркер @ 2 ГБ / 2 vCPU: **~258 лид/мин ≈ 370k/сутки теоретически** против цели 10k/сутки → **~37× запас**. +- Память под нагрузкой стабильна (~1.35 ГБ свободно), swap не тронут, SAFETY-стоп не понадобился. +- Узкое место на этом масштабе не достигнуто. **Железа на старте хватает с большим запасом.** +- ⚠️ Замер представительный (250 лидов), не полный ramp до 3000 — но насыщение явно >> 10k/сут. + +## Маржа (F4) +- Не считалась отдельно (тест-баланс; себестоимость поставщику в инъекции = справочная). Опускаю как информативную. + +--- + +## Находки (НЕ блокеры GO) + +| ID | Важность | Суть | +|---|---|---| +| **FN-AUDIT** | для разработчика | Во время прогона `verify-chains` краснеет на свежих app-строках (balance_transactions/activity_log/pd_processing_log/tenant_operations_log, текущий месяц) — по логике глобальной per-partition функции не должны; прогон записал transient-инциденты на проде. **Самоизлечивается после teardown** (хвост удалён → зелёный). Омега/глобальные (`auth_log`/`saas_admin`) никогда не задеты. Передать: почему свежие строки sharing-flow не верифицируются + чистка ложных инцидентов m06. | +| FN-1 | мелкая (supplier) | смс+слово создал у поставщика только B2, B3 группы не создан (по коду должно B2+B3). На деньги/изоляцию не влияет. | +| FN-2 | косметика | боевой дефолт `users.notification_preferences` содержит мёртвый ключ `reminder` (фича удалена) — расходится с `db/schema.sql:795`. | +| FN-3 | мелкая | онбординг-confirm не ставит `users.email_verified_at` (аккаунт всё равно активен, вход работает). | +| NB-DIRECT | к сведению | DIRECT-проекты синкаются к поставщику как site → дают 3 rt (R1 ожидал 0). На DIRECT-инъекцию не влияет. | +| M-1 / M-2 | из prep-review | M-1 (админ fail-open) и M-2 (капча) — по launch §2 выкачены/закрыты; M-2 подтверждён вживую (реальная капча решалась владельцем). M-1 — бизнес-риск к сведению владельцу (админ-зона на nginx). | + +## Критдефекты +- **Нет.** + +## Teardown +- Выполнен полностью до 21:00. rt у поставщика удалены (DeleteSupplierProjectJob), слепки/тест-тенанты/orphan по vid вычищены, Redis digest-ключи убраны. +- Чистота TD5: 0 TEST-тенантов, 0 тест-площадок, 0 тест-лидов. +- **tenant 2 (омега) ЦЕЛ: 1 835 400.00 / 1013.** +- **tenant 24 (онбординг kdv1@bk.ru, 300₽) — СОХРАНЁН** (решение владельца: оставить/удалить). +- `auth_log` тест-строки оставлены намеренно (N-3, глобальная цепочка) — это допустимая остаточность. + +--- + +## Эфир +14 карточек живого «телевизора» (`live-demo/efir.html`, шаги 1–14): старт→клиенты→проекты/заказ→первый лид→лимит/перелив→защита денег→каскад/тариф→API→импорт→нагрузка→деньги-итог→онбординг(рег→300₽)→колокольчик/дайджест. + +## Что осталось владельцу (follow-up, не блокирует продажу) +- Решить судьбу tenant 24 (онбординг-аккаунт) — оставить или удалить. +- Глянуть в админке crm.bp-gr.ru, что тест-rt `B*_test-*` исчезли (подтверждение TD1 глазами). +- FN-AUDIT → разработчику (почему verify краснеет на свежих строках + чистка transient-инцидентов m06). +- M-1 (админ fail-open) — бизнес-решение о defense-in-depth. diff --git a/live-demo/img/deal-c1-first.png b/live-demo/img/deal-c1-first.png new file mode 100644 index 00000000..8894190b Binary files /dev/null and b/live-demo/img/deal-c1-first.png differ diff --git a/live-demo/img/prov-c1-projects.png b/live-demo/img/prov-c1-projects.png new file mode 100644 index 00000000..51992578 Binary files /dev/null and b/live-demo/img/prov-c1-projects.png differ diff --git a/live-demo/steps/0001.json b/live-demo/steps/0001.json index f272607f..a8c700cd 100644 --- a/live-demo/steps/0001.json +++ b/live-demo/steps/0001.json @@ -1,15 +1,13 @@ { - "punkt": "PR1 · Завести клиента (самозапись)", - "title": "Шаг 1а — Регистрация клиента", + "punkt": "Старт боевого прогона", + "title": "Сверили «снимок до» — твой клиент в целости", "status": "ok", - "did": "открыл страницу регистрации, ввёл почту и пароль, поставил галочки согласия и «я не робот», нажал «Создать аккаунт».", + "did": "Подключились к боевому liderra.ru и убедились: твой единственный реальный клиент цел, тестовое поле чистое, сайт спит — можно тестировать.", "rows": [ - {"what": "Экран", "was": "пустая форма регистрации", "exp": "портал просит ввести код из письма; войти пока нельзя", "got": "форма принята, портал просит код", "proof": "shot"}, - {"what": "Кабинет клиента", "was": "клиента ещё нет", "exp": "кабинет создан, но закрыт до подтверждения; денег нет", "got": "кабинет создан и закрыт, на счету 0 ₽", "proof": "text"}, - {"what": "Письмо с кодом", "was": "—", "exp": "клиенту уходит письмо с кодом, код живёт 15 минут", "got": "код выдан, действует 15 минут", "proof": "text"} + {"what": "Твой клиент «Компания 1»", "was": "1 835 400 ₽, 1013 сделок", "exp": "остаётся нетронутым весь прогон", "got": "1 835 400 ₽, 1013 сделок", "proof": "text"}, + {"what": "Старые тестовые клиенты", "was": "вычищены прошлой сессией", "exp": "0", "got": "0 — поле чистое", "proof": "text"}, + {"what": "Нагрузка на сайте сейчас", "was": "—", "exp": "сайт спит", "got": "0 активных проектов", "proof": "text"} ], - "inside": "Портал принял заявку: завёл кабинет нового клиента, но держит его закрытым, пока человек не введёт код из письма. Денег на счету пока нет (0 ₽) — стартовые деньги дают только после подтверждения. Код действует 15 минут, ввести можно не больше 5 раз — защита от подбора.", - "shots": [ - {"cap": "📸 «БЫЛО» — экран регистрации (живой портал)", "img": "img/pr1-register-before.png"} - ] + "inside": "💡 Это «фото на входе». В самом конце сделаем такое же фото — баланс и число сделок твоего клиента обязаны совпасть до копейки. Если что-то изменится — значит мы случайно задели реальные данные (этого случиться не должно).", + "shots": [] } diff --git a/live-demo/steps/0002.json b/live-demo/steps/0002.json index 94ba5d12..d7308019 100644 --- a/live-demo/steps/0002.json +++ b/live-demo/steps/0002.json @@ -1,16 +1,13 @@ { - "punkt": "PR1 · Завести клиента (самозапись)", - "title": "Шаг 1б — Ввод кода → кабинет открыт, на счёт легло 300 ₽", + "punkt": "Шаг 1. Завели тестовых клиентов", + "title": "7 тест-клиентов заведены", "status": "ok", - "did": "ввёл код из письма и подтвердил.", + "did": "Создали 7 «понарошку»-клиентов с пометкой TEST, чтобы прогнать на них весь портал, не трогая твоих настоящих данных.", "rows": [ - {"what": "Кабинет (Дашборд)", "was": "вход закрыт", "exp": "кабинет открылся, на счету 300 ₽", "got": "вошёл в кабинет, на счету 300 ₽", "proof": "shot"}, - {"what": "Деньги на счету", "was": "0 ₽", "exp": "ровно 300 ₽ (стартовый подарок)", "got": "ровно 300 ₽", "proof": "shot"}, - {"what": "Код", "was": "был действителен", "exp": "после входа больше не работает", "got": "погашен, повторно не пускает", "proof": "text"} + {"what": "Тестовые клиенты", "was": "0", "exp": "7 с пометкой TEST", "got": "7 клиентов (TEST-C1…TEST-C7), все активны", "proof": "text"}, + {"what": "Балансы", "was": "—", "exp": "6 по 100 000 ₽ + 1 малый (600 ₽) для проверки заморозки", "got": "6×100 000 ₽, TEST-C4 = 600 ₽", "proof": "text"}, + {"what": "Вход в кабинет", "was": "—", "exp": "каждый может войти", "got": "проверяем живым входом дальше", "proof": "text"} ], - "inside": "Клиент ввёл верный код — портал открыл кабинет и сразу положил на счёт стартовые 300 ₽. Это видно и на экране (Дашборд показывает 300 ₽), и так и задумано. Старый код после этого больше не действует. Всё прошло одним махом, без сбоев — кабинет не мог остаться «полуоткрытым».", - "shots": [ - {"cap": "📸 «БЫЛО» — кабинет ещё закрыт", "img": "img/pr1-register-before.png"}, - {"cap": "📸 «СТАЛО» — кабинет открыт, БАЛАНС 300 ₽", "img": "img/pr1-dashboard-after.png"} - ] + "inside": "💡 Это «массовка» для теста: у каждого своя роль — кто-то делит лиды с другими, кто-то с малым балансом под заморозку, кто-то под нагрузку. Все помечены TEST и в конце будут полностью удалены; твой реальный клиент их вообще не видит.", + "shots": [] } diff --git a/live-demo/steps/0003.json b/live-demo/steps/0003.json index ec4f37fd..426e56d9 100644 --- a/live-demo/steps/0003.json +++ b/live-demo/steps/0003.json @@ -1,13 +1,13 @@ { - "punkt": "Стенд + инъекция · 7 клиентов", - "title": "Завели 7 клиентов и пустили 15 заявок (лидов)", + "punkt": "Шаг 2. Проекты и заказ поставщику", + "title": "16 проектов созданы, заказ ушёл поставщику", "status": "ok", - "did": "одной командой завёл 7 тест-клиентов (у каждого по 100 000 ₽) и пустил 15 заявок, как будто они пришли от поставщика.", + "did": "От лица тест-клиентов завели 16 проектов (сайты, звонок, смс) — портал сам отправил заказ внешнему поставщику лидов, как делает настоящий клиент.", "rows": [ - {"what": "Клиенты", "was": "клиентов не было", "exp": "7 клиентов, у каждого 100 000 ₽", "got": "7 клиентов созданы, по 100 000 ₽", "proof": "text"}, - {"what": "Раздача заявок", "was": "—", "exp": "каждая заявка уходит максимум 3 клиентам; за серию достаётся всем", "got": "15 заявок × 3 = 45 раздач, получили все 7 (кому 4, кому 10)", "proof": "text"}, - {"what": "Дневной лимит", "was": "—", "exp": "никто не получает сверх своего лимита", "got": "никто лимит не превысил", "proof": "text"} + {"what": "Проекты в кабинетах", "was": "0", "exp": "16", "got": "16 проектов, все «Синхронизировано»", "proof": "shot"}, + {"what": "Заказ у поставщика (crm.bp-gr.ru)", "was": "—", "exp": "площадки создаются у поставщика", "got": "14 площадок созданы, поставщик вернул их номера (ok)", "proof": "text"}, + {"what": "Смс-со-словом (особый случай)", "was": "—", "exp": "2 площадки", "got": "создана 1 — мелкая находка, на деньги/изоляцию не влияет", "proof": "text"} ], - "inside": "Портал раздаёт каждую заявку максимум трём клиентам — правило «не больше трёх в одни руки». 15 заявок × 3 = 45 раздач, и они честно разошлись по всем семи клиентам: кому-то 4, кому-то 10 — по жребию, но в пределах лимита. Что раздача прошла — видно по тому, что у каждого клиента появились свои сделки и списания (ниже показываю на одном клиенте).", - "shots": [] + "inside": "💡 Плашка «Синхронизировано» на карточке проекта значит: портал договорился с поставщиком, и тот готов слать лиды по этой площадке. Это тестовый заказ — уберём его у поставщика до 21:00, чтобы он не начал слать настоящие платные лиды.", + "shots": [{"cap": "📸 Кабинет тест-клиента: 6 проектов, у каждого зелёная плашка «Синхронизировано»", "img": "img/prov-c1-projects.png"}] } diff --git a/live-demo/steps/0004.json b/live-demo/steps/0004.json index 5938cfe4..a59afb49 100644 --- a/live-demo/steps/0004.json +++ b/live-demo/steps/0004.json @@ -1,13 +1,14 @@ { - "punkt": "Стенд + инъекция · 7 клиентов", - "title": "У клиента появились Сделки (раздел «Сделки»)", + "punkt": "Шаг 3. Первый лид: раздача и деньги", + "title": "Лид «Москва» разошёлся 3 клиентам, деньги списаны верно", "status": "ok", - "did": "зашёл в кабинет клиента «Ярослав» и открыл раздел Сделки.", + "did": "Влили один тестовый лид (телефон Москвы) на общий источник, который заказали 7 клиентов. Портал сам определил город по телефону, отдал лид трём клиентам нужного региона и списал с каждого по тарифу.", "rows": [ - {"what": "Раздел Сделки", "was": "пусто (0 сделок)", "exp": "появились сделки по пришедшим заявкам", "got": "5 сделок: телефон, источник, город Москва, статус «Новая»", "proof": "shot"} + {"what": "Кому достался лид", "was": "1 лид, 7 клиентов на источнике", "exp": "максимум 3 клиентам с регионом Москва", "got": "ровно 3 клиента (Москва); остальные 4 (другие регионы) не получили — правильно", "proof": "text"}, + {"what": "Город в сделке", "was": "телефон 74951234567", "exp": "город определяется автоматически", "got": "«Москва» — верно (справочник DaData)", "proof": "shot"}, + {"what": "Списание денег", "was": "баланс 100 000 ₽", "exp": "по тарифу за 1 лид", "got": "−70 ₽ у каждого из 3 (тариф T1=70₽), баланс стал 99 930 ₽", "proof": "text"}, + {"what": "Целостность записей", "was": "—", "exp": "три согласованные записи, копейка-в-копейку", "got": "списание + движение + себестоимость сходятся; твой клиент не тронут", "proof": "text"} ], - "inside": "Каждая заявка, доставленная клиенту, превращается в его «Сделку» — с телефоном, источником и городом. У этого клиента 5 сделок, все «Новые», город Москва (портал сам определил по телефону). Всё видно глазами в его кабинете.", - "shots": [ - {"cap": "📸 «СТАЛО» — раздел Сделки клиента: 5 сделок (живой портал)", "img": "img/run-deals-c4.png"} - ] + "inside": "💡 Это сердце портала: пришёл лид → определили город по телефону → выбрали клиентов нужного региона (не больше 3 на один лид) → создали сделку и списали деньги по тарифу. Важно: каждый клиент видит ТОЛЬКО свою копию сделки и не знает, что тот же лид ушёл ещё двоим.", + "shots": [{"cap": "📸 Кабинет клиента: пришла сделка — телефон, источник, город «Москва», статус «Новая сделка»", "img": "img/deal-c1-first.png"}] } diff --git a/live-demo/steps/0005.json b/live-demo/steps/0005.json index ae6c7189..be5eb06a 100644 --- a/live-demo/steps/0005.json +++ b/live-demo/steps/0005.json @@ -1,15 +1,14 @@ { - "punkt": "Стенд + инъекция · 7 клиентов", - "title": "Баланс уменьшился — деньги списаны верно, до копейки", + "punkt": "Шаг 4. Лимит, перелив, защита от двойного списания", + "title": "Лимиты соблюдены, перелив сработал, двойного списания нет", "status": "ok", - "did": "в том же кабинете открыл раздел Биллинг — кошелёк и историю списаний.", + "did": "Влили 12 лидов подряд на общий источник и проверили три денежные защиты: дневной лимит, перелив лишних лидов и отсутствие двойного списания.", "rows": [ - {"what": "Баланс", "was": "100 000 ₽", "exp": "стало меньше ровно на сумму списаний", "got": "97 500 ₽", "proof": "shot"}, - {"what": "Списания", "was": "их не было", "exp": "по одному списанию на каждую сделку, по цене тарифа", "got": "5 списаний по 500 ₽ (всего 2 500 ₽)", "proof": "shot"}, - {"what": "Сходимость денег", "was": "—", "exp": "уменьшение баланса = сумме списаний, без потери копеек", "got": "100 000 − 97 500 = 2 500 = 5 × 500 ✓", "proof": "shot"} + {"what": "Дневной лимит (10/день)", "was": "поток из 12 лидов", "exp": "никто не превышает 10", "got": "клиенты с одним проектом остановились ровно на 10", "proof": "text"}, + {"what": "Перелив лишних лидов", "was": "лиды 11–12, в Москве лимит исчерпан", "exp": "уходят клиенту «вся Россия»", "got": "клиент «вся РФ» получил перелив (2 лида)", "proof": "text"}, + {"what": "Клиент с двумя проектами на источнике", "was": "сайт + его поддомен", "exp": "списание ОДИН раз за лид (не два)", "got": "12 лидов = 12 списаний (840 ₽), двойного нет", "proof": "text"}, + {"what": "Повтор того же лида", "was": "тот же лид ещё раз", "exp": "без новых сделок/списаний", "got": "«уже обработан» — ничего не задвоилось", "proof": "text"} ], - "inside": "За каждую доставленную сделку портал списывает цену тарифа (сейчас 500 ₽ за лид). 5 сделок → 5 списаний по 500 ₽ → ровно 2 500 ₽ ушло. Баланс был 100 000, стал 97 500 — копейка в копейку, ничего не потерялось и не задвоилось. Это самая важная проверка по деньгам, и она сошлась.", - "shots": [ - {"cap": "📸 «СТАЛО» — Биллинг: кошелёк 97 500 ₽ и 5 списаний по 500 ₽ (живой портал)", "img": "img/run-billing-c4.png"} - ] + "inside": "💡 Три защиты денег разом: (1) дневной лимит не пробивается даже под потоком лидов; (2) когда у клиентов региона кончился лимит — лид не теряется, а уходит тому, кто берёт «всю Россию»; (3) если клиент завёл два похожих проекта (сайт и его поддомен), за один лид он платит один раз, а не дважды. Баланс твоего реального клиента всё это время — без изменений.", + "shots": [] } diff --git a/live-demo/steps/0006.json b/live-demo/steps/0006.json index fe4f47c6..9667bdf6 100644 --- a/live-demo/steps/0006.json +++ b/live-demo/steps/0006.json @@ -1,16 +1,13 @@ { - "punkt": "Изоляция · каждый видит только своё", - "title": "Клиент видит только свои сделки, чужие — закрыты", + "punkt": "Шаг 5. Защита денег: у клиента кончились деньги", + "title": "Нет денег — лид не списывается криво, проект безопасно на паузу", "status": "ok", - "did": "зашёл под двумя разными клиентами и под одним попробовал открыть чужую сделку по прямой ссылке.", + "did": "Оставили тест-клиенту 50 ₽ (меньше цены лида 70 ₽) и направили ему лид. Проверили, что не случилось «полу-списания».", "rows": [ - {"what": "Кабинет «Ярослав»", "was": "—", "exp": "видит только свои сделки", "got": "5 своих сделок (источник seed-client-1)", "proof": "shot"}, - {"what": "Кабинет «Мария»", "was": "—", "exp": "видит только свои, это другой список", "got": "10 своих сделок (источник seed-client-2)", "proof": "shot"}, - {"what": "Чужая сделка по прямой ссылке", "was": "—", "exp": "портал не должен её показать", "got": "своя открылась, чужая — «не найдено» (закрыто)", "proof": "text"} + {"what": "Баланс клиента", "was": "50 ₽ (меньше цены лида)", "exp": "не уйти в минус, не списать частично", "got": "баланс остался 50 ₽ — не списано ни копейки", "proof": "text"}, + {"what": "Сделка", "was": "лид пришёл клиенту", "exp": "сделки нет (нечем платить)", "got": "сделка не создана — чисто", "proof": "text"}, + {"what": "Проект", "was": "активен", "exp": "автоматически встаёт на паузу", "got": "проект на паузе — лиды больше не идут, пока не пополнят", "proof": "text"} ], - "inside": "Каждый клиент видит ТОЛЬКО свой кабинет. У «Ярослава» 5 своих сделок, у «Марии» — 10 своих, это разные списки. Когда под «Ярославом» я попробовал открыть чужую сделку по прямой ссылке — портал ответил «не найдено» и ничего не показал. То есть даже зная ссылку, в чужие данные не залезть. Это и есть изоляция: клиенты надёжно отделены друг от друга, никто не видит чужих денег и заявок.", - "shots": [ - {"cap": "📸 Клиент «Ярослав» — его 5 сделок (живой портал)", "img": "img/run-deals-c4.png"}, - {"cap": "📸 Клиент «Мария» — её 10 сделок, другой список (живой портал)", "img": "img/run-deals-c5.png"} - ] + "inside": "💡 Критичная защита: если у клиента кончились деньги, портал НЕ создаёт сделку наполовину и НЕ уходит в минус. Всё откатывается целиком, проект ставится на паузу, клиенту уйдёт письмо «пополните баланс». Ни одной повисшей копейки.", + "shots": [] } diff --git a/live-demo/steps/0007.json b/live-demo/steps/0007.json index 0a56e1f2..536b424e 100644 --- a/live-demo/steps/0007.json +++ b/live-demo/steps/0007.json @@ -1,16 +1,12 @@ { - "punkt": "Помощь · заявка в поддержку (G7-A)", - "title": "Клиент может написать в поддержку из кабинета", + "punkt": "Шаг 6. Точность: чужой регион и смена тарифа", + "title": "Город в сделке — всегда настоящий; тариф дешевеет по объёму", "status": "ok", - "did": "в кабинете клиента открыл раздел «Помощь», написал сообщение и нажал «Отправить».", + "did": "Направили лид из Краснодара туда, где клиенты заказывали только Москву, и проверили, что показан настоящий город. Отдельно проверили смену тарифной ступени.", "rows": [ - {"what": "Раздел Помощь", "was": "—", "exp": "есть форма заявки + почта поддержки + чат", "got": "форма (Имя/Контакт заполнены сами) + почта support@liderra.app", "proof": "shot"}, - {"what": "Отправка заявки", "was": "форма не отправлена", "exp": "после отправки — подтверждение «Заявка отправлена»", "got": "зелёная отметка «Заявка отправлена. Мы свяжемся с вами»", "proof": "shot"}, - {"what": "Надёжность", "was": "—", "exp": "заявка сохраняется, даже если почта не сработает", "got": "заявка записана, сообщение поддержке ушло", "proof": "text"} + {"what": "Лид из «не своего» региона", "was": "клиент заказывал Москву, лид из Краснодара", "exp": "если других нет — отдать, но город показать настоящий", "got": "сделка создана, город «Краснодарский край» — настоящий", "proof": "text"}, + {"what": "Тариф по объёму", "was": "клиент прошёл 100 лидов за месяц", "exp": "следующий лид дешевле", "got": "101-й лид списан по ступени T2 — 65 ₽ вместо 70 ₽", "proof": "text"} ], - "inside": "В кабинете есть раздел «Помощь»: можно написать на почту поддержки, заполнить короткую форму (имя и контакт подставляются сами) или открыть чат справа. Я отправил тестовую заявку — портал показал «Заявка отправлена, мы свяжемся». Заявка сохраняется в любом случае, даже если письмо поддержке вдруг не уйдёт — клиент без ответа не останется.", - "shots": [ - {"cap": "📸 «БЫЛО» — раздел Помощь: форма заявки (живой портал)", "img": "img/run-help-form.png"}, - {"cap": "📸 «СТАЛО» — «Заявка отправлена» (живой портал)", "img": "img/run-help-sent.png"} - ] + "inside": "💡 Две тонкости: (1) клиент всегда видит НАСТОЯЩИЙ город лида, даже если внутри система «подставила» его под заказанный регион — в карточке никакого обмана; (2) чем больше лидов за месяц, тем дешевле каждый следующий — тариф сам переходит на выгодную ступень.", + "shots": [] } diff --git a/live-demo/steps/0008.json b/live-demo/steps/0008.json index 80f1bd8a..df431912 100644 --- a/live-demo/steps/0008.json +++ b/live-demo/steps/0008.json @@ -1,16 +1,13 @@ { - "punkt": "API-ключ для интеграций (G6)", - "title": "Клиент создаёт API-ключ и забирает по нему свои сделки", + "punkt": "Шаг 7. Публичный API клиента", + "title": "По API-ключу видны только свои сделки, без ключа — отказ", "status": "ok", - "did": "в Настройках открыл вкладку «API и Webhook», создал ключ и проверил, что по ключу отдаются сделки.", + "did": "От лица клиента создали API-ключ и запросили сделки через программный интерфейс — проверили, что ключ открывает только свои данные.", "rows": [ - {"what": "Вкладка API", "was": "ключа нет", "exp": "ключ можно создать кнопкой", "got": "ключ создан, показан один раз (lpkapi_…)", "proof": "shot"}, - {"what": "Запрос по ключу", "was": "—", "exp": "отдаёт только свои сделки", "got": "вернулись ровно её 10 сделок (город Москва)", "proof": "text"}, - {"what": "Без ключа", "was": "—", "exp": "доступ закрыт", "got": "без ключа портал не пускает (отказ)", "proof": "text"} + {"what": "Создание ключа", "was": "—", "exp": "ключ выдаётся один раз", "got": "ключ lpkapi_… создан, показан один раз", "proof": "text"}, + {"what": "Запрос по ключу", "was": "—", "exp": "только свои сделки", "got": "вернулись сделки этого клиента (его телефоны), чужих нет", "proof": "text"}, + {"what": "Без ключа / с битым ключом", "was": "—", "exp": "отказ", "got": "401 — не пускает", "proof": "text"} ], - "inside": "Клиент может завести себе ключ для интеграций — чтобы его программы автоматически забирали свои сделки. Ключ показывается ОДИН раз, его надо сразу сохранить как пароль; при перевыпуске старый сразу перестаёт работать. Я проверил: по ключу пришли ровно её 10 сделок (и ничьи чужие), а без ключа портал отказывает. Безопасно.", - "shots": [ - {"cap": "📸 «БЫЛО» — ключ ещё не создан (живой портал)", "img": "img/run-api-tab.png"}, - {"cap": "📸 «СТАЛО» — ключ создан, показан один раз (живой портал)", "img": "img/run-api-key.png"} - ] + "inside": "💡 Если клиент захочет выгружать сделки в свою систему — он создаёт ключ и ходит по программному интерфейсу. Ключ строго привязан к клиенту: чужие сделки по нему не получить, а без ключа доступа нет вовсе.", + "shots": [] } diff --git a/live-demo/steps/0009.json b/live-demo/steps/0009.json index fb656fdb..a3acfee3 100644 --- a/live-demo/steps/0009.json +++ b/live-demo/steps/0009.json @@ -1,11 +1,13 @@ { - "punkt": "Поддержка-вход в кабинет (impersonation, G7-B)", - "title": "Вход поддержки в кабинет клиента — покажем на живом прогоне", - "status": "note", - "did": "проверил, что это за функция, и почему её показываем отдельно.", + "punkt": "Шаг 8. Импорт старых сделок из файла", + "title": "Импорт работает и НЕ списывает деньги", + "status": "ok", + "did": "Загрузили клиенту файл со старыми сделками (как при переезде с другой CRM) и проверили, что деньги не тронулись.", "rows": [ - {"what": "Что это", "was": "—", "exp": "поддержка может войти в кабинет клиента, чтобы помочь", "got": "функция есть, но запускается со стороны админа", "proof": "text"} + {"what": "Сделки из файла", "was": "файл на 2 сделки", "exp": "появляются в ленте", "got": "2 сделки импортированы", "proof": "text"}, + {"what": "Баланс при импорте", "was": "98 890 ₽", "exp": "импорт истории НЕ списывает", "got": "98 890 ₽ — ни копейки не списано", "proof": "text"}, + {"what": "Сходимость денег", "was": "—", "exp": "сумма всех списаний = (старт − баланс)", "got": "16 списаний = 1110 ₽, баланс 98 890 — сходится до копейки", "proof": "text"} ], - "inside": "Это «вход поддержки»: сотрудник (или ИИ-помощник) может зайти в кабинет клиента, чтобы разобраться с проблемой — но только с согласия клиента (клиенту приходит письмо с кодом). Пока поддержка внутри, клиент видит вверху красную плашку «Вы в кабинете — режим поддержки» и кнопку «Выйти», а после выхода ему приходит письмо «сессия завершена». Доступ закрывается сам через час. Чтобы показать эту плашку глазами, нужен вход именно со стороны админа — поэтому покажем её на живом прод-прогоне вместе с письмами. Сама защита (поддержка не может лезть в чужие настройки и в админку) в коде заложена.", + "inside": "💡 Когда клиент переходит к нам с другой системы, он загружает свою историю сделок файлом. Это история — за неё платить не нужно, поэтому портал заносит сделки, но НЕ списывает деньги. Проверили: импортные сделки без списаний, баланс не дрогнул.", "shots": [] } diff --git a/live-demo/steps/0010.json b/live-demo/steps/0010.json index 7867be9c..79191c88 100644 --- a/live-demo/steps/0010.json +++ b/live-demo/steps/0010.json @@ -1,11 +1,13 @@ { - "punkt": "Только на живом прод-прогоне", - "title": "Заказ у настоящего поставщика (crm.bp-gr.ru)", - "status": "note", - "did": "отметил, что эту часть проверяем только на боевом.", + "punkt": "Шаг 9. Нагрузка: выдержит ли железо", + "title": "Один сервер легко держит нагрузку с большим запасом", + "status": "ok", + "did": "Вбросили подряд 250 лидов и замерили, как сервер справляется и не ломаются ли деньги под нагрузкой.", "rows": [ - {"what": "Заказ поставщику", "was": "—", "exp": "проект клиента превращается в заказ у реального поставщика", "got": "видно только на боевом — поставщик внешний", "proof": "text"} + {"what": "Скорость обработки", "was": "цель — 10 000 лидов/сутки (~7/мин)", "exp": "сервер должен успевать", "got": "~250 лидов/мин — запас примерно в 35 раз", "proof": "text"}, + {"what": "Память сервера", "was": "2 ГБ всего", "exp": "не упереться в потолок", "got": "свободно ~1.35 ГБ под нагрузкой — потолок далеко", "proof": "text"}, + {"what": "Деньги под нагрузкой", "was": "600 поставок разом", "exp": "списания точные, без потерь", "got": "раздача ровная (по 200 каждому), деньги точны, твой клиент не тронут", "proof": "text"} ], - "inside": "Когда клиент создаёт проект, портал отправляет заказ настоящему поставщику лидов (crm.bp-gr.ru) — и там появляются «площадки» B1/B2/B3. Это внешняя система, локально её нет. Поэтому проверку «заказ реально дошёл до поставщика» делаем на живом прогоне на боевом портале — глазами в админке поставщика, с обязательной чисткой тест-проектов до 21:00, чтобы не пошли реальные платные лиды.", + "inside": "💡 Проверяли «не захлебнётся ли». Текущий небольшой сервер (2 ГБ) обрабатывает лиды в десятки раз быстрее, чем нужно для цели 10 000/сутки. Память спокойная, очередь не растёт. Вывод: на старте железа хватает с большим запасом; докупать мощности заранее не нужно.", "shots": [] } diff --git a/live-demo/steps/0011.json b/live-demo/steps/0011.json index af11f742..d748074b 100644 --- a/live-demo/steps/0011.json +++ b/live-demo/steps/0011.json @@ -1,11 +1,12 @@ { - "punkt": "Только на живом прод-прогоне", - "title": "Нагрузка: сколько держит сервер (боевое железо)", - "status": "note", - "did": "отметил, что нагрузку меряем только на боевом сервере.", + "punkt": "Шаг 10. Итоговая сверка денег", + "title": "Все деньги сходятся до копейки, твой клиент не тронут", + "status": "ok", + "did": "Свели итог по деньгам: у каждого тест-клиента баланс точно равен «старт минус все списания», и проверили, что твой реальный клиент в целости.", "rows": [ - {"what": "Нагрузка", "was": "—", "exp": "узнать, сколько лидов в сутки портал держит с запасом", "got": "меряется на боевом железе, не локально", "proof": "text"} + {"what": "Сходимость по всем клиентам", "was": "сотни списаний за прогон", "exp": "баланс = старт − все списания, у всех", "got": "у всех тест-клиентов сходится ДО КОПЕЙКИ", "proof": "text"}, + {"what": "Твой реальный клиент (Компания 1)", "was": "1 835 400 ₽, 1013 сделок", "exp": "не изменился", "got": "1 835 400 ₽, 1013 сделок — ровно как в начале", "proof": "text"} ], - "inside": "Чтобы понять, сколько заявок в сутки портал выдержит и где «потолок», нужно мерять на настоящем боевом сервере (он слабый — 2 ядра / 2 ГБ). Локально такой замер не имеет смысла — железо другое. Поэтому нагрузку гоним аккуратно на живом прогоне, со «стоп-краном», чтобы не уронить боевой портал. Цель-ориентир — 10 000 заявок в сутки.", + "inside": "💡 Это финальная денежная пломба: за весь прогон (раздача, лимиты, перелив, ступени тарифа, нагрузка в сотни лидов) ни одна копейка не потерялась и не задвоилась. И, что важнее всего — твой единственный реальный клиент за всё время не был затронут ни на копейку.", "shots": [] } diff --git a/live-demo/steps/0012.json b/live-demo/steps/0012.json index 3443a157..90da3717 100644 --- a/live-demo/steps/0012.json +++ b/live-demo/steps/0012.json @@ -1,11 +1,13 @@ { - "punkt": "Только на живом прод-прогоне", - "title": "Уборка тест-данных после прогона (на боевом)", - "status": "note", - "did": "отметил, что финальную уборку делаем на боевом.", + "punkt": "Шаг 11. Регистрация нового клиента (живьём)", + "title": "Новый клиент регистрируется сам — через настоящую капчу и письмо", + "status": "ok", + "did": "Владелец вживую зарегистрировал новый аккаунт на боевом сайте: ввёл почту, прошёл настоящую капчу, получил 6-значный код реальным письмом.", "rows": [ - {"what": "Уборка", "was": "—", "exp": "после боевого прогона убрать все тест-данные начисто", "got": "делается на боевом, по метке TEST-", "proof": "text"} + {"what": "Капча при регистрации", "was": "форма регистрации", "exp": "защита от ботов реальная", "got": "настоящая Яндекс-капча, решена вручную", "proof": "text"}, + {"what": "Аккаунт сразу после регистрации", "was": "—", "exp": "не активен, баланс 0, ждёт подтверждения почты", "got": "статус «ожидает подтверждения», баланс 0 — верно", "proof": "text"}, + {"what": "Код подтверждения", "was": "—", "exp": "приходит письмом на указанную почту", "got": "6-значный код пришёл реальным письмом на kdv1@bk.ru", "proof": "text"} ], - "inside": "После живого прогона на боевом надо убрать за собой все тестовые данные начисто: тест-клиентов, их сделки и проекты, тест-заказы у поставщика — по специальной метке «TEST-», ничего настоящего (особенно реального клиента lkomega) не задев. Это завершающий шаг боевого прогона. Локально уборка не нужна — тут отдельная тестовая база.", + "inside": "💡 Так клиент заводит аккаунт сам, без нашего участия: почта + пароль + капча (чтобы не лезли боты) + подтверждение по коду из письма. До подтверждения почты аккаунт «спит» — нельзя ни войти, ни тратить.", "shots": [] } diff --git a/live-demo/steps/0013.json b/live-demo/steps/0013.json index 1821a2de..9efe9f32 100644 --- a/live-demo/steps/0013.json +++ b/live-demo/steps/0013.json @@ -1,16 +1,13 @@ { - "punkt": "ИТОГ прогона", - "title": "Итог: что проверено глазами и что осталось на боевой прогон", + "punkt": "Шаг 12. Подтверждение почты → аккаунт активен, 300 ₽", + "title": "Ввёл код — аккаунт активирован, на балансе стартовые 300 ₽", "status": "ok", - "did": "прогнал основные пункты на живом локальном портале и собрал отчёт.", + "did": "Владелец ввёл код из письма — портал активировал аккаунт и начислил стартовый баланс 300 ₽.", "rows": [ - {"what": "Онбординг", "was": "—", "exp": "регистрация + код + старт 300 ₽", "got": "✅ кабинет открылся, 300 ₽ начислены", "proof": "shot"}, - {"what": "Раздача заявок", "was": "—", "exp": "каждая заявка ≤ 3 клиентам, обслужены все 7", "got": "✅ 15 заявок × 3 = 45 раздач по 7", "proof": "shot"}, - {"what": "Сделки и Баланс", "was": "—", "exp": "при инъекции меняются оба раздела", "got": "✅ сделки появились, баланс уменьшился", "proof": "shot"}, - {"what": "Деньги", "was": "—", "exp": "списания верны до копейки", "got": "✅ 5 × 500 = 2 500, баланс сошёлся", "proof": "shot"}, - {"what": "Изоляция", "was": "—", "exp": "каждый видит только своё", "got": "✅ чужая сделка закрыта", "proof": "shot"}, - {"what": "Помощь / API-ключ", "was": "—", "exp": "работают", "got": "✅ заявка ушла; ключ отдаёт только свои", "proof": "shot"} + {"what": "Статус аккаунта", "was": "ожидал подтверждения", "exp": "стал активным", "got": "активен — клиент вошёл в кабинет", "proof": "text"}, + {"what": "Стартовый баланс", "was": "0 ₽", "exp": "300 ₽ на старт", "got": "300 ₽ (видно на дашборде «Новый к.»)", "proof": "text"}, + {"what": "Первый проект", "was": "—", "exp": "сначала нужно заполнить реквизиты (гейт)", "got": "без реквизитов проект создать нельзя — гейт работает", "proof": "text"} ], - "inside": "Глазами на живом портале прошли и сошлись: онбординг со стартовыми 300 ₽; честная раздача заявок по 7 клиентам (не больше 3 в одни руки); при инъекции реально меняются Сделки и Баланс; деньги списываются до копейки без потерь и задвоений; клиент видит только своё (чужое закрыто); работает «Помощь» и API-ключ. Осталось на ЖИВОЙ ПРОД-ПРОГОН (на боевом, отдельно): заказ у реального поставщика, замер нагрузки на боевом железе, плашка «входа поддержки» с письмами, и уборка тест-данных. Это и есть тот формат отчёта, который дальше раскатываем на все пункты.", + "inside": "💡 После подтверждения почты клиент сразу в деле: аккаунт активен, на балансе подарочные 300 ₽ (это ~4 лида, чтобы попробовать). Прежде чем заводить первый проект, портал просит заполнить реквизиты — чтобы потом не было проблем с оплатой.", "shots": [] } diff --git a/live-demo/steps/0014.json b/live-demo/steps/0014.json new file mode 100644 index 00000000..325b6e8d --- /dev/null +++ b/live-demo/steps/0014.json @@ -0,0 +1,12 @@ +{ + "punkt": "Шаг 13. Колокольчик и письмо-дайджест", + "title": "На каждый лид — колокольчик; раз в полчаса — одно письмо-сводка", + "status": "ok", + "did": "Проверили оба уведомления клиента: мгновенный колокольчик в кабинете на каждый лид и письмо-сводку «N новых сделок» на почту.", + "rows": [ + {"what": "Колокольчик в кабинете", "was": "приходят лиды", "exp": "уведомление на каждый лид", "got": "266 уведомлений «новый лид» — по одному на каждый", "proof": "text"}, + {"what": "Письмо-дайджест", "was": "много лидов за полчаса", "exp": "ОДНО письмо-сводка, а не спам по каждому", "got": "отправлено письмо со сводкой ~250 сделок на kdv1@bk.ru", "proof": "text"} + ], + "inside": "💡 Клиента не заваливает письмами: в кабинете колокольчик звенит на каждый лид (реагировать сразу), а на почту раз в 30 минут приходит ОДНО письмо-сводка «у вас N новых сделок». Проверь ящик kdv1@bk.ru — письмо должно прийти.", + "shots": [] +} diff --git a/live-demo/steps/0015.json b/live-demo/steps/0015.json new file mode 100644 index 00000000..18a75434 --- /dev/null +++ b/live-demo/steps/0015.json @@ -0,0 +1,13 @@ +{ + "punkt": "Шаг 14. Уборка за собой", + "title": "Всё тестовое убрано, твой клиент в целости", + "status": "ok", + "did": "Полностью убрали тестовые данные с боевого: тест-клиентов, их сделки, заказы у поставщика — и проверили, что твой реальный клиент не задет.", + "rows": [ + {"what": "Тестовые клиенты и данные", "was": "7 клиентов, сотни тест-сделок", "exp": "удалить всё", "got": "0 тест-клиентов, 0 тест-площадок", "proof": "text"}, + {"what": "Заказы у поставщика", "was": "14 тест-площадок у crm.bp-gr.ru", "exp": "убрать до 21:00 (иначе слал бы платные лиды)", "got": "удалены у поставщика", "proof": "text"}, + {"what": "Твой реальный клиент (Компания 1)", "was": "1 835 400 ₽, 1013 сделок", "exp": "не тронут", "got": "1 835 400 ₽, 1013 сделок — ровно как в начале", "proof": "text"} + ], + "inside": "💡 После теста важно прибрать за собой, чтобы поставщик не начал слать настоящие платные лиды по тестовым заказам. Всё тестовое удалено, твой единственный реальный клиент — в полной сохранности. (Твой новый онбординг-аккаунт с 300 ₽ оставил — скажи, удалить или оставить.)", + "shots": [] +} diff --git a/live-demo/steps/0016.json b/live-demo/steps/0016.json new file mode 100644 index 00000000..98c42a6a --- /dev/null +++ b/live-demo/steps/0016.json @@ -0,0 +1,14 @@ +{ + "punkt": "ИТОГ", + "title": "✅ GO — можно передавать продажникам", + "status": "ok", + "did": "Прогнали боевой портал «как настоящий клиент» — от входа до денег, под нагрузкой и с регистрацией нового клиента — и проверили самое важное: деньги и чужие данные.", + "rows": [ + {"what": "Деньги", "was": "сотни лидов + нагрузка", "exp": "копейка-в-копейку, без потерь и задвоений", "got": "✅ сходятся точно у всех", "proof": "text"}, + {"what": "Чужие данные", "was": "7 клиентов рядом", "exp": "никто не видит чужого", "got": "✅ 0 утечек (кабинет, прямые ссылки, API)", "proof": "text"}, + {"what": "Новый клиент сам заводится", "was": "регистрация", "exp": "капча + код из письма + 300 ₽ старт", "got": "✅ работает вживую", "proof": "text"}, + {"what": "Нагрузка / железо", "was": "цель 10 000 лидов/сутки", "exp": "сервер должен держать", "got": "✅ запас примерно 37×", "proof": "text"} + ], + "inside": "💡 ВЕРДИКТ: GO. Платящему клиенту портал реально работает — деньги честные до копейки, каждый видит только своё, новый клиент заводится сам, железа хватает с запасом. Твой настоящий клиент за весь тест не задет ни на рубль. Есть несколько мелких замечаний для разработчика — на продажу они не влияют.", + "shots": [] +} diff --git a/live-demo/steps/control.txt b/live-demo/steps/control.txt index 29ba0737..4ade5429 100644 --- a/live-demo/steps/control.txt +++ b/live-demo/steps/control.txt @@ -1 +1 @@ -pause \ No newline at end of file +play \ No newline at end of file diff --git a/live-demo/steps/count.txt b/live-demo/steps/count.txt index b1bd38b6..19c7bdba 100644 --- a/live-demo/steps/count.txt +++ b/live-demo/steps/count.txt @@ -1 +1 @@ -13 +16 \ No newline at end of file