🎉 Release v2.5.7
📋 Краткое описание
Крупное обновление с улучшениями инфраструктуры, безопасности и UX. Добавлена централизованная работа с часовыми поясами, улучшена админская панель для управления рефералами и тикетами, расширены возможности настройки подписок и повышена надёжность синхронизации с панелью Remnawave.
✨ Основные нововведения
🌍 Централизованная поддержка часовых поясов
- Новый модуль
app/utils/timezone.pyс утилитами для работы с временными зонами:get_local_timezone()— кешируемая загрузка ZoneInfo с откатом на UTCto_local_datetime(dt)— конвертация datetime в локальную TZformat_local_datetime(dt, fmt, na_placeholder)— единообразное форматирование датTimezoneAwareFormatter— форматтер логов с учётом часового пояса
- Настройка
TIMEZONEв конфигурации (переменная окруженияTZили значение по умолчанию "UTC") - Валидация временных зон через Pydantic с понятными сообщениями об ошибках
- Логи теперь отображают время в настроенном часовом поясе
🤝 Управление рефералами в админке
- Новая кнопка "🤝 Рефералы" в интерфейсе управления пользователем
- Просмотр списка рефералов пользователя с детальной информацией
- Массовое редактирование рефералов (добавление/удаление)
- Улучшенная логика начисления реферальных комиссий:
- Комиссия может начисляться даже при пополнениях ниже порога первого бонуса
- Централизованная обработка комиссий без дублирования кода
- Унифицированное отображение имени пользователя в админ-уведомлениях
🔧 Гибкая настройка устройств
- Режим фиксированного количества устройств: возможность отключить выбор количества устройств в UI
- Новые настройки:
DEVICES_SELECTION_ENABLED— включение/отключение выбора устройствDEVICES_SELECTION_DISABLED_AMOUNT— фиксированное количество при отключённом выборе
- Корректная обработка
device_limit = Noneво всех потоках покупки/продления - Условное отображение информации об устройствах в зависимости от настроек
🎫 Улучшения безопасности в тикетах
- HTML-экранирование username для предотвращения XSS
- Корректная генерация ссылок на ЛС и профиль пользователя
- Отображение Telegram ID в обновлённых карточках тикетов
- Безопасная обработка отсутствующих username с fallback на ссылки по ID
🔄 Надёжная синхронизация с панелью Remnawave
- Дедупликация пользователей по Telegram ID с выбором наиболее актуальной записи
- Приоритизация записей по дате окончания подписки и статусу (ACTIVE/TRIAL)
- Безопасная обработка пустых/невалидных дат
expireAt - Улучшенная обработка конфликтов уникальности при создании пользователей
- Метод
_get_or_create_bot_user_from_panelс корректной обработкойIntegrityError
🔄 Изменения и улучшения
⚙️ System Settings и переменные окружения
- Поддержка ENV-overrides: настройки из окружения имеют приоритет над значениями в БД
ENV_OVERRIDE_KEYS— автоматическое определение переопределённых настроек- Логирование попыток изменения настроек, заблокированных через окружение
- Новые категории настроек: TIMEZONE, DATABASE, POSTGRES, SQLITE, REDIS, REMNAWAVE
🎨 Улучшения интерфейса
- Единообразное форматирование дат/времени во всех хендлерах и сервисах
- Улучшенное отображение статуса подписки с поддержкой состояний
disabled,pending,expired - Централизованная функция
_calculate_subscription_flagsдля определения активности подписки - Условное скрытие элементов управления устройствами при отключённом выборе
💰 Расчёт цен и платежи
- Новая утилита
format_period_option_labelдля корректного отображения опций периода - Скрытие нулевых цен в списке опций при динамическом расчёте
- Корректная обработка
device_limit = Noneво всех расчётах стоимости - Улучшенная логика fallback для DEFAULT_DEVICE_LIMIT
🔍 Поиск пользователей
- Поддержка поиска по внутреннему ID (User.id) в дополнение к telegram_id
- Поиск по числовому запросу возвращает результаты по обоим полям (OR-условие)
- Улучшенное администрирование при дебаге и массовых операциях
📊 Web API
PromoGroupResponse: добавленmodel_configсfrom_attributes=True- Поля
created_atиupdated_atсделаны опциональными response_model_exclude_none=Trueдля чистых JSON-ответов без null-полей- Корректная обработка отсутствующих атрибутов через
getattr
🛠️ Техническое обслуживание
- Новые настройки мониторинга режима техработ:
MAINTENANCE_MONITORING_ENABLED— автозапуск мониторинга при стартеMAINTENANCE_RETRY_ATTEMPTS— количество повторных попыток проверки панели
- Повторные попытки при проверке health/panel с логированием номера попытки
- Отображение
attempts_usedв интерфейсе админов
👤 Шаблоны пользователей Remnawave
- Настройка
REMNAWAVE_USER_USERNAME_TEMPLATEдля гибкой генерации username - Поддержка плейсхолдеров:
{full_name},{username},{username_clean},{telegram_id} - Автоматическая очистка запрещённых символов и ограничение длины до 64 символов
- Метод
settings.format_remnawave_username()для безопасного форматирования
🐛 Исправления
🔐 Безопасность
- Устранена возможность XSS через username в карточках тикетов
- Корректное экранирование всех пользовательских данных в HTML-сообщениях
- Безопасная обработка отсутствующих полей при формировании уведомлений
🔄 Синхронизация
- Исправлена обработка дубликатов пользователей при синхронизации с панелью
- Корректный откат транзакции при IntegrityError
- Безопасный парсинг дат с обработкой None и пустых строк
- Устранены рассинхроны при отправке
hwid_device_limitв Remnawave
💸 Реферальная система
- Удалён устаревший параметр
REFERRED_USER_REWARDиз API и настроек - Исправлена логика начисления комиссий при пополнениях
- Убрано дублирование кода расчёта комиссий
- Корректная обработка пользователей без first_name/username
📱 Подписки и устройства
- Исправлено некорректное поведение при
subscription.device_limit == None - Корректная обработка expired подписок с форматированием даты истечения
- Улучшена обработка неизвестных статусов подписки
- Безопасное применение fallback-значений для device_limit
🗑️ Удаление данных
- Добавлена безопасная очистка Heleket платежей при удалении пользователя
- Корректная обработка связанных записей с
transaction_id
🔧 Технические изменения
📦 Новые модули и утилиты
app/utils/timezone.py— централизованная работа с часовыми поясамиapp/utils/subscription_utils.py— helper-функции для device_limit:resolve_hwid_device_limit()resolve_hwid_device_limit_for_payload()resolve_simple_subscription_device_limit()
app/handlers/subscription/summary.py— вынесенный рендеринг сводки заказа
🗂️ Рефакторинг
- Централизованное использование
format_local_datetimeвместо.strftime() - Единая логика определения активности подписки через
_calculate_subscription_flags - Упорядоченное формирование payload для Remnawave через словари kwargs
- Многолинейные импорты для улучшения читаемости (PEP8)
🆕 CRUD-операции
get_user_by_usernameс нормализацией (lowercase) и case-insensitive поискомupdate_user_referralsдля массового управления рефералами- Улучшенная загрузка связей через
selectinload
🌐 Локализация
- Новые ключи для управления рефералами (RU/EN)
- Ключи для состояний подписки:
SUB_STATUS_DISABLED,SUB_STATUS_PENDING - Сообщения об отключённом выборе устройств:
DEVICES_SELECTION_DISABLED - Улучшенные шаблоны для условного отображения информации об устройствах
⚙️ Конфигурация
🆕 Новые переменные окружения
# Часовой пояс
TZ=Europe/Moscow # или UTC, America/New_York и т.д.
# Управление устройствами
DEVICES_SELECTION_ENABLED=true
DEVICES_SELECTION_DISABLED_AMOUNT=0
# Мониторинг техработ
MAINTENANCE_MONITORING_ENABLED=false
MAINTENANCE_RETRY_ATTEMPTS=10
# Автопроверка платежей
PAYMENT_VERIFICATION_AUTO_CHECK_ENABLED=false
PAYMENT_VERIFICATION_AUTO_CHECK_INTERVAL_MINUTES=10
# Шаблоны пользователей Remnawave
REMNAWAVE_USER_USERNAME_TEMPLATE=user_{telegram_id}
REMNAWAVE_USER_DESCRIPTION_TEMPLATE={full_name}📝 Обновлённые настройки
TIMEZONE— теперь валидируется через zoneinfoREFERRAL_COMMISSION_PERCENT— используется в новой логике комиссийDEFAULT_DEVICE_LIMIT— fallback для различных сценариев- Новые категории в system settings UI
🚀 Миграция и развёртывание
✅ Чеклист перед обновлением
-
Создайте бэкап базы данных (включая таблицу
system_settings) -
Обновите
.envфайл:# Добавьте новые переменные из секции "Конфигурация" # Проверьте корректность существующих настроек
-
Настройте часовой пояс (если требуется отображение локального времени):
TZ=Europe/Moscow # Замените на ваш часовой пояс -
Проверьте настройки устройств:
- Если хотите оставить возможность выбора —
DEVICES_SELECTION_ENABLED=true - Для фиксированного количества —
DEVICES_SELECTION_ENABLED=false+ установитеDEVICES_SELECTION_DISABLED_AMOUNT
- Если хотите оставить возможность выбора —
⚠️ Важные изменения в поведении
- Часовые пояса: Логи и уведомления теперь показывают время в настроенной TZ (по умолчанию UTC)
- ENV-overrides: Настройки из окружения блокируют изменения через админку
- Device limits: При
DEVICES_SELECTION_ENABLED=falseUI не показывает управление устройствами - Реферальные комиссии: Теперь могут начисляться при любых пополнениях (если
REFERRAL_COMMISSION_PERCENT > 0)
🧪 Рекомендуемое тестирование
На staging:
- Отображение времени в админских уведомлениях и пользовательских сообщениях
- Поведение system settings при наличии env-overrides
- Создание/редактирование рефералов через админку
- Покупка подписки с различными настройками устройств
- Синхронизация пользователей с панелью Remnawave
- Просмотр и обработка тикетов (проверка экранирования username)
Интеграционные тесты:
- Форматирование дат (включая None)
- Валидация TIMEZONE
- System settings CRUD при env-overrides
- Расчёт цен при различных device_limit (включая None)
- Реферальные начисления
💡 Рекомендации
Для администраторов
- Используйте переменную
TZдля установки часового пояса приложения - ENV-переменные имеют приоритет над настройками в БД — используйте это для критичных параметров
- При отключении выбора устройств установите
DEVICES_SELECTION_DISABLED_AMOUNT > 0для передачи лимита в Remnawave - Новая кнопка "🤝 Рефералы" позволяет быстро управлять реферальной структурой
Для разработчиков
- Используйте
format_local_datetime()вместо.strftime()для единообразия - Проверяйте
device_limitна None перед использованием - Применяйте
html.escape()для всех пользовательских данных в HTML-сообщениях - Используйте новые утилиты из
subscription_utils.pyдля работы с device_limit
Для DevOps
- Проверьте логи на наличие warning'ов о env-overrides
- Убедитесь, что часовой пояс корректно установлен в systemd/docker
- При использовании custom logging config учитывайте
TimezoneAwareFormatter - Настройте мониторинг для новых параметров техобслуживания
Полный список изменений: v2.5.6...v2.5.7