add docs
All checks were successful
SonarQube / Build and analyze (push) Successful in 3m22s

This commit is contained in:
Leonid Pershin
2025-10-21 05:08:40 +03:00
parent bc1b3c4015
commit e5e69470f8
12 changed files with 3550 additions and 6 deletions

View File

@@ -0,0 +1,369 @@
# 📊 Модели данных
Полное описание всех моделей и сущностей в ChatBot.
## 🗂️ Типы моделей
### 1. Domain Models (Доменные модели)
- `ChatSession` - Основная модель сессии чата
- `ChatMessage` - DTO для сообщений
### 2. Entity Models (Сущности БД)
- `ChatSessionEntity` - Сущность сессии в БД
- `ChatMessageEntity` - Сущность сообщения в БД
### 3. Configuration Models (Конфигурация)
- `TelegramBotSettings`
- `OllamaSettings`
- `AISettings`
- `DatabaseSettings`
## 📦 Domain Models
### ChatSession
Основная модель для работы с сессией чата.
```csharp
public class ChatSession
{
public string SessionId { get; set; } // Уникальный ID
public long ChatId { get; set; } // Telegram chat ID
public string ChatType { get; set; } // Тип чата
public string ChatTitle { get; set; } // Название
public string Model { get; set; } // AI модель
public DateTime CreatedAt { get; set; } // Создан
public DateTime LastUpdatedAt { get; set; } // Обновлен
public int MaxHistoryLength { get; set; } // Макс история
}
```
**Ключевые методы:**
#### Работа с сообщениями
```csharp
// Добавить сообщение (базовый)
void AddMessage(ChatMessage message)
// Добавить с компрессией
Task AddMessageWithCompressionAsync(ChatMessage message, int threshold, int target)
// Добавить user сообщение
void AddUserMessage(string content, string username)
Task AddUserMessageWithCompressionAsync(string content, string username, int threshold, int target)
// Добавить assistant сообщение
void AddAssistantMessage(string content)
Task AddAssistantMessageWithCompressionAsync(string content, int threshold, int target)
// Получить все сообщения
List<ChatMessage> GetAllMessages()
// Количество сообщений
int GetMessageCount()
// Очистить историю
void ClearHistory()
```
#### Управление компрессией
```csharp
void SetCompressionService(IHistoryCompressionService service)
```
**Thread Safety:**
Все операции с `_messageHistory` защищены `lock(_lock)`
**Управление историей:**
- Автоматическое обрезание при превышении `MaxHistoryLength`
- Сохранение system prompt при обрезке
- Поддержка асинхронной компрессии
### ChatMessage (DTO)
```csharp
public class ChatMessage
{
public ChatRole Role { get; set; } // user/assistant/system
public string Content { get; set; } // Текст сообщения
}
```
**ChatRole enum:**
```csharp
public enum ChatRole
{
System, // Системный промпт
User, // Сообщение пользователя
Assistant // Ответ бота
}
```
## 💾 Entity Models
### ChatSessionEntity
Сущность для хранения в PostgreSQL.
```csharp
public class ChatSessionEntity
{
public int Id { get; set; } // PK (auto-increment)
public string SessionId { get; set; } // Unique, indexed
public long ChatId { get; set; } // Indexed
public string ChatType { get; set; } // Max 20 chars
public string? ChatTitle { get; set; } // Max 200 chars
public string Model { get; set; } // Max 100 chars
public DateTime CreatedAt { get; set; } // Required
public DateTime LastUpdatedAt { get; set; } // Required
public List<ChatMessageEntity> Messages { get; set; } // Navigation property
}
```
**Индексы:**
- `SessionId` - Unique index
- `ChatId` - Index для быстрого поиска
**Constraints:**
- `SessionId` - Required, MaxLength(50)
- `ChatId` - Required
- `ChatType` - Required, MaxLength(20)
**Relationships:**
- One-to-Many с `ChatMessageEntity`
- Cascade Delete - удаление сессии удаляет сообщения
### ChatMessageEntity
```csharp
public class ChatMessageEntity
{
public int Id { get; set; } // PK
public int SessionId { get; set; } // FK
public string Content { get; set; } // Max 10000 chars
public string Role { get; set; } // Max 20 chars
public int MessageOrder { get; set; } // Порядок в диалоге
public DateTime CreatedAt { get; set; } // Время создания
public ChatSessionEntity Session { get; set; } // Navigation property
}
```
**Индексы:**
- `SessionId` - Index
- `CreatedAt` - Index для сортировки
- `(SessionId, MessageOrder)` - Composite index
**Constraints:**
- `Content` - Required, MaxLength(10000)
- `Role` - Required, MaxLength(20)
## ⚙️ Configuration Models
### TelegramBotSettings
```csharp
public class TelegramBotSettings
{
public string BotToken { get; set; } = string.Empty;
}
```
**Validator:**
```csharp
RuleFor(x => x.BotToken)
.NotEmpty()
.MinimumLength(10);
```
### OllamaSettings
```csharp
public class OllamaSettings
{
public string Url { get; set; } = string.Empty;
public string DefaultModel { get; set; } = string.Empty;
}
```
**Validator:**
```csharp
RuleFor(x => x.Url)
.NotEmpty()
.Must(BeValidUrl);
RuleFor(x => x.DefaultModel)
.NotEmpty();
```
### AISettings
```csharp
public class AISettings
{
public double Temperature { get; set; } = 0.9;
public string SystemPromptPath { get; set; } = "Prompts/system-prompt.txt";
public int MaxRetryAttempts { get; set; } = 3;
public int RetryDelayMs { get; set; } = 1000;
public int RequestTimeoutSeconds { get; set; } = 180;
// Compression settings
public bool EnableHistoryCompression { get; set; } = true;
public int CompressionThreshold { get; set; } = 20;
public int CompressionTarget { get; set; } = 10;
public int MinMessageLengthForSummarization { get; set; } = 50;
public int MaxSummarizedMessageLength { get; set; } = 200;
// Advanced
public bool EnableExponentialBackoff { get; set; } = true;
public int MaxRetryDelayMs { get; set; } = 30000;
public int CompressionTimeoutSeconds { get; set; } = 30;
public int StatusCheckTimeoutSeconds { get; set; } = 10;
}
```
**Validator:**
```csharp
RuleFor(x => x.Temperature)
.GreaterThanOrEqualTo(0.0)
.LessThanOrEqualTo(2.0);
RuleFor(x => x.MaxRetryAttempts)
.GreaterThanOrEqualTo(1)
.LessThanOrEqualTo(10);
```
### DatabaseSettings
```csharp
public class DatabaseSettings
{
public string ConnectionString { get; set; } = string.Empty;
public bool EnableSensitiveDataLogging { get; set; } = false;
public int CommandTimeout { get; set; } = 30;
}
```
**Validator:**
```csharp
RuleFor(x => x.ConnectionString)
.NotEmpty();
RuleFor(x => x.CommandTimeout)
.GreaterThanOrEqualTo(5)
.LessThanOrEqualTo(300);
```
## 🔄 Маппинг Entity ↔ Model
### Session Entity → Model
```csharp
public ChatSession ToModel()
{
var session = new ChatSession
{
SessionId = this.SessionId,
ChatId = this.ChatId,
ChatType = this.ChatType,
ChatTitle = this.ChatTitle ?? string.Empty,
Model = this.Model,
CreatedAt = this.CreatedAt,
LastUpdatedAt = this.LastUpdatedAt
};
// Восстановить сообщения
foreach (var msg in Messages.OrderBy(m => m.MessageOrder))
{
session.AddMessage(new ChatMessage
{
Role = ParseRole(msg.Role),
Content = msg.Content
});
}
return session;
}
```
### Session Model → Entity
```csharp
public ChatSessionEntity ToEntity()
{
return new ChatSessionEntity
{
SessionId = this.SessionId,
ChatId = this.ChatId,
ChatType = this.ChatType,
ChatTitle = this.ChatTitle,
Model = this.Model,
CreatedAt = this.CreatedAt,
LastUpdatedAt = this.LastUpdatedAt,
Messages = this.GetAllMessages()
.Select((msg, index) => new ChatMessageEntity
{
Content = msg.Content,
Role = msg.Role.ToString(),
MessageOrder = index,
CreatedAt = DateTime.UtcNow
})
.ToList()
};
}
```
## 📐 Database Schema
```sql
-- Таблица сессий
CREATE TABLE chat_sessions (
id SERIAL PRIMARY KEY,
session_id VARCHAR(50) UNIQUE NOT NULL,
chat_id BIGINT NOT NULL,
chat_type VARCHAR(20) NOT NULL,
chat_title VARCHAR(200),
model VARCHAR(100),
created_at TIMESTAMP NOT NULL,
last_updated_at TIMESTAMP NOT NULL
);
CREATE INDEX idx_chat_sessions_session_id ON chat_sessions(session_id);
CREATE INDEX idx_chat_sessions_chat_id ON chat_sessions(chat_id);
-- Таблица сообщений
CREATE TABLE chat_messages (
id SERIAL PRIMARY KEY,
session_id INTEGER NOT NULL REFERENCES chat_sessions(id) ON DELETE CASCADE,
content VARCHAR(10000) NOT NULL,
role VARCHAR(20) NOT NULL,
message_order INTEGER NOT NULL,
created_at TIMESTAMP NOT NULL
);
CREATE INDEX idx_chat_messages_session_id ON chat_messages(session_id);
CREATE INDEX idx_chat_messages_created_at ON chat_messages(created_at);
CREATE INDEX idx_chat_messages_session_order ON chat_messages(session_id, message_order);
```
## 🎯 Жизненный цикл Session
```
1. Создание (GetOrCreate)
2. Добавление сообщений (AddMessage)
3. Проверка длины истории
4. Компрессия (если нужно)
5. Сохранение в БД (SaveSessionAsync)
6. Обновление LastUpdatedAt
```
## 📚 См. также
- [Архитектура слоев](./layers.md)
- [База данных](./database.md)
- [Сервисы](../development/services.md)

