Files
clientsflow/docs/adr/0001-chat-platform-service-boundaries.md
2026-03-08 18:55:58 +07:00

4.1 KiB

ADR-0001: Chat Platform Boundaries (GraphQL + Hatchet)

Дата: 2026-03-08
Статус: accepted

Контекст

Нужна минимальная и предсказуемая схема из 5 сервисов:

  • frontend
  • backend
  • telegram_backend
  • telegram_worker
  • hatchet

Ключевые ограничения:

  • основная Prisma/доменная БД только в backend;
  • telegram_backend и telegram_worker не содержат CRM-домен и не пишут в основную БД;
  • взаимодействие между сервисами только через GraphQL;
  • асинхронность и ретраи централизованы в Hatchet.

Решение

Принимаем архитектуру:

  1. backend
  • владеет доменной моделью чатов и единственной основной Prisma-базой;
  • принимает inbound события от telegram_worker через GraphQL (ingestTelegramInbound);
  • создает outbound задачи в telegram_backend через GraphQL (requestTelegramOutbound);
  • принимает delivery-отчеты от telegram_worker через GraphQL (reportTelegramOutbound).
  1. telegram_backend
  • принимает webhook Telegram;
  • нормализует payload в OmniInboundEnvelopeV1;
  • ставит задачи в Hatchet (process-telegram-inbound, process-telegram-outbound);
  • предоставляет GraphQL API для enqueue и отправки в Telegram API.
  1. telegram_worker
  • исполняет задачи Hatchet;
  • для inbound вызывает backend /graphql;
  • для outbound вызывает telegram_backend /graphql (sendTelegramMessage), затем backend /graphql (reportTelegramOutbound);
  • не имеет собственной Prisma-базы.
  1. hatchet
  • единый оркестратор задач, ретраев и backoff-политик.

Потоки

Inbound (Telegram -> CRM)

  1. Telegram webhook приходит в telegram_backend.
  2. telegram_backend нормализует событие и enqueue в Hatchet process-telegram-inbound.
  3. telegram_worker исполняет задачу и вызывает backend.ingestTelegramInbound.
  4. backend сохраняет доменные изменения в своей БД.

Outbound (CRM -> Telegram)

  1. backend инициирует отправку (requestTelegramOutbound) в telegram_backend.
  2. telegram_backend enqueue в Hatchet process-telegram-outbound.
  3. telegram_worker вызывает telegram_backend.sendTelegramMessage.
  4. telegram_worker репортит итог в backend.reportTelegramOutbound.

Границы ответственности

backend:

  • можно: вся бизнес-логика и состояние;
  • нельзя: прямой вызов Telegram API.

telegram_backend:

  • можно: webhook ingress, нормализация, enqueue, адаптер Telegram API;
  • нельзя: доменные записи CRM.

telegram_worker:

  • можно: исполнение задач, ретраи, orchestration шагов;
  • нельзя: хранение CRM-состояния и прямой доступ к основной БД.

Надежность

  • webhook отвечает 200 только после успешной постановки задачи в Hatchet;
  • при недоступности сервисов задача ретраится Hatchet;
  • inbound обработка идемпотентна через idempotencyKey и provider identifiers в backend.

Последствия

Плюсы:

  • меньше сервисов и меньше скрытых связей;
  • изоляция доменной БД в backend;
  • единая точка ретраев/оркестрации (Hatchet).

Минусы:

  • выше требования к стабильности GraphQL-контрактов между сервисами;
  • нужна наблюдаемость по цепочке telegram_backend -> hatchet -> telegram_worker -> backend.