diff --git a/ChatBot.Tests/Services/Telegram/TelegramBotServiceBasicTests.cs b/ChatBot.Tests/Services/Telegram/TelegramBotServiceBasicTests.cs
new file mode 100644
index 0000000..8fa8c4a
--- /dev/null
+++ b/ChatBot.Tests/Services/Telegram/TelegramBotServiceBasicTests.cs
@@ -0,0 +1,84 @@
+using ChatBot.Services.Telegram.Services;
+using FluentAssertions;
+using Microsoft.Extensions.Logging;
+using Moq;
+using Telegram.Bot;
+
+namespace ChatBot.Tests.Services.Telegram;
+
+///
+/// Базовые тесты для TelegramBotService
+/// Полное тестирование затруднено из-за extension методов Telegram.Bot
+///
+public class TelegramBotServiceBasicTests
+{
+ [Fact]
+ public void Constructor_ShouldCreateInstance()
+ {
+ // Arrange
+ var loggerMock = new Mock>();
+ var botClientMock = new Mock();
+ var serviceProviderMock = new Mock();
+
+ // Act
+ var service = new TelegramBotService(
+ loggerMock.Object,
+ botClientMock.Object,
+ serviceProviderMock.Object
+ );
+
+ // Assert
+ service.Should().NotBeNull();
+ }
+
+ [Fact]
+ public async Task StopAsync_ShouldComplete()
+ {
+ // Arrange
+ var loggerMock = new Mock>();
+ var botClientMock = new Mock();
+ var serviceProviderMock = new Mock();
+
+ var service = new TelegramBotService(
+ loggerMock.Object,
+ botClientMock.Object,
+ serviceProviderMock.Object
+ );
+
+ // Act
+ var act = async () => await service.StopAsync(CancellationToken.None);
+
+ // Assert
+ await act.Should().NotThrowAsync();
+ }
+
+ [Fact]
+ public async Task StopAsync_ShouldLog()
+ {
+ // Arrange
+ var loggerMock = new Mock>();
+ var botClientMock = new Mock();
+ var serviceProviderMock = new Mock();
+
+ var service = new TelegramBotService(
+ loggerMock.Object,
+ botClientMock.Object,
+ serviceProviderMock.Object
+ );
+
+ // Act
+ await service.StopAsync(CancellationToken.None);
+
+ // Assert
+ loggerMock.Verify(
+ x => x.Log(
+ LogLevel.Information,
+ It.IsAny(),
+ It.Is((v, t) => v.ToString()!.Contains("Stopping Telegram bot service")),
+ It.IsAny(),
+ It.IsAny>()
+ ),
+ Times.Once
+ );
+ }
+}
diff --git a/SonarQube_70percent_Analysis.md b/SonarQube_70percent_Analysis.md
new file mode 100644
index 0000000..f956cbb
--- /dev/null
+++ b/SonarQube_70percent_Analysis.md
@@ -0,0 +1,154 @@
+# Анализ: почему покрытие 70%, а не 86%?
+
+## 🔍 Разница между локальным и SonarQube coverage
+
+**Локально (coverlet)**: 86.59%
+**SonarQube**: 70%
+**Разница**: ~16%
+
+---
+
+## 🤔 Возможные причины
+
+### 1. **"Coverage on New Code" vs "Overall Coverage"**
+
+SonarQube разделяет:
+- **Overall Coverage** - покрытие всего проекта
+- **Coverage on New Code** - покрытие только изменений в текущей ветке
+
+Вы смотрите на **Coverage on New Code** (70%), который:
+- Считается только для файлов, измененных после определенной даты
+- Не учитывает старый хорошо покрытый код
+- Включает ВСЕ новые изменения (в том числе миграции, если они были изменены)
+
+### 2. **SonarQube может по-другому считать исключения**
+
+Даже с правильными настройками, SonarQube может:
+- Не полностью применить exclusions к "New Code"
+- Считать строки по-другому (комментарии, пустые строки)
+- Учитывать partial classes иначе
+
+---
+
+## ✅ Решения
+
+### Вариант 1: Проверить "Overall Coverage" в SonarQube
+
+Откройте SonarQube dashboard и найдите:
+- **Overall Coverage** (должно быть ~86%)
+- **Coverage on New Code** (сейчас 70%)
+
+Если **Overall Coverage** ~86%, то все в порядке! Просто нужно:
+1. Дождаться merge в master
+2. Или добавить больше тестов для нового кода
+
+### Вариант 2: Сбросить "New Code Period"
+
+В SonarQube можно изменить период "New Code":
+1. Зайти в Project Settings → New Code
+2. Изменить на "Previous version" или "Number of days"
+3. Переанализировать проект
+
+### Вариант 3: Добавить больше тестов для конкретных файлов
+
+Давайте найдем, какие ИМЕННО файлы SonarQube считает недопокрытыми.
+
+---
+
+## 🎯 Действия прямо сейчас
+
+### Шаг 1: Проверьте SonarQube dashboard
+
+Найдите страницу "Coverage" в SonarQube и ответьте на вопросы:
+
+1. **Какое "Overall Coverage"?** (не "New Code Coverage")
+2. **Какие файлы показаны как недопокрытые?**
+3. **Какой период установлен для "New Code"?**
+
+### Шаг 2: Если нужно добавить тесты
+
+Я могу создать дополнительные тесты для:
+
+#### Сервисы без тестов:
+- ❌ `TelegramBotService` - нет тестов (инфраструктурный код)
+
+#### Сервисы с неполным покрытием (возможно):
+- ⚠️ `ModelService` - может быть не все пути покрыты
+- ⚠️ `ChatService` - могут быть непокрытые edge cases
+- ⚠️ `AIService` - могут быть непокрытые exception paths
+
+#### Команды с возможно неполным покрытием:
+- ⚠️ `SettingsCommand` - могут быть edge cases
+- ⚠️ `ClearCommand` - могут быть exception paths
+
+---
+
+## 💡 Рекомендации
+
+### Если Overall Coverage ~86%:
+
+**Ваш код отлично покрыт!** Проблема только в "New Code Coverage".
+
+**Решение**:
+1. Просто commit и push
+2. После merge в master "New Code Coverage" станет "Overall Coverage"
+3. Или добавьте comment в SonarQube, объясняющий ситуацию
+
+### Если Overall Coverage тоже ~70%:
+
+Тогда проблема в том, что SonarQube не применяет исключения корректно.
+
+**Решение**:
+1. Проверить логи SonarQube scanner в CI/CD
+2. Убедиться, что `.opencover.xml` файл создается правильно
+3. Возможно добавить `.globalconfig` для Roslyn analyzers
+
+---
+
+## 📊 Ожидаемая метрика после исправления
+
+```
+✅ Overall Coverage: 86.59%
+⚠️ Coverage on New Code: 70-86% (зависит от периода)
+✅ Quality Gate: SHOULD PASS (если смотрим на Overall)
+```
+
+---
+
+## 🚀 Что делать СЕЙЧАС
+
+### 1. Проверьте SonarQube
+Откройте SonarQube и найдите:
+- Overall Coverage (главная метрика)
+- Список непокрытых файлов
+- New Code Period настройки
+
+### 2. Если Overall Coverage ~86%:
+✅ **Все отлично! Push код как есть.**
+
+### 3. Если Overall Coverage ~70%:
+Скажите мне, какие КОНКРЕТНЫЕ файлы SonarQube показывает как недопокрытые, и я создам для них тесты.
+
+---
+
+## 📝 Дополнительная информация
+
+### Как увидеть Overall Coverage в SonarQube:
+
+1. Откройте ваш проект в SonarQube
+2. На главной странице проекта найдите блок "Coverage"
+3. Там должны быть ДВЕ цифры:
+ - **Coverage** (Overall) - главная метрика
+ - **Coverage on New Code** - только новые изменения
+
+### Как изменить New Code Period:
+
+1. Project Settings → New Code
+2. Выберите один из вариантов:
+ - **Previous version** (рекомендуется)
+ - **Number of days** (например, последние 30 дней)
+ - **Specific analysis** (конкретная дата)
+
+---
+
+**Сообщите мне, какую цифру Overall Coverage вы видите в SonarQube, и я помогу дальше!**