Files
Deal/docs/spec/ТЗ-дейл-новая-архитектура.md
T
Rustam Khalimov 27c7831910
ci / build-test (push) Canceled after 0s
Deal — единая кодовая база
SaaS-мониторинг Telegram: ядро (модули Cards/Kanban/Pipeline/Tenants/Settings/
Discovery, Api, Infrastructure), сервисы telegram/ai/ml/storage, фронт Vue,
контракты и grpc-hosting, деплой-конфиги (dev/prod/observability/CI-раннер),
Gitea Actions CI, документация (ТЗ, техдок, api-map, код-стайл, планы, бэклог).

Текущее состояние: все этапы роадмапа 0–12 закрыты, сборка 5 sln 0/0,
тесты 1340/130/52/38/9 зелёные.
2026-09-11 23:56:47 +03:00

23 KiB
Raw Blame History

Дейл (Deal) — Техническое задание на новую архитектуру

Версия: 1.0 (отражает этапы 0–12) Дата: 2026-09-10 Связанные документы: docs/architecture/2026-09-05-deal-architecture-design.md, docs/architecture/2026-09-10-unified-api-contract.md, docs/architecture/2026-09-10-operator-analytics-contract.md, исходное ТЗ прототипа LeadRadar V1.2 — archive/leadradar-legacy/ТЗ-LeadRadar-v1.2.md.


1. О продукте

«Дейл» — SaaS-сервис мониторинга Telegram-каналов и групп. Клиент подключает свой Telegram-аккаунт, выбирает каналы/группы для мониторинга, а система:

  1. получает сообщения из источников в реальном времени;
  2. отсеивает мусор: рекламу, скам, служебные сообщения, дубликаты, устаревшее;
  3. структурирует оставшееся в карточки (заказ/вакансия/услуга) по профилю клиента (сфера, стек, бюджет, локация);
  4. раскладывает карточки по колонкам-фильтрам клиента;
  5. обучается на действиях клиента (ML) и всё больше обрабатывает поток сама;
  6. помогает искать и подключать новые источники (Discovery).

Целевая аудитория: специалисты и мастера в разных сферах (разработчики, дизайнеры, риелторы, строители и т.д.), которые ищут реальные заказы и клиентов в Telegram.

Ключевая ценность: видеть реальные заказы и клиентов, а не кучу дубликатов и рекламы.


2. Термины

  • Тенант — клиент SaaS. Владеет схемой БД, настройками обработки, ML-моделью.
  • Аккаунт (Telegram) — личный Telegram-аккаунт тенанта, подключённый к системе.
  • Источник — откуда система получает записи. Сейчас это Telegram-канал/группа/чат (тема форума); контракт источника универсален, поэтому позже сюда добавляются другие сервисы (WhatsApp, сайты, файлы/таблицы) без изменения ядра.
  • Сырое сообщение — оригинальное сообщение из источника до обработки (входные данные пайплайна).
  • Карточка — единая сущность системы: ядро (id, заголовок, источник) + опциональные модули (содержимое, бюджет, контакты, атрибуты, комментарии, ссылки, файлы, ТЗ, история, напоминания, размещение в контейнере). Создаётся из прошедшего фильтры сообщения либо вручную; переезжает между дашбордами/контейнерами без смены сущности. Термин «лид» не используется — это лишь входное сообщение.
  • Источник (Source) — откуда пришла карточка: локально/вручную, ссылка на сайт, файл, Telegram (канал/группа/чат, тема форума), колонка импортированных данных, внешний API, ИИ (провайдер+модель), составной «первоисточник + цепочка обработки».
  • Контейнер — общая база колонок/стадий/зон: пользовательские колонки дашборда (набор фильтров), стадии «Выбранных», «Неразобранное», архив, корзина, терминальные зоны. У каждого контейнера — политика (что можно/нельзя, автоочистка, терминальность).
  • Отсев — сообщения, отклонённые пайплайном (с причиной).

3. Роли и доступ

