Перейти к основному содержимому

Известные ограничения

Описание

Список того, что в текущей реализации онбординг-бота осознанно отложено, с причиной и тем, что уже готово на стороне бота (чтобы включение в будущем было минимальным изменением). Ни один из пунктов не является багом — затронутая функциональность либо не активирована намеренно, либо требует отдельного решения вне скоупа этой задачи.

1. Reactivation / struct_overtake — backend-эмиссия не включена

Бот полностью готов принимать и обрабатывать события reactivation и struct_overtake из outbox (EventHandlersService.onReactivation, onStructOvertake, apps/onboarding-bot/src/outbox/event-handlers.service.ts) — DM пользователю уже реализован и покрыт тестами. BotEventType содержит оба значения на обеих сторонах контракта.

Backend их не эмитит. Точка эмиссии завязана на закомментированный блок распределения наград StructPartnerUpReward в apps/backend/src/.../distributionsStats.job.ts (финансовый код начисления наград при обгоне структуры) — включать его нужно осознанным решением команды, а не как побочный эффект доработки бота: раскомментирование затрагивает не только уведомление, а саму логику начисления вознаграждений.

Что нужно, чтобы включить: раскомментировать/реализовать эмиссию BotOutboxService-события в соответствующей точке job'а начисления наград (без изменения самой логики распределения) — на стороне бота дорабатывать ничего не требуется.

2. Сегментация «неактивные» — по бот-активности, не по веб-сессии

AdminService.filterInactive / сегмент bc:seg:inactive:<N> в мастере рассылки и pt:list:stuck в списке партнёров используют bot_users.lastActivityAt — момент последнего взаимодействия с ботом (FunnelService.advanceStage обновляет её на каждый переход этапа).

Пользователь, который активно пользуется веб-кабинетом Magnet, но не заходит в Telegram, будет ошибочно попадать в сегмент «неактивные» — сейчас бот не видит sessions.timeActive (веб-активность) основного backend'а.

Что нужно, чтобы включить: синхронизация веб-времени активности в bot_users (либо через outbox-событие на каждую веб-сессию, либо через периодический батч-синк GET /bot/user/statetimeActive, поле уже возвращается этим эндпоинтом, но в bot_users не сохраняется). Отложено как краевое уточнение — основной путь (бот-активность) уже отражает вовлечённость в воронку.

3. Детект «ушёл к другому лидеру B» — только для wallet-регистрации

EventHandlersService.onRegistered сравнивает payload.submitted_link (сырую реф-ссылку, с которой юзер регистрировался) с botUser.leaderLink (first-touch реф-ссылка лидера A из бота) — расхождение триггерит notifyLeaderLeft (DM лидеру A «Ваш партнёр зарегистрировался у лидера B»). Это работает, потому что кошелёк-регистрация (processRegistrationInProgramsEvent, ончейн-синк) эмитит registered с заполненным submitted_link.

Социальная/email-регистрация (registerSocialWallet, off-chain путь) не эмитит бот-событие registered вообще — вся эмиссия событий registered привязана к sync.service (ончейн-синк). Соответственно уход партнёра к другому лидеру через соц./email-регистрацию бот не детектит и лидера A не уведомляет.

Что нужно, чтобы включить: протянуть эмиссию registered (или эквивалентного события с submitted_link) из off-chain пути регистрации — отдельная задача на стороне auth/sync, не затрагивающая бота.

4. Frontend: рендер уведомлений PartnerLeftToLeader/NewPartnerViaBot не добавлен

Пассивный фоллбэк POST /bot/notification (когда DM недоступен, 403 — нет активного диалога с ботом) пишет генерическую запись в NotificationService.addNotification веб-кабинета основного backend'а, но фронтенд (apps/frontend) не добавляет специфичный рендер для типов события бота (type: 'bot_event' и т.п.) — такие уведомления в веб-кабинете отобразятся как есть (или не отобразятся специфично оформленными), без кастомной иконки/текста под конкретный сценарий.

Низкий приоритет: основной канал доставки таких уведомлений — DM в боте; веб-фоллбэк срабатывает только когда у адресата нет активного диалога с ботом (не начинал /start или заблокировал бота).

5. Известный технический долг (не риск, но стоит знать)

  • AdminService.createBroadcast/runBroadcast — более ранняя (глобальная, без per-recipient леджера/rate-limit/resume) реализация рассылок, вытесненная BroadcastUpdate + BroadcastSenderService. Код не удалён и не вызывается ни одним пользовательским путём — кандидат на чистку в будущем рефакторинге, не влияет на текущее поведение.
  • BonusService/bot_bonus_grants — сущность и сервис стартовых бонусов существуют в кодовой базе, но провайдер не зарегистрирован в AppModule (сознательно откреплён на раннем этапе доработки бота, до решения продукта по механике бонусов). Таблица bot_bonus_grants создаётся миграцией, но не используется.
  • In-memory telegraf-сессия (ctx.session) — состояние мастера рассылки и кэш Viewer живут в памяти процесса. При строгом соблюдении «1 реплика» (см. «Архитектура») это не проблема; при рестарте процесса открытый мастер рассылки теряется (пользователь просто начинает заново через bc:new) — приемлемо для короткоживущего мастера. Redis-backed session — потенциальное будущее улучшение для многоинстансной раскатки, не требуется для v1.
  • Пресеты расписания рассылки — только «через 1 час» и «завтра в 10:00»; произвольный ввод даты/времени текстом не реализован (см. «Меню-навигация»).