Мера: о новой заявке узнаёт ответственный, а на дашборде видно, сколько оценок доходит до заявки #3551
No reviewers
Labels
No labels
Fable 5 ревью
GG-форсайт
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
feedback/max
generative
needs-discussion
needs-human
observability
pause-bots
performance
priority/p0
priority/p1
priority/p2
priority/p3
scope/backend
scope/db
scope/devops
scope/frontend
scope/qa
scrapers
security
site-finder
stage/1
stage/2
status/blocked
status/done
status/needs-analysis
status/needs-fix
status/qa
status/ready
status/review
status/wip
tech-debt
tradein
ux
week ревью 1
wontfix
ИРД
вторичка
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#3551
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/lead-funnel"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Что было
В #1971 было четыре пункта DoD. Два уже сделали раньше:
POST /api/v1/trade-in/leadс сохранением и доказательством согласия (#2376, #2497, #2511) и форма вместо mailto (#2377). Два оставались несделанными:lead.pyбыло прямо написано «Notification (Telegram/email) — вне scope», а колонкуnotified_atоставили на будущее. На проде 17.09: вtrade_in_leads4 строки,notified_atне заполнен ни у одной, последняя заявка 12.07, за 30 дней ни одной. За те же 30 дней посчитано 189 оценок. Все от вошедших пользователей, 7 разных аккаунтов.mera_estimates_totalиmera_leads_totalесть (#3471), но доли заявок от оценок нет ни на одной панели.Почему этого не сделали сразу: в разборе 04.07 записали, что интеграции с Telegram в коде нет. Сейчас это уже неверно. Появились общий клиент
app/services/tgbot/shared.py:get_telegram_clientи веб-чат поддержки (api/v1/support.py), который пишет в support-топик. На проде уtradein-backendзаданыTELEGRAM_BOT_TOKEN,TELEGRAM_SUPPORT_CHAT_IDиTELEGRAM_SUPPORT_TOPIC_ID=2(проверено черезdocker inspect17.09).Что сделано
Уведомление (
tradein-mvp/backend/app/api/v1/lead.py):support._bot_configured), вBackgroundTasksставится_notify_new_lead. Ответ клиенту не ждёт Telegram.app/tasks/glitchtip_alert_retry.py. После успешной отправки выполняетсяUPDATE trade_in_leads SET notified_at = now()в отдельной сессии.notified_atостаётся пустым, и по нему видно, что заявка не дошла.data_erasure.py) не стирает копию в Telegram, поэтому в сообщение идут только id заявки, имя пользователя (его уже показывает зеркало поддержки) и id оценки. Телефон оператор смотрит вtrade_in_leadsпо id.Конверсия (
ops/metrics/grafana/dashboards/product.json): новая панель «Конверсия оценка → заявка, скользящие 7 суток» с выражениемsum(increase(mera_leads_total[7d])) / sum(increase(mera_estimates_total{outcome="ok"}[7d])).В знаменателе только
outcome="ok": на/trade-in/v2LeadFormрендерится только приhasEstimate = … && !insufficient.Тесты
tests/test_trade_in_lead.py: добавлено 3 теста, всего в файле 17 passed.chat_id/message_thread_idиз настроек, в тексте есть id лида и пользователь. Цифр телефона9123456789нет даже среди цифр текста. UPDATE ушёл с{"id": <лид>}, выполнены commit и close.send_messageбросаетTelegramError: ответ 200 с тем же id, лид закоммичен, UPDATE не выполнялся.telegram_support_chat_id=0: отправки нет.DATABASE_URL=… uv run python -m pytest tests/ -q -p no:cacheprovider: 6228 passed, 42 skipped, rc=0.uv run ruff check app tests: All checks passed.ruff format --checkпо изменённым файлам: already formatted./api/v1/query). Скрипт берётexprиз JSON и отдельно считает числитель и знаменатель:panel value: [0.0] numerator: [0.0] denominator: [91.00765993265993], то есть 91 успешная оценка за неделю и 0 заявок.Фальсификация
Каждый раз ломал копию исходника, запускал проверку, восстанавливал файл и сверял
diff -q.returnперед UPDATE (notified_atне пишется)FAILED test_lead_notifies_topic_without_phone_and_sets_notified_at:AttributeError: 'NoneType' object has no attribute 'args', rc=1AssertionError: assert '9123456789' not in '00000000000...179123456789', rc=1FAILED test_lead_telegram_failure_keeps_200_and_notified_at_empty:app.services.tgbot.client.TelegramError: boom, rc=1FAILED test_lead_bot_not_configured_skips_notification:AssertionError: Expected mock to not have been awaited. Awaited 1 times., rc=1outcome="OK"AssertionError: панель пустая при живых оценках — выражение не матчит ряды, rc=1mera_lead_totalДеплой
tradein-backendиtradein-scraperбудут пересозданы. Деплой сам ждёт, покаscrape_runs.status='running'станет 0 (до 5 мин). Перед мержем стоит проверить, что прямо сейчас не идёт долгий обход. Миграций нет:notified_atна проде уже есть.deploy-metrics.yml(Beget). Каталогdashboardsсмонтирован целиком, Grafana перечитывает его раз в 30 с.Приёмка на проде (после деплоя, до 24.09.2026)
SELECT id, notified_at FROM trade_in_leads ORDER BY created_at DESC LIMIT 1показывает заполненныйnotified_at. Если заявка есть, аnotified_atпуст, ищемtrade_in_lead: уведомление не доставленовdocker logs tradein-backend.Что не сделано
BackgroundTasksне переживают рестарт). Лид при этом сохранится с пустымnotified_at. Повторная досылка неуведомлённых заявок не сделана: при 4 заявках за 2 месяца это лишнее.Closes #1971
🤖 Generated with Claude Code