Роль Возможности
Оператор (владелец SaaS) Создаёт тенантов и инвайты; управляет лимитами; видит health; impersonation с аудитом
Тенант (клиент) Входит по инвайту, задаёт пароль; подключает свой Telegram-аккаунт; настраивает обработку; работает с дашбордом
  • Регистрация — только по инвайту (ссылка/код от оператора).
  • Логин: email + пароль; email уникален в масштабе SaaS; tenantId — в сессии/JWT.
  • Вход оператора — отдельный, изолированный от тенантов.

4. Подключение Telegram-аккаунта

  1. Оператор один раз задаёт ключи приложения Telegram (api_id/api_hash) — глобально.
  2. Тенант в UI: «Добавить аккаунт» → QR-код (или телефон + код подтверждения).
  3. Система сохраняет сессию аккаунта (в telegram-service) и показывает статус подключения.
  4. 1 аккаунт на тенанта на старте (схема допускает расширение).
  5. При первом подключении система подтягивает список диалогов аккаунта (каналы/группы/чаты) и обновляет его при каждом входе на экран каналов и в фоне (появление/исчезновение источников отслеживается автоматически).

Мониторинг источников

  • Тенант включает/выключает мониторинг по каждому источнику из списка его диалогов.
  • Настройка «новый чат → мониторинг автоматически» (вкл/выкл).
  • Источники, удалённые/покинутые вне системы, исчезают из списка.
  • Кнопка «Перечитать»: догон последних ~10 сообщений всех включённых источников (с паузами, анти-бан).
  • Полученные сообщения сразу помечаются прочитанными в Telegram.

Discovery (поиск и подключение источников)

  • Тенант создаёт задачу поиска: описание цели → ИИ генерирует ключевые слова.
  • Система ищет каналы/группы/форумы, в которых аккаунт не состоит (глобальное правило).
  • Каскад фильтров: участники → язык → содержание (по темам, порог ≥40%).
  • Кандидаты показываются «на рассмотрение» с метаданными (тип, участники, fit «X из N», темы форума, метки: закрытая группа и т.п.).
  • Действия: «Вступить и мониторить» (вручную) или авто-вступление с квотами (50/сутки общий, паузы 50–70 с), «Отклонить» → чёрный список.
  • Чёрный список исключает источник во всех задачах; снимается вручную.

5. Обработка входящих (пайплайн)

Путь сообщения: источник → очередь → стоп-лист → дедуп → ML → ИИ → карточка. Всё, что отсеяно, — в «Отсеве» с причиной. Настройки обработки — per-tenant.

Этап 1 (без ИИ, дёшево)

  1. Минимальная длина текста.
  2. Стоп-фразы (настраиваемый список).
  3. Отсев резюме соискателей (настройка).
  4. Тип заявки (только вакансии / только заказы) по контексту.
  5. Дедуп: одинаковый текст (нормализованный хэш) уже в системе → отсев «повтор».
  6. Устаревшее сообщение (старше срока архивации) → отсев.

ML-слой

  • Если ML-модель тенанта уверена — решает сама: спам → отсев; колонка → карточка сразу.
  • Не уверена → сообщение уходит на ИИ.
  • Возврат из отсева (force) идёт мимо ML к ИИ-классификации.

ИИ-слой (если включён)

  • ИИ-фильтр: сообщение не про заявки/интересы тенанта → отсев.
  • Классификация: структурированный разбор (компания, формат, о задаче, требования, плюсы, условия, бюджет, стек, контакты, тип заявки).
  • Назначение колонки с проверкой её правил.

Глобальные фильтры

  • «Не создавать карточку без суммы» — отдельно для вакансий и для заказов.
  • Исключения по ключевым словам/технологиям/бюджету/локации (стоп на уровне фильтров).

