Перейти к содержанию

Fairflow — Карта микросервисов, шлюзов и инфраструктуры

Модульное разбиение бэкенда по доменам, плюс AGW, IGW и сопутствующие сервисы. Чат — опционально (v2+).
Основа: GraphQL-спецификация, требования v5.2, roadmap v2+.
Целевой контракт Gateway (REST+GraphQL снаружи, gRPC внутри): gateway-services-grpc-spec.md.
Реализовано: внешний трафик только на gateway; домены принимают бизнес только по gRPC с service API key в metadata (services-runbook.md).


1. Имена микросервисов (идентификаторы)

Краткие имена используются в путях, репозиториях, конфигурации и маршрутизации AGW.

Сервис Идентификатор
Auth Service auth
Organization Service control
Project Service control
Contacts Service contact
Companies Service company
Pipelines & Deal Sources Service pipe
Deals Service pipe
Orders Service orders
Products Service product
Activities Service activity
Documents Service documents
Reports Service reports
Search Service search
Audit Service audit
Notifications Service notification
Billing Service billing
API Gateway gateway
Integration Gateway integration
File / Storage Service storage
Chat Service (v2+) chat
Импорт Отдельного сервиса нет — методы импорта в каждом домене: contact, company, product, pipe (сделки), orders (продажи).

Примечание: Organization и Project объединены под идентификатором control. Pipelines, Deal Sources и Deals — под pipe. Остальные сервисы — один идентификатор на сервис.


2. Сводная схема

