> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bedolagam.ru/llms.txt
> Use this file to discover all available pages before exploring further.

# Обслуживание и безопасность

> Бэкапы, техработы, бан-система, чёрный список, ротация логов

## Бэкапы

### Автоматические бэкапы

Бот автоматически создаёт резервные копии базы данных по расписанию.

```env theme={null}
BACKUP_AUTO_ENABLED=true
BACKUP_INTERVAL_HOURS=24
BACKUP_TIME=03:00
BACKUP_MAX_KEEP=7
```

При запуске бот рассчитывает следующее время бэкапа от `BACKUP_TIME`, далее повторяет каждые `BACKUP_INTERVAL_HOURS`.

### Содержимое бэкапа

Формат: `.tar.gz` (или `.tar` без сжатия). Архив содержит:

| Компонент                        | Описание                                    |
| -------------------------------- | ------------------------------------------- |
| `metadata.json`                  | Метаданные (время, тип БД, таблицы, записи) |
| `database.sql` / `database.json` | Дамп БД (`pg_dump` или ORM-дамп)            |
| `files/`                         | Конфигурационные файлы (`app-config.json`)  |
| `data/`                          | Снимок директории `data/`                   |

Покрывает **70+ таблиц** в порядке зависимостей foreign key.

### Ручные бэкапы

Из админ-панели: **"Бэкап-панель"** → **"Создать бэкап"**.

### Отправка в Telegram

```env theme={null}
BACKUP_SEND_ENABLED=true
BACKUP_SEND_CHAT_ID=-100123456789
BACKUP_SEND_TOPIC_ID=123
BACKUP_ARCHIVE_PASSWORD=          # AES-шифрование (опционально)
```

Если указан `BACKUP_ARCHIVE_PASSWORD`, бэкап оборачивается в AES-шифрованный ZIP.

### Восстановление

Два режима:

* **Восстановление (merge)** — данные добавляются/обновляются (upsert по PK)
* **Полная замена** — существующие данные удаляются, затем импорт

Поддерживается загрузка файла бэкапа (`.json`, `.json.gz`, `.tar.gz`) через Telegram (до 50 МБ).

После восстановления PostgreSQL последовательности автоматически синхронизируются (`sync_postgres_sequences()`).

### Настройки бэкапов

| Переменная                | По умолчанию        | Описание                 |
| ------------------------- | ------------------- | ------------------------ |
| `BACKUP_AUTO_ENABLED`     | `true`              | Автобэкапы               |
| `BACKUP_INTERVAL_HOURS`   | `24`                | Интервал (часы)          |
| `BACKUP_TIME`             | `03:00`             | Время первого бэкапа     |
| `BACKUP_MAX_KEEP`         | `7`                 | Максимум хранимых файлов |
| `BACKUP_COMPRESSION`      | `true`              | Сжатие gzip              |
| `BACKUP_INCLUDE_LOGS`     | `false`             | Включать MonitoringLog   |
| `BACKUP_LOCATION`         | `/app/data/backups` | Директория хранения      |
| `BACKUP_SEND_ENABLED`     | `true`              | Отправка в Telegram      |
| `BACKUP_SEND_CHAT_ID`     | —                   | ID чата для бэкапов      |
| `BACKUP_SEND_TOPIC_ID`    | —                   | ID топика                |
| `BACKUP_ARCHIVE_PASSWORD` | —                   | Пароль AES-шифрования    |

## Режим техработ

### Принцип работы

Глобальный `MaintenanceMiddleware` перехватывает все запросы:

* Если техработы активны — пользователь видит сообщение, запрос блокируется
* Администраторы обходят блокировку

### Ручное управление

Из админ-панели: включение с указанием причины (или без — `/skip`).

### Автоматический режим

Мониторинг API RemnaWave с автоматическим включением/выключением:

1. Фоновая задача проверяет доступность API каждые `MAINTENANCE_CHECK_INTERVAL` секунд
2. При каждой проверке пытается подключиться к RemnaWave (до `MAINTENANCE_RETRY_ATTEMPTS` попыток)
3. **API доступен**: сбрасывает счётчик ошибок. Если техработы были автовключены — автоотключает
4. **API недоступен**: увеличивает счётчик. После 3 последовательных сбоев — автовключает техработы