Карточка

  • Единая сущность: ядро (id, заголовок, источник) + опциональные модули. Вид карточки — композиция модулей, не отдельный класс/таблица; третий дашборд работает с той же карточкой.
  • Реализация (этап 9): карточка — одна строка одной таблицы Cards во всех дашбордах; таблица ProjectCards упразднена. Модули — колонки той же строки (StackJson/LinksJson/FilesJson/ HistoryJson/TzText/напоминание), комментарии — общая таблица LeadComments. Колонки/стадии/зоны — единый реестр контейнеров; пространства не пересекаются (карточка не может быть одновременно в дашборде и в «Выбранных»), «взять в работу» — смена контейнера, а не клон.
  • Модули: содержимое (единая структура «О заявке»: Компания → Формат → О задаче → Требования → Будет плюсом → Условия), бюджет (from/to/валюта), контакты (квалифицированные: tg/phone/email/ linkedin/site), атрибуты (стек/грейд/локация/сроки — настраиваются тенантом в UI, не зашиты), комментарии, ссылки, файлы, ТЗ, история движения, напоминание, размещение в контейнере.
  • Исходное сообщение карточки хранится и доступно: текст структурируется и показывается в карточке, вложения/ссылки/контакты — отдельными блоками; кнопка «Обновить из источника» догружает оригинал у сервиса-владельца источника (для Telegram — по id сообщения), если он доступен.

6. Дашборд (канбан)

  • Колонки: «Неразобранное», пользовательские колонки (набор фильтров), «Архив», «Корзина».
  • Пользовательские колонки создаёт пользователь; ИИ может предлагать колонки с обоснованием (по каким критериям), пользователь принимает/отклоняет/переименовывает.
  • Колонка = сложный набор опциональных фильтров: ключевые слова/стек/грейд/уровень/цена/ бюджет/локация/тип + отрицательные фильтры («чтобы не попадало»).
  • При помещении карточки в колонку указывается, по каким критериям она попала.
  • Карточки в колонке: свежие сверху. Drag&drop между колонками (с обучением ML).
  • Быстрые действия на карточке: комментарий, корзина, контакт, «открыть исходник».
  • Виджеты-счётчики свёрнутых колонок; колонки можно двигать, менять размер/ширину.
  • Архив: карточки старше N дней (настройка 1–30); очистка архива через 90 дней.
  • Корзина: очистка раз в 7 дней; из архива/корзины карточку можно вернуть (на канбан).

«Выбранные» (пространство стадий)

  • То же пространство карточек: те же карточки в контейнерах-стадиях (Запланировано → Отклик → Согласование → В работе → Проверка → Готово / Отложено и др.). «Взять в работу» — переход карточки в контейнер, а не создание второй сущности.
  • У карточки наполняются модули работы: комментарии, изменение суммы/стека/контактов, прикрепление ссылок, ТЗ, файлов (медиа/документы; тип определяется автоматически; хранение в S3/MinIO; на карточке значки количества файлов и ссылок).
  • Отложенные: напоминания (через срок + в заданное время, выбор даты в календаре); настройка в общих настройках; если напоминания выключены — окно не показывается и установленные не срабатывают.
  • История движения карточки (статус, дата, время) — под спойлером в карточке.
  • Ручное создание карточки с тем же набором полей (пометка «создано локально»).
  • В архив/корзину дашборда карточки «Выбранных» не попадают; свои терминальные зоны: «Отклонено», «Выполнено» (политики контейнеров).

7. Вкладка «Обработка»

  • Очередь: сырые сообщения, ожидающие обработки (этап 1 / ожидают ИИ), с автопрокруткой.
  • Отсев: отклонённые сообщения с причиной и источником решения (правила / ML / ИИ / система), включая конкретное стоп-слово/фразу.
  • У записи: метаданные (источник, подпись, вид, время), «показать исходное сообщение» с форматированием, кнопка обновления исходника у сервиса-владельца источника.
  • Поиск по отсеву — полнотекстовый.
  • Возврат из отсева в обработку: причины отсева игнорируются, ML/ИИ обучаются на решении; можно указать причину возврата.
  • Автоочистка отсева: раз в 3 дня; ручная очистка.
  • Вкладка показывает счётчик обработки (в боковой панели отсев не показывается).