AGW — единая точка входа. Доменные сервисы и Billing / File / Notifications вызываются через AGW или по внутренней сети. IGW — только исходящий шлюз (webhook'и, email, push); он не стоит «между» доменами и остальными сервисами.

                    ┌─────────────────────────────────────────────────────────────┐
                    │                        КЛИЕНТЫ                               │
                    │  Web (React)  │  Mobile (v2+)  │  Внешние системы (webhook)  │
                    └───────────────────────────┬─────────────────────────────────┘
                                                │
                    ┌───────────────────────────▼───────────────────────────┐
                    │              API GATEWAY (AGW)                          │
                    │  Единая точка входа (HTTPS/WS). Маршрутизация, проверка JWT, │
                    │  rate limit, CORS. Бизнес-логика — в сервисах.              │
                    └───────────────────────────┬───────────────────────────┘
                                                │
    ┌───────────────────────────────────────────┼───────────────────────────────────────────┐
    │                           Доменные сервисы (вызовы через AGW / внутренняя сеть)      │
    ▼                                           ▼                                           ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ ┌─────────────┐ ┌─────────────┐
│ Auth        │ │ Org         │ │ Project             │ │ CRM-домены  │ │ Automation  │
│             │ │             │ │ + Workspace         │ │ (Contacts,  │ │             │
│             │ │             │ │ + Access Policy     │ │ Deals, …)   │ │             │
└─────────────┘ └─────────────┘ └─────────────────────┘ └─────────────┘ └─────────────┘
    │                 │                 │                 │                 │
    └─────────────────┴─────────────────┴─────────────────┴─────────────────┘
                                │
        ┌───────────────────────┼───────────────────────┐
        ▼                       ▼                       ▼
┌───────────────┐  ┌───────────────┐  ┌───────────────┐  ┌───────────────┐  ┌───────────────┐
│ Billing       │  │ File/Storage  │  │ Notifications │  │ Workers       │  │ IGW           │
│ (лимиты,      │  │ (S3/MinIO)   │  │ (in-app,      │  │ (automation,  │  │ только        │
│ платежи)      │  │              │  │ WS, настройки)│  │ DLQ, cron)    │  │ исходящие:    │
└───────────────┘  └───────────────┘  └───────────────┘  └───────────────┘  │ webhook,      │
        ▲                 ▲                 ▲                 ▲             │ email, push   │
        └─────────────────┴─────────────────┴─────────────────┴─────────────┴───────────────┘
         Вызовы от доменов напрямую (лимиты, файлы, события). IGW — вызовы наружу.

3. API Gateway (AGW / gateway)

Назначение Описание
Единая точка входа Все клиенты ходят только в AGW (HTTPS).
Маршрутизация По path/операции: GraphQL → BFF или напрямую к доменным сервисам; REST — к конкретным MS; WebSocket — к подписчикам (notifications, chat).
Аутентификация Проверка JWT; запрос refresh проксируется в Auth Service (выдаёт токены только Auth).
Доп. функции Rate limiting, CORS, сжатие, логирование запросов, метрики.

Не входит в AGW: бизнес-логика; агрегация данных (это в BFF или в доменных сервисах).

Варианты реализации: Kong, AWS API Gateway, Apigatewayv2 (WebSocket), custom на Node/Go; для GraphQL — Apollo Router или merge schema за AGW. Схема объединения подсхем доменных сервисов (federation / schema stitching) — отдельное решение.


4. Integration Gateway (IGW / integration)

Назначение Описание
Исходящие webhook'и Order Type: финальное действие при завершении этапа продажи; retry по RetryPolicy, DLQ при исчерпании.
Очереди Очередь задач для retry webhook, для правил автоматизации (триггер → действие).
События (v2+) Шина событий (Kafka/RabbitMQ) для уведомлений, аудита, интеграций.
Адаптеры Email (SMTP/SendGrid), Push (FCM), в будущем — Telegram, обогащение по ИНН и т.д.

IGW не хранит доменные сущности CRM — только маршрутизация вызовов, retry и адаптеры.


5. Микросервисы по доменам (модульно)

Ниже — разбиение по разделам GraphQL-спецификации и экранам. Каждый пункт можно оформить отдельным микросервисом или сгруппировать (например, «CRM Core» = контакты + компании + сделки + воронки).

5.1 Auth Service (auth)

Ответственность GraphQL / функции
Регистрация, вход, выход signIn, signUp, signOut
Восстановление пароля forgotPassword, resetPassword
Подтверждение email verifyEmail
2FA Расширение мутаций (TOTP)
Приглашение в систему acceptInvite
Сессии, токены Session, refreshToken
Текущий пользователь и контекст me, myWorkspaces, myProjects (или через BFF)
Настройки пользователя Язык, часовой пояс, формат даты/чисел, вид по умолчанию (канбан/список), тема (v2+) — требования 29

Хранит: users, sessions, user_settings, invite_tokens (координация с Org: токен приглашения в организацию может храниться в Org), 2fa_secrets.
Зависимости: Org Service (роли в организациях), Project Service (workspaces, роли в проектах) — для myWorkspaces / myProjects читать через API или кэш.


5.2 Organization Service (control)

Ответственность GraphQL / функции
Организации (юрлица) Organization, CRUD
Подразделения Department, дерево
Сотрудники, приглашения Employee, inviteEmployee, removeEmployee
Роли в организации OrgRole (PO, PA, Employee)

Хранит: organizations, departments, employees, invitations.
Связь с Auth: при invite — создание/привязка user (invite-токен и письмо — координация Auth ↔ Org); при remove — отзыв доступа, переназначение записей по каждому проекту (координация с CRM и Access Policy).


5.3 Project Service (control)

Ответственность GraphQL / функции
Проекты Project, CRUD, archiveProject
Workspace Владение сущностью Workspace (личное vs организация): workspaces, привязка проекта к workspaceId. Query myWorkspaces агрегируется здесь или в BFF.
Модули проекта modules[], включение/выключение; при отключении — координация с Orders (webhook/DLQ пауза), Activities (напоминания), Automation (правила пауза)
Участники проекта ProjectMember, addProjectMember, updateProjectMemberRole, removeProjectMember
Шаблоны проектов templateId, предустановки модулей/воронок
Политики доступа (Access Control) RBAC (матрица по ролям), иерархия отделов (видимость записей подчинённых), шаринг записей, виртуальное членство в отделе. Настройки видимости per-project (только свои / свои+расшаренные / отдел / все). API проверки доступа для всех CRM-сервисов.

Хранит: projects, project_members, workspaces, project_access_policies, sharing_records (или эквивалент).
Зависимости: Org (дерево отделов для иерархии). Изоляция по projectId — основа для всех CRM-сервисов.


5.4 Contacts Service (contact)

Ответственность GraphQL / функции
Контакты Contact, CRUD, soft delete, restore
Связь контакт ↔ компания many-to-many (contact_company_links)
Merge, дедупликация mergeContacts, проверка дублей при создании
Импорт importContacts (файл уже в Storage)

Хранит: contacts, contact_company_links (единственный владелец связи many-to-many; Companies Service читает состав через API Contacts или общий контракт).
Индексы: projectId, ownerId, email (partial deletedAt null).


5.5 Companies Service (company)

Ответственность GraphQL / функции
Компании Company, CRUD, soft delete, restore
many-to-many с контактами через общую связку или запросы в Contacts
Merge mergeCompanies
Импорт importCompanies

Хранит: companies. Связь контакт ↔ компания: владелец данных — Contacts Service (contact_company_links); здесь только чтение через API/контракт при необходимости.


5.6 Pipelines & Deal Sources Service (pipe)

Ответственность GraphQL / функции
Воронки Pipeline, стадии, порядок
Источники сделок DealSource
Запрет удаления при активных сделках Бизнес-правило при delete; координация с Deals (перенос сделок при удалении стадии/воронки)

Хранит: pipelines, deal_sources.
Зависимости: Deals Service проверяет наличие сделок на стадии перед удалением. Вариант упрощения: объединить с Deals в один сервис, чтобы избежать циклической координации при удалении стадий.


5.7 Deals Service (pipe)

Ответственность GraphQL / функции
Сделки Deal, CRUD, moveDealToStage, closeDeal, reopenDeal
Stage log Время на стадиях, история
Передача между проектами transferDeal, lineage
Drift detection Снимки контакта/компании, confirmContactSnapshot
Bulk bulkMoveDealsToStage, bulkAssignDeals, bulkTransferDeals
Подписки (real-time) dealUpdated, dealsByStageUpdated → через Notifications или отдельный WS (чат — v2+)

Хранит: deals (stage_log, lineage, lightContact, snapshots embedded).
Зависимости: Contacts, Companies (валидация contactId/companyId), Pipelines (стадии), IGW (события для уведомлений/автоматизаций).


5.8 Order Types Service (в составе orders)

Ответственность GraphQL / функции
Типы продаж OrderType, поля, этапы, версионирование
Webhook URL, retry policy Настройки для IGW
Запрет удаления при активных продажах Согласование с Orders Service

Хранит: order_types.
Зависимости: IGW (вызов webhook при завершении этапа/продажи). Вариант упрощения: объединить с Orders в один сервис из-за тесной связи (схема полей, версионирование).


5.9 Orders Service (orders)

Ответственность GraphQL / функции
Продажи Order, CRUD, этапы, stage_log
Связь со сделкой dealId, contact/company snapshots
DLQ Статус ERROR, dlqError, dlqAttempts, retryOrderWebhook
Генерация документов Запрос в Documents Service

Хранит: orders.
Зависимости: Order Types, Deals, Contacts/Companies (snapshots), IGW (webhook, DLQ), Documents (генерация).


5.10 Products Service (product)

Ответственность GraphQL / функции
Каталог продуктов Product, CRUD
Связь с типом продажи orderTypeId
Импорт importProducts

Хранит: products.


5.11 Activities Service (activity)

Ответственность GraphQL / функции
Задачи, звонки, встречи, заметки Activity, CRUD
Календарь activitiesCalendar (по диапазону дат)
Напоминания reminderAt → в Worker + Notifications

Хранит: activities.
Зависимости: Notifications (напоминания, назначение).


5.12 Documents Service (documents)

Ответственность GraphQL / функции
Шаблоны документов DocumentTemplate, переменные, контекст (Order/Deal/Contact/Company)
Генерация документов generateDocument — подстановка переменных, рендер (DOCX и т.д.)
Хранение файлов Сохранение в File Service, запись Document с fileUrl

Хранит: document_templates, documents (метаданные + fileUrl).
Зависимости: File/Storage Service (загрузка шаблона, выдача сгенерированного файла), Orders/Deals/Contacts/Companies (данные для подстановки).


5.13 Reports Service (reports)

Ответственность GraphQL / функции
Агрегированная аналитика reportSales, reportFunnel, reportSources, reportActivity
Дашборд dashboard (статистика, виджеты)
Конструктор отчётов (v1/v2) Сохранённые отчёты, произвольные срезы

Хранит: кэш отчётов или read model (материализованные срезы/проекции), обновляемый по событиям из доменов. Избегать «общей БД» с доменами — предпочтительно: подписка на события (CQRS) или чтение через API с кэшированием.
Зависимости: остальные CRM-сервисы (чтение или событийная подписка).


Ответственность GraphQL / функции
Глобальный поиск по проекту search(projectId, query) — сделки, контакты, компании, продажи, активности, продукты

Реализация: Elasticsearch/OpenSearch или поиск по MongoDB; индексация по projectId, обновление при изменении сущностей.
Зависимости: события обновления из CRM-сервисов (или периодическая синхронизация).


5.15 Audit Service (audit)

Ответственность GraphQL / функции
Журнал событий projectAudit, organizationAudit, entityHistory
Типы событий CREATE, UPDATE, DELETE, TRANSFER, STATUS_CHANGE, LOGIN, LOGOUT, MERGE, SHARE
Хранение изменений JSON Patch + абсолютные значения ключевых полей

Хранит: audit_events.
Поступление данных: все доменные сервисы пишут события в Audit (напрямую или через очередь/шину).


5.16 Notifications Service (notification)

Ответственность GraphQL / функции
In-app уведомления notifications, unreadNotificationsCount, markNotificationRead, markAllNotificationsRead
Real-time доставка Подписка notificationReceived (WebSocket/SSE) — через AGW или отдельный endpoint
Правила доставки In-app + email для критичных; настройки per-user (дайджест и т.д.)

Хранит: notifications, настройки уведомлений per-user (каналы in-app/email, дайджест раз в час/день, отключаемые категории; критичные события не отключаются).
Зависимости: IGW (email, push), все домены (создание уведомлений по событиям). Может быть единый «Notification Backend» + отдельный WebSocket/SSE endpoint для real-time.


5.17 Billing Service (billing)

Ответственность Описание
Тарифы физлица Free / Pro / Business — лимиты проектов, участников в проекте, хранилища, автоматизаций per-project, типов продаж, конструктор отчётов (да/нет)
Тарифы организации Starter / Pro / Enterprise — лицензии (сотрудники), проекты, хранилище, автоматизации, типы продаж, SSO, self-hosted
Проверка лимитов Вызов Billing при: создании проекта, приглашении участника, создании правила автоматизации, создании типа продаж, загрузке файлов (квота хранилища). Модули не лимитируются — включение/выключение модулей по тарифу не проверяется.
Перелимит, грейс-период Read-only режим, баннеры; данные не удаляются
Платежи, счета, способы оплаты Интеграция с платёжным провайдером (Stripe и т.д.)

Хранит: subscriptions, plans, invoices, payment_methods, usage_snapshots.
Зависимости: Auth (пользователь), Org (организация); уведомления о перелимите/грейсе — через Notifications.


5.18 Импорт (в составе доменов + Import Worker)

Владение операцией импорта — у доменного сервиса (Contacts, Companies, Products; при наличии — Deals, Orders). Файл загружается через File Service; маппинг и опции (updateExisting, skipDuplicates) — в API домена. Тяжёлая обработка (парсинг CSV/Excel, создание записей) — в Import Worker (очередь задач); по завершении — уведомление инициатору через Notifications.

Сущность Мутация / владелец Примечание
Контакты importContacts — Contacts Service Фронт: /p/:pid/contacts/import
Компании importCompanies — Companies Service Фронт: /p/:pid/companies/import
Продукты importProducts — Products Service Фронт: /p/:pid/products/import
Сделки / Продажи Импорт при наличии в требованиях — Deals/Orders Service + Worker Фронт имеет маршруты deals/import, orders/import; уточнить объём в спеке.

5.19 Automation Service

Ответственность GraphQL / функции
Правила автоматизации CRUD правил: триггер (сделка на стадии, продажа на этапе, просроченная задача, поле изменено и т.д.) → условия → действия (создать контакт, задачу, уведомить, переместить, сгенерировать документ, email)
Включение/выключение Toggle правила без удаления
Статистика и лог Счётчик выполнений, последнее срабатывание, лог последних срабатываний (для UI)
Лимит по тарифу Проверка через Billing (5/50/∞ для физлица, 10/100/∞ для орг. per-project)

Хранит: automation_rules.
Зависимости: Billing (лимит правил), Deals/Orders/Activities/Contacts (триггеры и действия). Automation Worker (раздел 6) выполняет правила по событиям из очереди; сервис хранит конфигурацию и отдаёт её воркеру.


6. Чат (Chat Service / chat) — v2+ / опционально

Чат не входит в текущие требования (нет в требованиях v5.2 и в GraphQL-спеке). Во фронтенде есть прототип ChatDropdown (личные и групповые чаты) с захардкоженными данными; в уведомлениях — ссылка на /projects/1/chat. Ниже — проектирование на будущее для полноценного чата.

6.1 Chat Service (chat)

Ответственность Описание
Каналы Личные (user–user), групповые (проект, команда, комната)
Сообщения Отправка, хранение, история, редактирование/удаление (политика)
Участники Управление участниками групповых чатов; привязка к проекту/организации
Real-time WebSocket (или долгоживущий HTTP) — доставка сообщений без опроса
Read state Прочитано/непрочитано, счётчики для UI (колокольчик/бейдж)

Хранит: channels (или chats), messages, channel_members, read_state.
Протокол: WebSocket подключается через AGW (или отдельный WS endpoint); аутентификация по JWT.
Связь с CRM: опционально — привязка чата к сделке/контакту/компании (ссылка из карточки «Чат» в DealInfoWidget и т.д.) — v1/v2.

5.2 AGW и IGW для чата

Компонент Роль для чата
AGW 1) Маршрутизация HTTP API чата (список чатов, участники, история при пагинации). 2) Поднятие WebSocket для real-time: клиент подключается к AGW, AGW проксирует в Chat Service или в отдельный Chat Gateway (см. ниже).
IGW Для чата не обязателен; если нужны исходящие уведомления о новых сообщениях (email, push) — события из Chat Service в IGW/Notifications.