### Панель администратора

| Действие                        | Описание                                                |
| ------------------------------- | ------------------------------------------------------- |
| Включить/Выключить              | Ручное управление                                       |
| Запустить/Остановить мониторинг | Управление фоновой проверкой                            |
| Принудительная проверка         | Немедленная проверка API                                |
| Статус панели                   | Детальная информация (время ответа, ноды, пользователи) |
| Ручное уведомление              | Отправка уведомления с выбранным типом и текстом        |

### Настройка

| Переменная                       | По умолчанию                    | Описание                        |
| -------------------------------- | ------------------------------- | ------------------------------- |
| `MAINTENANCE_MODE`               | `false`                         | Начальное состояние при запуске |
| `MAINTENANCE_CHECK_INTERVAL`     | `30`                            | Интервал проверки API (секунды) |
| `MAINTENANCE_AUTO_ENABLE`        | `true`                          | Автовключение после 3 сбоев     |
| `MAINTENANCE_MONITORING_ENABLED` | `true`                          | Мониторинг при запуске бота     |
| `MAINTENANCE_RETRY_ATTEMPTS`     | `1`                             | Попытки на одну проверку        |
| `MAINTENANCE_MESSAGE`            | `Ведутся технические работы...` | Сообщение для пользователей     |

## Система бан-интеграции (BedolagaBan)

Интеграция с внешней системой мониторинга BedolagaBan для контроля злоупотреблений.

### Типы уведомлений

| Тип              | Описание                                   |
| ---------------- | ------------------------------------------ |
| `punishment`     | Блокировка за превышение лимита устройств  |
| `enabled`        | Разблокировка пользователя                 |
| `warning`        | Предупреждение                             |
| `network_wifi`   | Блокировка за использование WiFi           |
| `network_mobile` | Блокировка за использование мобильной сети |

Уведомления приходят через FastAPI endpoint `POST /ban-notifications/send` и пересылаются пользователю.

### Шаблоны сообщений

Все шаблоны настраиваются через переменные окружения с плейсхолдерами:

| Переменная           | Плейсхолдеры                                            |
| -------------------- | ------------------------------------------------------- |
| `BAN_MSG_PUNISHMENT` | `{ip_count}`, `{limit}`, `{ban_minutes}`, `{node_info}` |
| `BAN_MSG_ENABLED`    | — (статический текст)                                   |
| `BAN_MSG_WIFI`       | `{ban_minutes}`, `{network_info}`, `{node_info}`        |
| `BAN_MSG_MOBILE`     | `{ban_minutes}`, `{network_info}`, `{node_info}`        |
| `BAN_MSG_WARNING`    | `{warning_message}`                                     |

### Настройка

| Переменная                   | По умолчанию | Описание                   |
| ---------------------------- | ------------ | -------------------------- |
| `BAN_SYSTEM_ENABLED`         | `false`      | Включить интеграцию        |
| `BAN_SYSTEM_API_URL`         | —            | URL BedolagaBan API        |
| `BAN_SYSTEM_API_TOKEN`       | —            | Bearer-токен авторизации   |
| `BAN_SYSTEM_REQUEST_TIMEOUT` | `30`         | Таймаут запросов (секунды) |

## Чёрный список

Глобальный чёрный список Telegram ID, загружаемый из GitHub.

### Как работает

1. `BlacklistMiddleware` проверяет каждый запрос
2. Если пользователь в списке — показывается "Доступ запрещён" с причиной
3. Результаты кэшируются в памяти на 5 минут
4. Список автообновляется с GitHub каждые `BLACKLIST_UPDATE_INTERVAL_HOURS`

### Формат файла

```
# Комментарии начинаются с #
7021477105 #@username, причина блокировки
1234567890 @another_user, перепродажа подписок
```

### Настройка

| Переменная                        | По умолчанию            | Описание                     |
| --------------------------------- | ----------------------- | ---------------------------- |
| `BLACKLIST_CHECK_ENABLED`         | `false`                 | Включить проверку            |
| `BLACKLIST_GITHUB_URL`            | *(URL к blacklist.txt)* | URL файла на GitHub          |
| `BLACKLIST_UPDATE_INTERVAL_HOURS` | `24`                    | Интервал обновления          |
| `BLACKLIST_IGNORE_ADMINS`         | `true`                  | Игнорировать администраторов |

