541f38d452
Повод — письмо тревоги 31.07.2026 05:30 МСК: сверка №1417 отрапортовала «потеряно 7». Разбор на бою показал, что вебхук по тем же семи пришёл через 2,5 минуты (05:32:32 ×2 + 05:33:03 ×5) и получил «уже есть». Потери не было: поставщик кладёт строку в журнал отданного РАНЬШЕ, чем шлёт вебхук, а наша сверка (каждые 30 мин) попадала в эту щель. Цена ошибки не только ложная тревога: добранная карточка беднее живой (в журнале нет tag/time/phones) — у 4 из 7 не определился регион, у сделок пустые регион и город. 1. Отсрочка добора (CsvReconcileJob::GRACE_MINUTES = 15). Недостача, увиденная впервые, уходит в карантин (Redis, карта vid => время первого обнаружения) и добирается только следующим прогоном, если провисела дольше отсрочки. Реальная потеря доезжает максимум через полчаса. Потеря карантина безопасна: в худшем случае добор на прогон позже. drift и «потеряно» в письме считаются ТОЛЬКО по просроченному; «в пути» — отдельно (новая колонка supplier_csv_reconcile_log.pending_count). 2. Журнал вебхука поставщика (новая таблица supplier_webhook_log). Прежний logSupplierWebhook писал в webhook_log, снесённую 24.05 вместе с legacy-каналом, и молча выходил по Schema::hasTable — журнала не было ВООБЩЕ. Из-за этого 70 отказов 404 за 10 дней никто не видел; нашлись случайно в логе nginx. Пишем статус, адрес отправителя, запрошенный хост и отпечаток присланного ключа (первые 8 символов md5 — отвечает «наш ключ или чужой», секретом не является). Отказы дополнительно уровнем warning: на бою LOG_LEVEL=warning, info в журнал не попадает. 3. Текст письма-тревоги переписан: «потеря» = только то, что не дошло даже за отсрочку; «в пути» показывается отдельной строкой и потерей не считается. 4. В catch сверки — Log::error ПЕРВЫМ действием, до обращений к БД: при испорченной транзакции следующий запрос бросал своё исключение и настоящая причина терялась. Проверено: тесты поставщика и вебхука 230/230 (в т.ч. 5 новых на карантин, поздний вебхук, отчёт «в пути» и смоук шаблона письма), Larastan 0, Pint чисто. Прогон всей базы 3566/3575; 5 падений — чужие и до этих правок (замерено откатом файлов): биллинг на стыке месяцев и маршруты телеграм-ветки. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
23 lines
1.9 KiB
PHP
23 lines
1.9 KiB
PHP
<!DOCTYPE html>
|
||
<html lang="ru">
|
||
<head><meta charset="UTF-8"><title>Вебхук потерял номера — добрали сверкой</title></head>
|
||
<body style="font-family: Arial, sans-serif;">
|
||
<h3>Вебхук поставщика потерял номера — сверка их добрала</h3>
|
||
<p>Окно проверки: <strong>{{ $windowStart->format('d.m.Y H:i') }} — {{ $windowEnd->format('d.m.Y H:i') }}</strong></p>
|
||
<ul>
|
||
<li>Поставщик отдал за окно: <strong>{{ $totalCsvRows }}</strong></li>
|
||
<li>Не дошло вебхуком и не дошло за отсрочку (считаем потерей): <strong>{{ $missingCount }}</strong></li>
|
||
<li>Из них заведено в базу сверкой: <strong>{{ $recoveredCount }}</strong></li>
|
||
<li>Ещё в пути — ждём вебхук, потерей НЕ считаем: <strong>{{ $pendingCount }}</strong></li>
|
||
<li>Доля потерь: <strong>{{ number_format($driftRatio * 100, 2, ',', ' ') }}%</strong> (порог тревоги 5%)</li>
|
||
</ul>
|
||
<p style="color:#555">
|
||
«Потеря» здесь — номер, который поставщик отдал, а вебхук не принёс даже спустя отсрочку.
|
||
Такие номера портал заводит сам из журнала отданного, но карточка выходит беднее живой:
|
||
в журнале нет региона и точного времени. Если потери повторяются — смотреть журнал вебхука
|
||
(отказы = чужой пароль или старый адрес) и настройки интеграции у поставщика.
|
||
</p>
|
||
<p>Подробности прогона — строка <code>supplier_csv_reconcile_log.id = {{ $reconcileLogId }}</code>.</p>
|
||
</body>
|
||
</html>
|