Files
TG_autoposter/docs/ARCHITECTURE.md
2025-12-18 05:55:32 +09:00

374 lines
15 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.

# Архитектура TG Autoposter
## Общая структура
```
┌─────────────────────────────────────────────────────┐
│ Telegram User (в личных сообщениях) │
└──────────────────────┬──────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ Telegram Bot (python-telegram-bot) │
│ main.py → app/__init__.py │
└──────────────────┬──────────────────┬──────────────┘
│ │
┌──────────┘ └────────────┐
↓ ↓
┌─────────────┐ ┌──────────────┐
│ Handlers │ │ Callbacks │
│ (команды) │ │ (кнопки) │
└──────┬──────┘ └──────┬───────┘
│ │
└──────────────┬───────────────────────┘
┌───────────────────────────────┐
│ Database Repository │
│ (repository.py) │
│ - GroupRepository │
│ - MessageRepository │
│ - MessageGroupRepository │
└──────────────┬────────────────┘
┌───────────────────────────────┐
│ SQLAlchemy ORM │
│ (database/__init__.py) │
│ - AsyncSessionLocal │
│ - engine │
└──────────────┬────────────────┘
┌───────────────────────────────┐
│ Database (SQLite/PgSQL) │
│ - groups │
│ - messages │
│ - message_groups │
└───────────────────────────────┘
```
## Слои приложения
### 1. **Presentation Layer** (Telegram Bot)
- Файлы: `handlers/`, `utils/keyboards.py`
- Отвечает за взаимодействие с пользователем
- Обработка команд и callback'ов
- Формирование инлайн кнопок
### 2. **Application Logic Layer** (Handlers)
- Файлы: `handlers/commands.py`, `handlers/callbacks.py`, `handlers/sender.py`, `handlers/message_manager.py`, `handlers/group_manager.py`
- Бизнес-логика отправки сообщений
- Учет slow mode
- Управление сообщениями и группами
### 3. **Repository Layer** (Data Access)
- Файл: `database/repository.py`
- CRUD операции для каждой сущности
- Абстракция работы с БД
- Защита от прямых SQL запросов
### 4. **ORM Layer** (Object-Relational Mapping)
- Файл: `database/__init__.py`
- SQLAlchemy для работы с БД
- Асинхронные сессии
- Управление подключением
### 5. **Data Layer** (Models & Database)
- Файлы: `models/`, база данных
- Определение структуры данных
- Связи между таблицами
- Физическое хранилище
## Модели данных
### Group (Группа)
```
┌──────────────────┐
│ Group │
├──────────────────┤
│ id (PK) │
│ chat_id (UNQ) │
│ title │
│ slow_mode_delay │
│ last_message_time│
│ is_active │
│ created_at │
│ updated_at │
└──────────────────┘
│ 1..N
└───────────────────┐
┌────────────────┐
│ MessageGroup │
│ (pivot table) │
└────────────────┘
│ 1..N
┌────────────────┐
│ Message │
│ (Сообщение) │
└────────────────┘
```
## Поток данных при отправке сообщения
```
1. Пользователь нажимает "📤 Отправить"
2. send_message() получает callback
├─→ Получить сообщение из БД
│ (MessageRepository.get_message)
├─→ Получить все связи для отправки
│ (MessageGroupRepository.get_message_groups_to_send)
3. Для каждой группы:
├─→ Проверить slow mode
│ (can_send_message() из utils)
├─→ Если нужно, ждать
│ (asyncio.sleep)
├─→ Отправить сообщение через Bot API
│ (context.bot.send_message)
├─→ Обновить время последнего сообщения
│ (GroupRepository.update_last_message_time)
├─→ Отметить как отправленное
│ (MessageGroupRepository.mark_as_sent)
└─→ Обновить статус в UI
(query.edit_message_text)
4. Показать итоговое сообщение пользователю
```
## Поток данных при добавлении бота в группу
```
1. Бот добавлен в группу
2. Telegram отправляет my_chat_member update
3. my_chat_member() обработчик получает событие
├─→ Проверить статус: member или left
├─→ Если member:
│ │
│ ├─→ Получить информацию о группе
│ │ (context.bot.get_chat)
│ │
│ ├─→ Получить slow mode
│ │
│ ├─→ Проверить есть ли уже в БД
│ │ (GroupRepository.get_group_by_chat_id)
│ │
│ └─→ Добавить или обновить
│ (GroupRepository.add_group)
└─→ Если left:
└─→ Деактивировать в БД
(GroupRepository.deactivate_group)
```
## Асинхронность
Весь код использует async/await:
```python
async def main():
# Инициализация
await init_db()
# Создание приложения
application = Application.builder().token(TOKEN).build()
# Добавление обработчиков
application.add_handler(...)
# Polling (слушаем обновления)
await application.run_polling()
```
## Обработка ошибок
```
┌─────────────────────────────────────┐
│ Попытка отправки сообщения │
└────────────┬────────────────────────┘
┌──────┴──────┐
│ │
↓ ↓
SUCCESS EXCEPTION
│ │
├─→ mark_as_sent() ├─→ Сохранить ошибку
│ (is_sent=True) mark_as_sent(error=str(e))
│ (is_sent=False)
└─────────┬──────────┬──────────┘
│ │
└─────────┘
Показать статус
пользователю
```
## Состояния ConversationHandler
При создании сообщения:
```
START
└─→ CREATE_MSG_TITLE
(ввод названия)
└─→ CREATE_MSG_TEXT
(ввод текста, создание в БД)
└─→ SELECT_GROUPS
(выбор групп с кнопками)
└─→ DONE или CANCEL
(завершение)
```
## Безопасность данных
### Уровни защиты:
1. **Переменные окружения** (.env)
- Токен бота не в коде
- DATABASE_URL скрыт
2. **Асинхронные сессии**
- Каждая операция в собственной транзакции
- Автоматический rollback при ошибке
3. **SQL Injection**
- SQLAlchemy использует parameterized queries
- Защита встроена в ORM
4. **Логирование**
- Чувствительные данные не логируются
- Ошибки записываются в файл с ротацией
## Масштабируемость
### Текущие возможности:
- ✅ Линейная масштабируемость с количеством групп
- ✅ Асинхронная обработка не блокирует бота
- ✅ БД может быть PostgreSQL для производства
- ✅ Логирование с ротацией
### Возможные улучшения:
- [ ] Queue (Celery) для больших рассылок
- [ ] Cache (Redis) для часто используемых данных
- [ ] Webhook вместо polling для масштабирования
- [ ] Connection pooling для БД
## Производительность
### Оптимизации:
1. **Асинхронность**
- Не блокирует при I/O операциях
- Может обрабатывать много групп параллельно
2. **Batch операции**
- Отправка в несколько групп одновременно
- Кэширование результатов
3. **Индексы в БД**
- `chat_id` в таблице Groups (UNIQUE)
- Foreign keys оптимизированы
## Тестирование
### Структура для тестирования:
```
tests/
├── test_models.py # Модели
├── test_repository.py # Репозитории
├── test_handlers.py # Обработчики
└── test_integration.py # Интеграция
```
## Развертывание
### Production deployment:
```
1. Клонировать репо
2. pip install -r requirements.txt
3. Настроить .env с реальным токеном
4. Использовать PostgreSQL вместо SQLite
5. Запустить с systemd/supervisor
6. Настроить ротацию логов
7. Мониторинг и алерты
```
## Взаимодействие компонентов
```
┌────────────────────────────────────────────────────────────┐
│ Telegram Bot (main.py) │
├────────────────────────────────────────────────────────────┤
│ Application (python-telegram-bot) │
│ ├─ CommandHandler (/start, /help) │
│ ├─ CallbackQueryHandler (callback buttons) │
│ ├─ ChatMemberHandler (my_chat_member events) │
│ └─ ConversationHandler (multi-step flows) │
└────────────────────────────────────────────────────────────┘
↓ ↓ ↓ ↓
┌─────────┐ ┌────────────┐ ┌──────────┐ ┌─────────────┐
│ commands │ │ callbacks │ │ sender │ │group_manager│
│ .py │ │ .py │ │ .py │ │ .py │
└────┬─────┘ └──────┬─────┘ └────┬─────┘ └──────┬──────┘
│ │ │ │
└────────────────┼─────────────┼───────────────┘
┌────▼────┐
│ message_ │
│manager.py│
└────┬─────┘
┌──────────┴──────────┐
│ │
┌────▼────────┐ ┌────▼────────┐
│ Repository │ │ Utils │
│ Layer │ │ - keyboards│
│ │ │ - slow_mode│
└────┬────────┘ └─────────────┘
┌────▼─────────┐
│ SQLAlchemy │
│ ORM │
└────┬─────────┘
┌────▼──────────┐
│ SQLite/PgSQL │
│ Database │
└───────────────┘
```
Это архитектура позволяет:
- ✅ Легко тестировать каждый слой
- ✅ Менять БД без изменения логики
- ✅ Расширять функциональность
- ✅ Масштабировать приложение