## Защита имён (Banwords)

`DisplayNameRestrictionMiddleware` блокирует пользователей с подозрительными именами:

| Проверка              | Описание                                          |
| --------------------- | ------------------------------------------------- |
| Символ `@`            | Блокировка имён с `@` или `＠`                     |
| Ссылки                | `t.me/+`, `joinchat`, `https://`, `www.`, `tg://` |
| Обфускация доменов    | Варианты вроде `t . m e`, кириллические подмены   |
| Нормализация символов | Кириллические а→a, е→e, о→o и т.д.                |
| Запрещённые слова     | Из `DISPLAY_NAME_BANNED_KEYWORDS`                 |

```env theme={null}
DISPLAY_NAME_BANNED_KEYWORDS=tme,joingroup,support,admin
```

## Очистка неактивных пользователей

Бот автоматически удаляет пользователей, которые не проявляли активность дольше `INACTIVE_USER_DELETE_MONTHS` месяцев.

При определении неактивности учитываются два фактора:

* **Дата последней активности** — последнее взаимодействие с ботом
* **Дата окончания подписки** (`end_date`) — пользователь с активной или недавно истёкшей подпиской не будет удалён, даже если давно не заходил в бота

| Переменная                    | По умолчанию | Описание                                  |
| ----------------------------- | ------------ | ----------------------------------------- |
| `INACTIVE_USER_DELETE_MONTHS` | `3`          | Период неактивности для удаления (месяцы) |

<Info>
  Пользователь считается неактивным только если и дата последней активности, и дата окончания подписки старше порога. Это предотвращает удаление пользователей с действующими подписками.
</Info>

## Сканер заблокированных пользователей

Массовая проверка пользователей, заблокировавших бота:

1. Отправляет тестовый запрос каждому пользователю
2. Определяет заблокировавших бот
3. Действия: удалить из БД, из RemnaWave, отметить как заблокированного

## Массовый бан

Массовая блокировка по списку Telegram ID:

* Ввод ID (по одному на строку, через запятую или пробел)
* Максимум 1000 ID за раз
* Каждому отправляется уведомление
* Результаты: заблокировано / ошибки

## Ротация логов

### Автоматическая ротация

```env theme={null}
LOG_ROTATION_ENABLED=true
LOG_ROTATION_TIME=00:00
LOG_ROTATION_KEEP_DAYS=7
LOG_ROTATION_COMPRESS=true
```

Ежедневно в указанное время:

1. Сброс всех обработчиков логов
2. Сбор непустых файлов: `info.log`, `warning.log`, `error.log`, `payments.log`, `bot.log`
3. Создание архива `logs_YYYY-MM-DD.tar.gz`
4. Очистка текущих файлов
5. Удаление старых архивов (> `LOG_ROTATION_KEEP_DAYS`)
6. Опционально — отправка в Telegram

### Отправка в Telegram

```env theme={null}
LOG_ROTATION_SEND_TO_TELEGRAM=true
LOG_ROTATION_CHAT_ID=          # Fallback на BACKUP_SEND_CHAT_ID
LOG_ROTATION_TOPIC_ID=         # Fallback на BACKUP_SEND_TOPIC_ID
```

### Просмотр логов (админ)

Из админ-панели:

* Последние 2300 символов лога в раскрывающемся блоке
* Кнопка обновления
* Скачивание полного файла как Telegram-документ

### Настройки логирования

| Переменная                      | По умолчанию   | Описание                 |
| ------------------------------- | -------------- | ------------------------ |
| `LOG_LEVEL`                     | `INFO`         | Уровень логирования      |
| `LOG_FILE`                      | `logs/bot.log` | Основной лог-файл        |
| `LOG_ROTATION_ENABLED`          | `false`        | Ротация логов            |
| `LOG_ROTATION_TIME`             | `00:00`        | Время ежедневной ротации |
| `LOG_ROTATION_KEEP_DAYS`        | `7`            | Хранить архивы (дни)     |
| `LOG_ROTATION_COMPRESS`         | `true`         | Сжатие gzip              |
| `LOG_ROTATION_SEND_TO_TELEGRAM` | `false`        | Отправка архивов         |