5.3 Chat Gateway (отдельный объект для real-time чата)

Чтобы не перегружать AGW и изолировать нагрузку по соединениям:

Назначение Описание
Chat Gateway (или WebSocket Gateway) Отдельный сервис/проект: принимает WebSocket-соединения, аутентификация (JWT из query/cookie), подписка на каналы пользователя. Передаёт сообщения из Chat Service в реальном времени (сервис чата пушит в Gateway по внутреннему брокеру — Redis Pub/Sub, RabbitMQ и т.д.).
Масштабирование Горизонтальное: несколько инстансов Gateway; подписки по userId/channelId через общий брокер.

Итого для чата (v2+): - Chat Service — доменная логика (каналы, сообщения, участники, история). - AGW — HTTP API чата и/или маршрутизация WS. - Chat Gateway (опционально) — выделенный проект для WebSocket чата и, при желании, для уведомлений (notificationReceived).


7. Workers и фоновые задачи

Сервис/воркер Ответственность
Automation Worker Выполнение правил из Automation Service: подписка на события (Deals, Orders, Activities) или очередь; выполнение действий (создать контакт, задачу, уведомить, переместить, документ, email).
DLQ / Webhook Retry Worker Повторные попытки webhook (Order Type); при исчерпании — статус ERROR, уведомление. В контуре IGW или отдельный воркер.
Scheduled / Cron Напоминания активностей (reminderAt); проверка «сделка на стадии > N дней» (триггер для автоматизаций/уведомлений); грейс-период и перелимит биллинга; архивация (soft delete → archive → hard delete); дайджест уведомлений (раз в час/день по настройкам пользователя); очистка shadow-копий после merge (30 дней, требования 15).
Import Worker Обработка очереди импорта (парсинг CSV/Excel, маппинг, вызов API Contacts/Companies/Products или Deals/Orders); по завершении — уведомление инициатору.
Document Generation Worker Тяжёлая генерация документов в фоне (если не синхронно в Documents Service) — очередь из Orders/Documents.