View File

@@ -0,0 +1,351 @@
# 🗄️ База данных
Описание работы с PostgreSQL в ChatBot.
## 📊 Схема базы данных
### Таблицы
#### chat_sessions
Хранит информацию о сессиях чатов.
| Колонка | Тип | Constraints | Описание |
|---------|-----|-------------|----------|
| id | SERIAL | PRIMARY KEY | Auto-increment ID |
| session_id | VARCHAR(50) | UNIQUE, NOT NULL | Уникальный идентификатор |
| chat_id | BIGINT | NOT NULL, INDEXED | Telegram chat ID |
| chat_type | VARCHAR(20) | NOT NULL | Тип чата |
| chat_title | VARCHAR(200) | NULL | Название чата |
| model | VARCHAR(100) | NULL | AI модель |
| created_at | TIMESTAMP | NOT NULL | Дата создания |
| last_updated_at | TIMESTAMP | NOT NULL | Последнее обновление |
**Индексы:**
```sql
CREATE UNIQUE INDEX idx_chat_sessions_session_id ON chat_sessions(session_id);
CREATE INDEX idx_chat_sessions_chat_id ON chat_sessions(chat_id);
```
#### chat_messages
Хранит историю сообщений.
| Колонка | Тип | Constraints | Описание |
|---------|-----|-------------|----------|
| id | SERIAL | PRIMARY KEY | Auto-increment ID |
| session_id | INTEGER | FK, NOT NULL | Ссылка на сессию |
| content | VARCHAR(10000) | NOT NULL | Текст сообщения |
| role | VARCHAR(20) | NOT NULL | user/assistant/system |
| message_order | INTEGER | NOT NULL | Порядок в диалоге |
| created_at | TIMESTAMP | NOT NULL | Время создания |
**Foreign Keys:**
```sql
FOREIGN KEY (session_id) REFERENCES chat_sessions(id) ON DELETE CASCADE
```
**Индексы:**
```sql
CREATE INDEX idx_chat_messages_session_id ON chat_messages(session_id);
CREATE INDEX idx_chat_messages_created_at ON chat_messages(created_at);
CREATE INDEX idx_chat_messages_session_order ON chat_messages(session_id, message_order);
```
## 🔄 Entity Framework Core
### DbContext
```csharp
public class ChatBotDbContext : DbContext
{
public DbSet<ChatSessionEntity> ChatSessions { get; set; }
public DbSet<ChatMessageEntity> ChatMessages { get; set; }
}
```
### Конфигурация моделей
```csharp
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// ChatSessionEntity
modelBuilder.Entity<ChatSessionEntity>(entity =>
{
entity.HasKey(e => e.Id);
entity.Property(e => e.SessionId).IsRequired().HasMaxLength(50);
entity.HasIndex(e => e.SessionId).IsUnique();
entity.HasIndex(e => e.ChatId);
entity.HasMany(e => e.Messages)
.WithOne(e => e.Session)
.HasForeignKey(e => e.SessionId)
.OnDelete(DeleteBehavior.Cascade);
});
// ChatMessageEntity
modelBuilder.Entity<ChatMessageEntity>(entity =>
{
entity.HasKey(e => e.Id);
entity.Property(e => e.Content).IsRequired().HasMaxLength(10000);
entity.HasIndex(e => e.SessionId);
entity.HasIndex(e => new { e.SessionId, e.MessageOrder });
});
}
```
### Миграции
#### Создание миграции
```bash
dotnet ef migrations add InitialCreate --project ChatBot
```
#### Применение миграций
```bash
# Вручную
dotnet ef database update --project ChatBot
# Автоматически при запуске (DatabaseInitializationService)
```
#### Откат миграции
```bash
dotnet ef database update PreviousMigration --project ChatBot
```
#### Удаление последней миграции
```bash
dotnet ef migrations remove --project ChatBot
```
## 🔌 Подключение к БД
### Connection String
```
Host={host};Port={port};Database={name};Username={user};Password={password}
```
**Пример:**
```
Host=localhost;Port=5432;Database=chatbot;Username=chatbot;Password=secret
```
### Конфигурация в Program.cs
```csharp
builder.Services.AddDbContext<ChatBotDbContext>(
(serviceProvider, options) =>
{
var dbSettings = serviceProvider
.GetRequiredService<IOptions<DatabaseSettings>>()
.Value;
options.UseNpgsql(
dbSettings.ConnectionString,
npgsqlOptions =>
{
npgsqlOptions.CommandTimeout(dbSettings.CommandTimeout);
}
);
}
);
```
### Connection Pooling
Npgsql автоматически использует connection pooling:
```
Max Pool Size=100
Min Pool Size=1
Connection Lifetime=300
Connection Idle Lifetime=300
```
## 📝 Repository Pattern
### Interface
```csharp
public interface IChatSessionRepository
{
Task<ChatSessionEntity?> GetByChatIdAsync(long chatId);
Task<ChatSessionEntity> CreateAsync(ChatSessionEntity session);
Task UpdateAsync(ChatSessionEntity session);
Task DeleteAsync(int id);
Task<List<ChatSessionEntity>> GetAllAsync();
}
```
### Implementation
```csharp
public class ChatSessionRepository : IChatSessionRepository
{
private readonly ChatBotDbContext _context;
public async Task<ChatSessionEntity?> GetByChatIdAsync(long chatId)
{
return await _context.ChatSessions
.Include(s => s.Messages)
.FirstOrDefaultAsync(s => s.ChatId == chatId);
}
public async Task<ChatSessionEntity> CreateAsync(ChatSessionEntity session)
{
_context.ChatSessions.Add(session);
await _context.SaveChangesAsync();
return session;
}
}
```
## 🚀 Оптимизация запросов
### Eager Loading
```csharp
// Загрузка с сообщениями
var session = await _context.ChatSessions
.Include(s => s.Messages)
.FirstOrDefaultAsync(s => s.ChatId == chatId);
```
### Projections
```csharp
// Только нужные поля
var sessionInfo = await _context.ChatSessions
.Where(s => s.ChatId == chatId)
.Select(s => new { s.SessionId, s.Model })
.FirstOrDefaultAsync();
```
### AsNoTracking
```csharp
// Read-only запросы
var sessions = await _context.ChatSessions
.AsNoTracking()
.ToListAsync();
```
## 🔧 Обслуживание БД
### Vacuum (очистка)
```sql
VACUUM ANALYZE chat_sessions;
VACUUM ANALYZE chat_messages;
```
### Статистика
```sql
SELECT
schemaname,
tablename,
n_live_tup,
n_dead_tup
FROM pg_stat_user_tables
WHERE tablename IN ('chat_sessions', 'chat_messages');
```
### Размер таблиц
```sql
SELECT
tablename,
pg_size_pretty(pg_total_relation_size(tablename::regclass)) as size
FROM pg_tables
WHERE schemaname = 'public';
```
## 🛡️ Безопасность
### SQL Injection Prevention
Entity Framework Core автоматически параметризует запросы:
```csharp
// ✅ Безопасно
var session = await _context.ChatSessions
.Where(s => s.ChatId == chatId)
.FirstOrDefaultAsync();
```
### Права пользователя БД
```sql
-- Создание пользователя
CREATE USER chatbot WITH PASSWORD 'secure_password';
-- Выдача прав
GRANT CONNECT ON DATABASE chatbot TO chatbot;
GRANT USAGE ON SCHEMA public TO chatbot;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO chatbot;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO chatbot;
```
## 📊 Мониторинг
### Active Connections
```sql
SELECT count(*)
FROM pg_stat_activity
WHERE datname = 'chatbot';
```
### Long Running Queries
```sql
SELECT
pid,
now() - pg_stat_activity.query_start AS duration,
query
FROM pg_stat_activity
WHERE state = 'active'
ORDER BY duration DESC;
```
### Locks
```sql
SELECT * FROM pg_locks
WHERE NOT granted;
```
## 🔄 Backup & Restore
### Backup
```bash
# Полный backup
pg_dump -U chatbot chatbot > backup.sql
# Только схема
pg_dump -U chatbot --schema-only chatbot > schema.sql
# Только данные
pg_dump -U chatbot --data-only chatbot > data.sql
```
### Restore
```bash
# Восстановление
psql -U chatbot chatbot < backup.sql
```
## 📚 См. также
- [Модели данных](./data-models.md)
- [Конфигурация](../configuration.md)
- [Установка](../installation.md)

