flea/architecture.md
2025-10-16 22:11:06 +04:00

390 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Архитектура системы NOCR
Диаграмма взаимодействия между сервисами системы мониторинга Telegram-каналов.
```mermaid
classDiagram
TelegramListener --|> Bus : publishes
Bus --|> TextMatcher : subscribes
TextMatcher --|> Bus : publishes
Bus --|> TelegramClient : subscribes
TelegramClient --|> Users : REST API
TelegramClient --|> TextMatcher : REST API
class Bus{
<<RabbitMQ Message Broker>>
+MessageReceived events
+MessageEdited events
+TextSubscriptionMatched events
+TextSubscriptionUpdated events
}
class TelegramListener {
<<Сканер каналов>>
+publishes: MessageReceived
+publishes: MessageEdited
---
WTelegramClient (MTProto API)
Хранение сессий пользователей
}
class TextMatcher {
<<Обработчик совпадений>>
+publishes: TextSubscriptionMatched
+publishes: TextSubscriptionUpdated
-subscribes: MessageReceived
-subscribes: MessageEdited
---
REST API:
+long Create(CreateTextMatchRequest)
+TextMatchData? GetById(long id)
+TextMatchData[] GetByUserId(long userId)
+void Delete(long id)
+void Activate(long id)
+void Disable(long id)
---
БД: История совпадений (MariaDB)
Проверка регулярных выражений
}
class Users {
<<Управление пользователями>>
---
REST API:
+long Create(CreateUserRequest)
+UserData? GetById(long id)
+UserData? GetByIdentity(type, identity)
---
БД: Пользователи и настройки (MariaDB)
}
class TelegramClient {
<<Telegram Bot интерфейс>>
-subscribes: TextSubscriptionMatched
-subscribes: TextSubscriptionUpdated
---
Telegram.Bot (Bot API)
Обработка команд пользователей
Отправка уведомлений
---
REST клиенты:
-Users.Create()
-Users.GetById()
-Users.GetByIdentity()
-TextMatcher.GetByUserId()
-TextMatcher.Create()
}
```
## Описание компонентов
### 1. TelegramListener (Сканер каналов)
**Технологии:** .NET 8, WTelegramClient, Rebus
**Ответственность:**
- Подключение к Telegram через MTProto API
- Подписка на открытые каналы и чаты
- Получение новых и отредактированных сообщений
- Публикация событий в RabbitMQ
**Публикуемые события:**
- `MessageReceived` - новое сообщение получено
- `MessageEdited` - сообщение отредактировано
**Примечание:** WTelegram отправляет оба события (`UpdateNewChannelMessage` и `UpdateEditChannelMessage`) для одного и того же сообщения. TelegramListener публикует отдельные события, чтобы избежать дублирования уведомлений.
---
### 2. TextMatcher (Обработчик совпадений)
**Технологии:** .NET 8, Entity Framework Core, MariaDB, Rebus
**Ответственность:**
- Подписка на события сообщений от TelegramListener
- Проверка совпадений с пользовательскими подписками (regex, ключевые слова)
- Хранение истории совпадений в БД
- Публикация событий о найденных совпадениях
- REST API для управления подписками
**Подписывается на события:**
- `MessageReceived` - проверка нового сообщения
- `MessageEdited` - обновление ранее найденного совпадения
**Публикуемые события:**
- `TextSubscriptionMatched` - новое совпадение найдено
- `TextSubscriptionUpdated` - обновление ранее найденного совпадения
**REST API эндпоинты:**
- `POST /api/textmatch` - Создать новую подписку
- `GET /api/textmatch/{id}` - Получить подписку по ID
- `GET /api/textmatch/user/{userId}` - Получить все подписки пользователя
- `DELETE /api/textmatch/{id}` - Удалить подписку
- `POST /api/textmatch/{id}/activate` - Активировать подписку
- `POST /api/textmatch/{id}/disable` - Отключить подписку
---
### 3. TelegramClient (Telegram Bot)
**Технологии:** .NET 8, Telegram.Bot, Rebus, RestEase
**Ответственность:**
- Интерфейс бота для взаимодействия с пользователями
- Обработка команд бота (/start, /subscribe, /list и т.д.)
- Подписка на события совпадений
- Отправка уведомлений пользователям
- Интеграция с Users и TextMatcher через REST API
**Подписывается на события:**
- `TextSubscriptionMatched` - отправка уведомления о новом совпадении
- `TextSubscriptionUpdated` - уведомление об обновлении
**REST клиенты:**
- **Users API:** управление пользователями
- **TextMatcher API:** управление подписками
---
### 4. Users (Управление пользователями)
**Технологии:** .NET 8, Entity Framework Core, MariaDB
**Ответственность:**
- CRUD операции для пользователей
- Хранение предпочтений и настроек
- REST API для других сервисов
**REST API эндпоинты:**
- `POST /api/users` - Создать нового пользователя
- `GET /api/users/{id}` - Получить пользователя по ID
- `GET /api/users/identity/{type}/{identity}` - Найти пользователя по Telegram ID
---
### 5. RabbitMQ (Message Bus)
**Технологии:** RabbitMQ 3.x, Rebus
**Ответственность:**
- Асинхронная доставка событий между сервисами
- Гарантия доставки сообщений
- Очереди и обмены (exchanges)
**Настройка:**
- **Direct Exchange:** `nocr.direct` - для точечной маршрутизации
- **Topic Exchange:** `nocr.topics` - для публикации/подписки по топикам
- **Очереди:** Каждый сервис имеет свою input queue
---
## Паттерны взаимодействия
### Event-Driven Architecture (Асинхронная)
```
TelegramListener → RabbitMQ → TextMatcher → RabbitMQ → TelegramClient
```
**Преимущества:**
- Слабая связанность сервисов
- Масштабируемость (можно добавить несколько обработчиков)
- Отказоустойчивость (сообщения не теряются при падении сервиса)
### Request-Response (Синхронная)
```
TelegramClient → REST API → Users
TelegramClient → REST API → TextMatcher
```
**Использование:**
- Создание/получение данных пользователей
- Управление подписками
- Запросы, требующие немедленного ответа
---
## Потоки данных
### Основной поток (Мониторинг и уведомления)
1. **Сканирование:**
- TelegramListener подключается к Telegram MTProto
- Получает новые сообщения из каналов
- Публикует `MessageReceived` в RabbitMQ
2. **Обработка:**
- TextMatcher получает `MessageReceived`
- Проверяет сообщение на совпадение с подписками
- Сохраняет историю в БД
- Публикует `TextSubscriptionMatched` в RabbitMQ
3. **Уведомление:**
- TelegramClient получает `TextSubscriptionMatched`
- Получает данные пользователя из Users API
- Отправляет уведомление через Telegram Bot API
### Поток редактирования сообщений
1. **Обновление:**
- TelegramListener получает `UpdateEditChannelMessage`
- Публикует `MessageEdited` в RabbitMQ
2. **Повторная проверка:**
- TextMatcher получает `MessageEdited`
- Проверяет, было ли это сообщение ранее найдено
- Если было, публикует `TextSubscriptionUpdated`
3. **Уведомление об обновлении:**
- TelegramClient получает `TextSubscriptionUpdated`
- Отправляет обновленное уведомление пользователю
---
## Clean Architecture
Каждый сервис следует принципам Clean Architecture:
```
┌─────────────────────────────────────────┐
│ Host (API / Entry Point) │ ← ASP.NET Core, Controllers
├─────────────────────────────────────────┤
│ AppServices (Business Logic) │ ← Use Cases, Handlers
├─────────────────────────────────────────┤
│ Core (Domain / Shared) │ ← Entities, Interfaces
├─────────────────────────────────────────┤
│ Persistence (Data Access) │ ← EF Core, Repositories
├─────────────────────────────────────────┤
│ Async.Api.Contracts (Event Contracts) │ ← RabbitMQ Events (NuGet)
├─────────────────────────────────────────┤
│ Api.Contracts (REST Contracts) │ ← DTOs, Requests (NuGet)
├─────────────────────────────────────────┤
│ Migrator (Database Migrations) │ ← EF Core Migrations
└─────────────────────────────────────────┘
```
**Преимущества:**
- Независимость от фреймворков
- Тестируемость
- Независимость от UI/Database
- Переиспользование контрактов через NuGet
---
## Базы данных
### TextMatcher Database (MariaDB)
**Порт:** 3316 (локально), 3306 (Docker/K8s)
**Таблицы:**
- `TextMatches` - Пользовательские подписки
- `MatchHistory` - История найденных совпадений
- `__EFMigrationsHistory` - История миграций EF Core
### Users Database (MariaDB)
**Порт:** 3326 (локально), 3306 (Docker/K8s)
**Таблицы:**
- `Users` - Пользователи системы
- `UserPreferences` - Настройки пользователей
- `__EFMigrationsHistory` - История миграций EF Core
---
## Развертывание
### Docker Compose (Локальная разработка)
```
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ telegram- │ │ telegram- │ │ text- │ │ users │
│ listener │ │ client │ │ matcher │ │ │
│ :5040 │ │ :5050 │ │ :5041 │ │ :5042 │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ │ │ │
└────────────────┴────────────────┴────────────────┘
┌─────────┴─────────┐
│ RabbitMQ │
│ :5672, :15672 │
└───────────────────┘
┌───────────────┴───────────────┐
│ │
┌───────┴────────┐ ┌────────┴────────┐
│ text-matcher- │ │ users-db │
│ db :3316 │ │ :3326 │
└────────────────┘ └─────────────────┘
```
### Kubernetes (Production)
- **Namespace:** nocr
- **Services:** ClusterIP для внутренней коммуникации
- **Deployments:** С health checks и resource limits
- **Secrets:** Для Telegram API credentials и Bot tokens
- **ConfigMaps:** Для конфигурации окружения
---
## Мониторинг и наблюдаемость
### Health Checks
Каждый сервис предоставляет `/health` эндпоинт:
- **telegram-listener:** http://localhost:5040/health
- **text-matcher:** http://localhost:5041/health
- **users:** http://localhost:5042/health
- **telegram-client:** http://localhost:5050/health
### Логирование
- Структурированное логирование через Serilog
- Логи выводятся в stdout для Docker/K8s
- Централизованное логирование через kubectl logs
### Метрики
- RabbitMQ Management UI: http://localhost:15672
- Мониторинг очередей и exchanges
- Просмотр активных подключений
---
## Масштабирование
### Горизонтальное масштабирование
**Можно масштабировать:**
-**TextMatcher** - несколько инстансов обрабатывают сообщения параллельно
-**TelegramClient** - несколько инстансов отправляют уведомления параллельно
-**Users** - stateless API, можно масштабировать без ограничений
**Ограничения:**
- ⚠️ **TelegramListener** - один инстанс на одну Telegram сессию (ограничение WTelegram)
### Вертикальное масштабирование
- Увеличение CPU/RAM для сервисов
- Оптимизация запросов к БД
- Настройка connection pools
---
## Безопасность
### Секреты
- Telegram API credentials хранятся в K8s Secrets
- Bot tokens хранятся в K8s Secrets
- Database credentials в environment variables
### Сетевая безопасность
- Все сервисы работают в приватной сети
- Только TelegramClient имеет доступ к внешним API
- RabbitMQ защищен credentials
### Валидация
- Входящие данные валидируются в AppServices
- REST API использует Data Annotations
- Event contracts строго типизированы
---
## Дополнительная информация
- **[README.md](README.md)** - Общая документация проекта
- **[CONFIGURATION.md](CONFIGURATION.md)** - Руководство по конфигурации
- **[_deploy/README.md](_deploy/README.md)** - CI/CD и деплой
- **[CLAUDE.md](CLAUDE.md)** - Инструкции для AI-ассистента
---
оследнее обновление: 16 октября 2025_