Координация при отключении модуля (требования 26): при выключении модуля Project Service инициирует паузу: webhook/DLQ retry (Orders), напоминания (Activities), правила автоматизации (Automation). При включении обратно webhook'и не возобновляются автоматически — повтор по решению менеджера.


8. File / Storage Service (storage)

Ответственность Описание
Загрузка файлов Аватар пользователя, шаблоны документов (DOCX), сгенерированные документы, вложения (v2)
Выдача по URL Подписанные URL (S3/MinIO) или прокси через свой endpoint
Квоты Учёт хранилища по workspace/организации для биллинга

Реализация: S3-совместимое хранилище (AWS S3, MinIO для self-hosted). Отдельный микросервис «File» или «Storage» — метаданные + выдача URL; сам объект хранится в бакете.


9. Что не упустить: чек-лист

Категория Компонент Назначение
Вход AGW Единая точка входа, проверка JWT, маршрутизация GraphQL/REST/WebSocket
Выход IGW Только исходящие: webhook, retry, DLQ, адаптеры (email, push), очереди
Аутентификация и пользователь Auth Service Регистрация, вход, 2FA, invite, сессии, refresh, me/workspaces/projects, настройки пользователя (язык, timezone, вид по умолчанию)
Организация Org Service Организации, подразделения, сотрудники, роли, приглашения
Проекты и доступ Project Service Проекты, Workspace, модули, участники, шаблоны, политики доступа (RBAC, иерархия, шаринг)
CRM Contacts, Companies Контакты, компании, many-to-many (владелец связки — Contacts), merge, импорт
CRM Pipelines, Deals Воронки, источники, сделки, stage log, transfer, drift
CRM Order Types, Orders Типы продаж, продажи, этапы, webhook, DLQ
CRM Products, Activities Продукты, активности, календарь, напоминания
CRM Automation Service Правила автоматизации (CRUD), лимит по тарифу, конфигурация для Automation Worker
Контент и отчёты Documents, Reports Шаблоны, генерация, отчёты, дашборд (read model / события)
Поиск и аудит Search, Audit Глобальный поиск, журнал событий
Уведомления Notifications In-app, real-time (WS/SSE), настройки per-user, дайджесты
Чат (v2+) Chat Service Опционально: каналы, сообщения, личные/групповые, история
Чат real-time (v2+) Chat Gateway Опционально: WebSocket для чата
Платежи и лимиты Billing Service Тарифы, лицензии, проверка лимитов (проекты, участники, хранилище, автоматизации, типы продаж), перелимит, грейс, платежи
Файлы File/Storage Service Загрузка, выдача URL, квоты
Фон Workers Automation, DLQ retry, cron (напоминания, дайджест, биллинг, retention, shadow cleanup), импорт, генерация документов. Координация паузы при отключении модуля.