8. Настройки тенанта

  • Telegram: ключи приложения (оператор), подключение аккаунта, авто-мониторинг новых.
  • ИИ: провайдер (один; включая локальные), модель, ключ (хранится зашифрованно), промпты (базовый + свой), библиотека готовых промптов по сферам + «мои промпты», вкл/выкл ИИ, вкл/выкл ИИ-фильтр.
  • ML: вкл/выкл, обучение на действиях, проверка на сообщении/канале, сброс, самооценка («ML справляется с последними N сообщениями — ИИ можно отключить»).
  • Обработка: стоп-фразы, длина, резюме, тип заявки, домен/ключи, маркеры найма/заказа.
  • Проверка текста: сухой прогон по цепочке (стоп-правила → глобальные исключения → ML → ИИ → «без суммы») без создания карточки — показывает этапы, причину отсева и куда попала бы карточка.
  • Колонки: набор, правила, отрицательные фильтры, исключения.
  • Валюта: целевая валюта отображения, источник курсов (4 запроса/сутки), конвертация при приходе данных + пересчёт старых карточек (кроме архива/корзины); USDT = USD.
  • Хранение: срок архивации (1–30 дней), очистка архива/корзины.
  • Уведомления и напоминания (общие; отложенные — отдельно).
  • Звук, внешний вид.

9. Лимиты (бюджет токенов)

  • Каждый тенант имеет бюджет токенов на LLM-вызовы (период — настраивается).
  • ai-service оценивает каждый вызов в токенах и списывает с бюджета.
  • При исчерпании: AI-обработка переключается на fallback (ML/локальный разбор), тенант получает уведомление; приём и базовая обработка сообщений не блокируются.
  • Оператор видит расход по тенантам в админке и может менять бюджет.

10. Админка оператора

  • Тенанты: создание, инвайты, статус, лимиты/бюджеты, приостановка.
  • Health всех сервисов и очередей.
  • Аудит: входы/выходы, инвайты, impersonation, действия оператора и пользователей тенанта (создание/перенос/удаление карточек, комментарии, контейнеры, настройки, каналы).
  • Аналитика: расход токенов (по дню/тенанту/провайдеру/модели) и лента действий с фильтрами.
  • Подозрительная активность (по логам безопасности) и метрики сервисов (Prometheus/Grafana).
  • UI: оператор-консоль (#/operator) и страница активации инвайта (#/join).

11. Нефункциональные требования

  • Безопасность: TLS, mTLS между сервисами, параметризованный SQL, защита от IDOR/XSS/SSRF/CSRF, Argon2id, rate limiting (прокси + приложение; счётчики — распределённые, в БД, работают при нескольких инстансах), Cloudflare.
  • Надёжность: ежедневные бэкапы (Postgres, файлы, сессии), outbox для событий; авто-очистки (retention аудита, лимитов, окон rate-limit); мгновенный разлогин suspended-сессий.
  • Наблюдаемость: структурированные логи → Loki, метрики (OpenTelemetry → Prometheus) → Grafana
    • правила алертов; история расхода токенов (token_usage_events).
  • Масштабируемость: модульный монолит + отдельные сервисы (ml/ai/telegram); горизонтальное масштабирование сервисов; k8s — позже.
  • Производительность: пайплайн обрабатывает поток без потерь; анти-бан-паузы Telegram не блокируют обработку.
  • Локализация (i18n): весь интерфейс — на русском; все пользовательские строки вынесены в ресурсы (без хардкода в компонентах), включая тексты ошибок; фолбэк — русский. Переключатель языка и второй язык — в бэклоге: делаем, когда возникнет потребность (основа в ресурсах уже готова). Область — основное приложение и оператор-консоль. (Этап 11 roadmap.)

12. Ограничения и допущения

  • Фронтенд (Vue 3 + Vite + Tailwind) переезжает из LeadRadar; с этапа 9 контракт карточек/колонок — единый (/api/cards + /api/containers, см. docs/architecture/2026-09-10-unified-api-contract.md).
  • Данные текущего LeadRadar тестовые — не мигрируются.
  • Kafka, k8s, биллинг-провайдер, саморегистрация — вне рамок текущего этапа.
  • 1 Telegram-аккаунт на тенанта; несколько аккаунтов — позже (схема готова).