81 lines
9.9 KiB
Markdown
81 lines
9.9 KiB
Markdown
# SuperSam — проверка «Аналитики»: обзвоны и согласования
|
||
|
||
Проверка: 02.10.2026, МСК. Данные — последние 30 дней (02.09–02.10), живой вызов RPC на боевой БД (.8), плюс сверка с кодом, триггерами и живой сборкой фронта.
|
||
|
||
## Короткий вердикт
|
||
|
||
**По обзвонам (робот) цифры в целом верные.** Отдельные неточности: тестовые звонки попадают в статистику, в таблице попыток «Согласовали» считается по одному исходу, а KPI — по трём.
|
||
|
||
**По согласованиям — неверно.** Главная цифра «Согласовано» и блок «Чем подтвердили» показывают не подтверждения клиента, а служебный перевод заказа из ручной работы. Ошибка не в аналитике, а в данных: заказ, доставленный без согласования, помечается «Согласовано».
|
||
|
||
Две поверхности аналитики (одна страница!) дают разные цифры об одном и том же.
|
||
|
||
## Что показывает сейчас (живой `admin_comms_funnel(30)`)
|
||
|
||
Воронка коммуникаций:
|
||
- Групп в работе 438 · Первое SMS 393 (89.7%) · **Открыли ссылку 1 (0.2%)** · Робот позвонил 80 (18.3%) · Взяли трубку 54 · Согласовано 186 (42.5%) · В ручную работу 18 · Выдано/доставлено 405 (92.5%) · Не достали 236 (53.9%)
|
||
|
||
Чем подтвердили: **Ссылка из SMS 137** · Менеджер 25 · Робот-звонок 24
|
||
|
||
Путь заказа (там же): Дата согласована 158 (36.1%) · мимо цепочки 259 · Как согласовали дату: **Логист 116** · Звонок робота 24 · SMS-ссылка 18 · Источники: Менеджер 116 · Робот-звонок 24
|
||
|
||
## 1. «Согласовано» на 137 заказах из 186 — это не подтверждения клиента
|
||
|
||
Что нашёл по этим 137 группам (status confirmed, источник даты пустой):
|
||
- все 137 уже `delivered`;
|
||
- даты нет ни в заказе (`delivery_date`/`pickup_date` пустые), ни в приглашении (состояние `awaiting_choice`, `confirmed_at` нет);
|
||
- 131 из 137 получили первое SMS, звонки были у 16;
|
||
- в истории: `delivery_status manual_confirmation_required → delivered` и одновременно `notification_status manual_required → confirmed`, источник — «system» (внешнее обновление, пришло из обмена).
|
||
|
||
Причина: триггер `clear_manual_required_on_action` (`supabase/sync-manual-status.sql`) при любом изменении статуса доставки переводит «нужен менеджер» в «согласовано». Заказ уехал без согласования — система записала подтверждение.
|
||
|
||
Масштаб: из 137 в блоке «Чем подтвердили» настоящих подтверждений по ссылке только 9 (у них есть подтверждённое приглашение), остальные 128 — подменённые триггером. Всего подтверждений по приглашениям за 30 дней — 20.
|
||
|
||
Это видно и в реестре: `orderGroupViews` рисует `confirmed` как «Согласовано», то есть владелец видит «Согласовано» по заказам, где клиент ничего не подтверждал.
|
||
|
||
## 2. Робот: почти верно, но есть расхождения
|
||
|
||
- Реально робот согласовал слот по **29** группам за 30 дней. В аналитике «Робот-звонок 24»: у 5 групп источник позже перезаписан логистом (робот согласовал, потом логист поменял дату) — в статистике эти подтверждения потеряны.
|
||
- 1 группа согласована тестовым звонком и тоже считается.
|
||
|
||
## 3. Тестовые звонки не отфильтрованы
|
||
|
||
За 30 дней в `autocall_log` 37 тестовых строк (`was_test_mode`), 6 из них привязаны к группе — они попадают в «Робот позвонил / Взяли трубку» и в таблицу попыток.
|
||
|
||
Во вкладке «Коммуникации → Аналитика» фильтра по тесту нет вообще: «Звонков 179» (включая 37 тестовых), «Согласовали 40» (включая 11 тестовых), «Конверсия звонка 22%». Плюс период «Всё время» в этой вкладке на самом деле 90 дней.
|
||
|
||
## 4. «Согласовали» в таблице попыток считается не так, как в KPI
|
||
|
||
Таблица попыток берёт только `outcome='confirmed'` (16+7+6 = 29 звонков), а KPI и воронка — все три подтверждающих исхода (`confirmed`, `confirmed_silent`, `confirmed_kept_previous`). Подтверждения «молчанием» в таблице попыток не видны.
|
||
|
||
## 5. «Открыли ссылку» = 1 — метрика сломана
|
||
|
||
`opened_at` заполняет только edge-функция. По факту за 30 дней 76 приглашений имеют `access_count > 0` / `last_accessed_at` — страницу открывали, а `opened_at` стоит у 1. Шаг стоит в воронке между SMS и звонками, и читается как «клиенты не открывают ссылки» (0.2%).
|
||
|
||
## 6. Два блока на одной странице дают разные цифры
|
||
|
||
«Чем подтвердили» считает только текущий `notification_status='confirmed'` (186), «Как согласовали дату» — только заказы с датой (158), источники — все с датой (116+24), таблица попыток — звонки (29). Показательно про логиста: **25 в одном блоке и 116 в другом** — 91 группа с источником `manual` уже имеет статус `completed` и в первый блок не попадает. То есть цифра «кто согласовал» меняется задним числом по мере завершения заказов.
|
||
|
||
Отдельно: из 116 «логист согласовал» 97 уже получили SMS и 27 — звонки робота. Это ручное дорешивание после автоматики, а не «клиент сразу согласовал с логистом»; в отчёте это стоит различать.
|
||
|
||
## 7. Критическая находка: согласование по ссылке не работало с 29.09
|
||
|
||
`confirmDeliveryChoice` в `src/services/deliveryInvitationApi.js` читал переменную `src`, которой нет среди параметров (`p_src: src || null`) → `ReferenceError: src is not defined`. Клиент на странице выбора слота получал ошибку, выбор не сохранялся, канал согласования (`p_src`) в заказ не записывался.
|
||
|
||
Доказательства: живая сборка prod содержала `p_src:src` (переменной в области видимости нет); тест `deliveryInvitationApi.test.js` падал с `ReferenceError: src is not defined`; последнее подтверждение по ссылке в БД — 28.09 (миграция каналов — 29.09).
|
||
|
||
Исправлено и выложено: коммиты `f2a9249` и `6dba84f`. Prod dost.supersamsev.ru и dev dev.mkn8n.ru, SW v133. Тесты: 13/13 и 17/17. Каналы из ссылки (`sms`, `client`, `push`, `messenger`) теперь подписаны человеческими словами, а не сырыми ключами БД.
|
||
|
||
## Что предлагаю решить
|
||
|
||
1. **Убрать ложное «Согласовано»**: в триггере не ставить `confirmed`, когда дата не проставлена; такие заказы — отдельный исход «закрыт без согласования» (и в реестре, и в аналитике). Это меняет и реестр, поэтому нужно ваше решение.
|
||
2. **«Открыли ссылку» считать по `last_accessed_at`/`access_count`** (76 вместо 1).
|
||
3. **Исключить тестовые звонки** из аналитики по `was_test_mode`.
|
||
4. **Свести обе поверхности к одному источнику цифр**: «кто согласовал» — по каналу (`autocall` / логист / ссылка), не потекущему статусу.
|
||
|
||
## Чего не проверял
|
||
|
||
Как блоки выглядят живьём в браузере (мобильный 390px, десктоп) — проверял данные напрямую в БД и RPC; UI глазами не кликал.
|
||
|
||
Проверки, по которым получены цифры: `/tmp/ss_analytics_check*.sql` (выполнены на .8 в контейнере `supabase-db`).
|