Онбординг: сценарии (profile → first project → invite team) — оркестрация Auth, Project, Org; явно не выделен отдельный сервис, но поток нужно учитывать при интеграции.


10. Варианты группировки (упрощение числа сервисов)

Для первой версии можно уменьшить количество физических сервисов:

Группа Включить в один сервис
Identity Auth + Org (или только Auth, Org отдельно). Настройки пользователя — в Auth.
Project & Access Project + Workspace + политики доступа (один сервис для проектов и проверки видимости).
CRM Core Contacts + Companies + Pipelines + Deals + Order Types + Orders + Products
Work Activities + Documents (или Documents в CRM Core)
Automation Automation Service (правила) — отдельно или рядом с CRM Core; Worker — в Infra.
Analytics Reports + Search + Dashboard
Platform Audit отдельно (write-heavy); Notifications + Billing — при необходимости разделять по нагрузке (Audit и Billing лучше не объединять в один процесс).
Chat (v2+) Chat Service (+ Chat Gateway при необходимости) — опционально
Infra AGW, IGW, File Service, Workers — отдельно

Итого: AGW, IGW, доменные микросервисы (в т.ч. Automation, Access Control в составе Project), File/Storage, Workers, Billing. Chat и Chat Gateway — опционально (v2+). Ничего из перечисленного в разделе 9 не упущено.