349
docs/architecture/layers.md Normal file
View File

@@ -0,0 +1,349 @@
# 🏛️ Слои приложения
Детальное описание каждого слоя архитектуры ChatBot.
## 1⃣ Presentation Layer (Уровень представления)
### Telegram Bot Integration
Отвечает за взаимодействие с пользователями через Telegram.
#### Основные компоненты
**TelegramBotService**
- Главный сервис, управляющий ботом
- Запускается как `IHostedService`
- Получает updates через Webhook или Long Polling
- Координирует обработку сообщений
**TelegramMessageHandler**
- Обработка входящих сообщений
- Фильтрация по типу чата
- Извлечение информации о пользователе
- Передача в ChatService
**TelegramCommandProcessor**
- Распознавание команд (`/start`, `/help`, и т.д.)
- Routing к соответствующему обработчику
- Валидация прав доступа
**Commands (Команды)**
```
StartCommand - /start
HelpCommand - /help
ClearCommand - /clear
SettingsCommand - /settings
StatusCommand - /status
```
#### Паттерн Command
```csharp
public interface ITelegramCommand
{
string Command { get; }
string Description { get; }
Task<ReplyInfo> ExecuteAsync(TelegramCommandContext context);
}
```
Каждая команда:
- Изолирована
- Легко тестируется
- Независимо расширяема
## 2⃣ Service Layer (Бизнес-логика)
### Core Services
#### ChatService
**Ответственность:**
- Управление сессиями чатов
- Координация между AI и storage
- Обработка сообщений пользователей
**Методы:**
```csharp
GetOrCreateSession() // Получить/создать сессию
ProcessMessageAsync() // Обработать сообщение
ClearHistoryAsync() // Очистить историю
UpdateSessionParameters() // Обновить параметры
```
**Взаимодействия:**
- IAIService → Генерация ответов
- ISessionStorage → Хранение сессий
- IHistoryCompressionService → Оптимизация истории
#### AIService
**Ответственность:**
- Генерация ответов через Ollama
- Управление retry логикой
- Таймауты и error handling
**Методы:**
```csharp
GenerateChatCompletionAsync() // Базовая генерация
GenerateChatCompletionWithCompressionAsync() // С сжатием
```
**Особенности:**
- Экспоненциальный backoff
- Streaming responses
- Timeout handling
- System prompt injection
#### HistoryCompressionService
**Ответственность:**
- Суммаризация длинной истории
- Оптимизация контекста
- Сохранение важной информации
**Алгоритм:**
```
1. Сохранить system prompt
2. Сохранить последние N сообщений
3. Суммаризировать старые сообщения
4. Объединить результаты
```
**Методы:**
```csharp
ShouldCompress() // Проверка необходимости
CompressHistoryAsync() // Выполнить сжатие
SummarizeMessageAsync() // Суммаризировать одно сообщение
```
#### SystemPromptService
**Ответственность:**
- Загрузка системного промпта
- Кеширование промпта
- Обработка ошибок чтения файла
#### ModelService
**Ответственность:**
- Управление AI моделями
- Получение списка доступных моделей
- Переключение между моделями
### Storage Services
#### DatabaseSessionStorage
**Ответственность:**
- Сохранение сессий в PostgreSQL
- CRUD операции через репозиторий
- Синхронизация с базой данных
**Методы:**
```csharp
GetOrCreate() // Получить или создать
Get() // Получить по ID
SaveSessionAsync() // Сохранить сессию
Remove() // Удалить сессию
CleanupOldSessions() // Очистка старых
```
**Особенности:**
- Автоматическая конвертация Entity ↔ Model
- Lazy loading сессий
- Кеширование в памяти
#### InMemorySessionStorage
**Ответственность:**
- Хранение сессий в памяти
- Быстрый доступ для тестов
- Не требует БД
**Использование:**
- Unit тесты
- Development режим
- Прототипирование
## 3⃣ Data Access Layer (Доступ к данным)
### DbContext
**ChatBotDbContext**
- Entity Framework Core контекст
- Конфигурация таблиц
- Отношения между сущностями
```csharp
DbSet<ChatSessionEntity> ChatSessions
DbSet<ChatMessageEntity> ChatMessages
```
**Конфигурация:**
- Индексы для оптимизации
- Foreign Keys и Cascade Delete
- Constraints и Validation
### Repositories
#### ChatSessionRepository
**Ответственность:**
- Абстракция доступа к данным
- CRUD операции с сессиями
- Query оптимизация
**Методы:**
```csharp
GetByChatIdAsync() // По chat ID
CreateAsync() // Создать
UpdateAsync() // Обновить
DeleteAsync() // Удалить
GetAllAsync() // Все сессии
```
**Преимущества паттерна Repository:**
- Изоляция от EF Core
- Легкое тестирование
- Возможность смены ORM
### Entities (Сущности БД)
#### ChatSessionEntity
```csharp
Id // PK
SessionId // Unique identifier
ChatId // Telegram chat ID
ChatType // private/group/supergroup
ChatTitle // Название чата
Model // AI модель
CreatedAt // Дата создания
LastUpdatedAt // Последнее обновление
Messages // Коллекция сообщений
```
#### ChatMessageEntity
```csharp
Id // PK
SessionId // FK → ChatSessionEntity
Content // Текст сообщения
Role // user/assistant/system
MessageOrder // Порядок в диалоге
CreatedAt // Дата создания
```
## 4⃣ Infrastructure Layer (Инфраструктура)
### External Services
#### PostgreSQL
**Функции:**
- Persistent storage сессий
- Транзакционность
- ACID гарантии
**Оптимизации:**
- Индексы на ChatId, SessionId
- Connection pooling
- Query optimization
#### Ollama
**Функции:**
- Локальные LLM модели
- Streaming responses
- Multiple models support
**Адаптер:**
```csharp
OllamaClientAdapter : IOllamaClient
```
Абстрагирует от конкретной реализации OllamaSharp.
#### Telegram Bot API
**Функции:**
- Получение updates
- Отправка сообщений
- Управление ботом
**Wrapper:**
```csharp
TelegramBotClientWrapper : ITelegramBotClientWrapper
```
## 🔄 Взаимодействие слоев
### Правила взаимодействия
```
Presentation → Service → Data → Infrastructure
↓ ↓ ↓
Interfaces Interfaces Repository
```
**Принципы:**
- Слои зависят только от интерфейсов
- Вышестоящие слои не знают о нижестоящих
- Dependency Injection связывает реализации
### Пример: Обработка сообщения
```
1. TelegramBotService (Presentation)
↓ вызывает
2. TelegramMessageHandler (Presentation)
↓ вызывает
3. ChatService (Service)
↓ использует
4. ISessionStorage (Service Interface)
↓ реализован как
5. DatabaseSessionStorage (Service)
↓ использует
6. IChatSessionRepository (Data Interface)
↓ реализован как
7. ChatSessionRepository (Data)
↓ использует
8. ChatBotDbContext (Data)
↓ обращается к
9. PostgreSQL (Infrastructure)
```
## 🎯 Разделение ответственности
### Presentation Layer
- ✅ Обработка входящих запросов
- ✅ Валидация команд
- ✅ Форматирование ответов
- ❌ Бизнес-логика
- ❌ Доступ к данным
### Service Layer
- ✅ Бизнес-логика
- ✅ Координация сервисов
- ✅ Валидация бизнес-правил
- ❌ UI логика
- ❌ SQL запросы
### Data Layer
- ✅ CRUD операции
- ✅ Query построение
- ✅ Маппинг Entity ↔ Model
- ❌ Бизнес-логика
- ❌ UI логика
### Infrastructure Layer
- ✅ Внешние интеграции
- ✅ Конфигурация подключений
- ❌ Бизнес-логика
## 📚 См. также
- [Архитектура - Обзор](./overview.md)
- [Модели данных](./data-models.md)
- [Структура проекта](../development/project-structure.md)

View File

@@ -0,0 +1,210 @@
# 🏗️ Архитектура проекта
## 📐 Общая архитектура
ChatBot построен на принципах **Clean Architecture** с четким разделением ответственности.
## 🔄 Диаграмма слоев
```
┌─────────────────────────────────────────────┐
│ Presentation Layer │
│ (Telegram Bot, Commands, Handlers) │
├─────────────────────────────────────────────┤
│ Service Layer │
│ (ChatService, AIService, Compression) │
├─────────────────────────────────────────────┤
│ Data Access Layer │
│ (Repositories, DbContext, Entities) │
├─────────────────────────────────────────────┤
│ Infrastructure Layer │
│ (PostgreSQL, Ollama, Telegram) │
└─────────────────────────────────────────────┘
```
## 🎯 Принципы проектирования
### SOLID
- **S**ingle Responsibility - Каждый класс имеет одну ответственность
- **O**pen/Closed - Открыт для расширения, закрыт для модификации
- **L**iskov Substitution - Интерфейсы взаимозаменяемы
- **I**nterface Segregation - Мелкие специализированные интерфейсы
- **D**ependency Inversion - Зависимость от абстракций
### Design Patterns
- **Repository Pattern** - `IChatSessionRepository`
- **Dependency Injection** - Microsoft.Extensions.DependencyInjection
- **Strategy Pattern** - `ISessionStorage` (In-Memory/Database)
- **Command Pattern** - Telegram команды
- **Adapter Pattern** - `OllamaClientAdapter`
## 📦 Компоненты системы
### 1. Presentation Layer
**Telegram Bot Integration:**
- `TelegramBotService` - Основной сервис бота
- `TelegramMessageHandler` - Обработка сообщений
- `TelegramCommandProcessor` - Обработка команд
- `TelegramErrorHandler` - Обработка ошибок
- Commands: `StartCommand`, `HelpCommand`, `ClearCommand`, etc.
### 2. Service Layer
**Core Services:**
- `ChatService` - Управление диалогами
- `AIService` - Генерация ответов AI
- `HistoryCompressionService` - Сжатие истории
- `SystemPromptService` - Загрузка системного промпта
- `ModelService` - Управление AI моделями
**Storage Services:**
- `DatabaseSessionStorage` - Хранение в БД
- `InMemorySessionStorage` - Хранение в памяти
### 3. Data Access Layer
**Repositories:**
- `ChatSessionRepository` - Работа с сессиями
- `ChatBotDbContext` - EF Core контекст
**Entities:**
- `ChatSessionEntity` - Сессия чата
- `ChatMessageEntity` - Сообщение чата
### 4. Infrastructure
**External Services:**
- PostgreSQL - База данных
- Ollama - AI модели
- Telegram Bot API - Telegram интеграция
## 🔌 Dependency Injection
```csharp
// Telegram Services
services.AddSingleton<ITelegramBotClient>
services.AddSingleton<ITelegramBotService>
services.AddSingleton<ITelegramMessageHandler>
// Core Services
services.AddSingleton<IAIService, AIService>
services.AddScoped<ChatService>
services.AddScoped<ISessionStorage, DatabaseSessionStorage>
// Data Access
services.AddDbContext<ChatBotDbContext>
services.AddScoped<IChatSessionRepository, ChatSessionRepository>
```
## 🔄 Data Flow
### Обработка сообщения пользователя
```
User Message
TelegramBotService (получение update)
TelegramMessageHandler (валидация)
TelegramCommandProcessor (проверка команды)
↓ (если не команда)
ChatService (обработка сообщения)
SessionStorage (получение/создание сессии)
AIService (генерация ответа)
OllamaClient (запрос к AI)
AIService (получение ответа)
ChatService (сохранение в историю)
SessionStorage (сохранение сессии)
TelegramMessageSender (отправка ответа)
User receives response
```
## 🗂️ Структура проекта
```
ChatBot/
├── Common/ # Общие константы
│ └── Constants/
├── Data/ # Слой доступа к данным
│ ├── Interfaces/
│ ├── Repositories/
│ └── ChatBotDbContext.cs
├── Models/ # Модели и конфигурация
│ ├── Configuration/
│ ├── Dto/
│ ├── Entities/
│ └── ChatSession.cs
├── Services/ # Бизнес-логика
│ ├── HealthChecks/
│ ├── Interfaces/
│ ├── Telegram/
│ └── *.cs
├── Migrations/ # EF Core миграции
├── Prompts/ # AI промпты
└── Program.cs # Точка входа
```
## 📊 Диаграмма классов (упрощенная)
```
┌─────────────────────┐
│ ChatService │
├─────────────────────┤
│ + ProcessMessage() │
│ + ClearHistory() │
└──────────┬──────────┘
├──> IAIService
├──> ISessionStorage
└──> IHistoryCompressionService
┌─────────────────────┐
│ AIService │
├─────────────────────┤
│ + GenerateChat() │
└──────────┬──────────┘
└──> IOllamaClient
```
## 🔐 Security Architecture
- Секреты в переменных окружения
- Валидация входных данных
- SQL инъекции предотвращены (EF Core)
- Безопасное логирование (без секретов)
## 📈 Scalability
**Готовность к масштабированию:**
- Stateless сервисы
- Database session storage
- Async/await везде
- Connection pooling
- Health checks
## 🎛️ Configuration Management
```
Environment Variables → .env
appsettings.json
IOptions<T>
Validation (FluentValidation)
Services
```