diff --git a/app/handlers/admin/bot_configuration.py b/app/handlers/admin/bot_configuration.py index 245672a0..33019f87 100644 --- a/app/handlers/admin/bot_configuration.py +++ b/app/handlers/admin/bot_configuration.py @@ -20,38 +20,75 @@ SETTINGS_PAGE_SIZE = 8 CATEGORY_GROUP_DEFINITIONS: Tuple[Tuple[str, str, Tuple[str, ...]], ...] = ( ( - "core", - "⚙️ Основные настройки", + "telegram_bot", + "🤖 Telegram бот", + ("SUPPORT", "ADMIN_NOTIFICATIONS", "ADMIN_REPORTS", "CHANNEL"), + ), + ( + "database", + "🗄️ База данных", + ("DATABASE", "POSTGRES", "SQLITE", "REDIS"), + ), + ( + "remnawave", + "🌊 Remnawave API", + ("REMNAWAVE",), + ), + ( + "subscriptions", + "🪙 Подписки и тарифы", ( - "DEFAULT", - "ADMIN", - "SUPPORT", - "REMNAWAVE", - "VERSION", - "DEBUG", - "LOG", - "BACKUP", + "TRIAL", + "PAID_SUBSCRIPTION", + "SUBSCRIPTIONS_GLOBAL", + "TRAFFIC", + "PERIODS", + "SUBSCRIPTION_PRICES", + "TRAFFIC_PACKAGES", + "DISCOUNTS", + "REFERRAL", + "AUTOPAY", ), ), ( - "infrastructure", - "🗄️ Инфраструктура", - ("DATABASE", "POSTGRES", "SQLITE", "REDIS", "WEBHOOK", "SERVER", "MONITORING", "MAINTENANCE"), + "payments", + "💳 Платежные системы", + ("TELEGRAM", "TRIBUTE", "YOOKASSA", "CRYPTOBOT", "MULENPAY", "PAL24", "PAYMENT"), ), ( - "billing", - "💳 Оплаты и тарифы", - ("PRICE", "PAYMENT", "YOOKASSA", "CRYPTOBOT", "MULENPAY", "PAL24", "AUTOPAY", "TRIAL"), + "interface", + "🎨 Интерфейс и UX", + ("INTERFACE_BRANDING", "INTERFACE_SUBSCRIPTION", "CONNECT_BUTTON", "HAPP", "SKIP"), ), ( - "communication", - "📡 Подключение и коммуникации", - ("CONNECT", "CHANNEL", "TELEGRAM", "HAPP"), + "monitoring", + "📣 Мониторинг и уведомления", + ("MONITORING", "NOTIFICATIONS"), ), ( - "loyalty", - "🎁 Рефералы и лояльность", - ("REFERRAL", "TRIBUTE"), + "operations", + "🛠️ Статусы и обслуживание", + ("SERVER", "MAINTENANCE"), + ), + ( + "localization", + "🈯 Локализация", + ("LOCALIZATION",), + ), + ( + "extras", + "🧩 Дополнительные настройки", + ("ADDITIONAL",), + ), + ( + "reliability", + "💾 Бекапы и обновления", + ("BACKUP", "VERSION"), + ), + ( + "technical", + "🧰 Технические", + ("LOG", "WEBHOOK", "DEBUG"), ), ) diff --git a/app/services/system_settings_service.py b/app/services/system_settings_service.py index fa229bf1..b77d0745 100644 --- a/app/services/system_settings_service.py +++ b/app/services/system_settings_service.py @@ -58,37 +58,142 @@ class BotConfigurationService: EXCLUDED_KEYS: set[str] = {"BOT_TOKEN", "ADMIN_IDS"} CATEGORY_TITLES: Dict[str, str] = { + "SUPPORT": "Поддержка", + "ADMIN_NOTIFICATIONS": "Уведомления администраторов", + "ADMIN_REPORTS": "Автоотчеты", + "CHANNEL": "Обязательная подписка на канал", "DATABASE": "База данных", "POSTGRES": "PostgreSQL", "SQLITE": "SQLite", "REDIS": "Redis", - "REMNAWAVE": "Remnawave", - "SUPPORT": "Поддержка", - "ADMIN": "Администрирование", - "CHANNEL": "Каналы", - "TRIAL": "Триал", - "DEFAULT": "Значения по умолчанию", - "PRICE": "Цены", - "TRAFFIC": "Трафик", - "REFERRAL": "Реферальная программа", + "REMNAWAVE": "Remnawave API", + "TRIAL": "Триал подписка", + "PAID_SUBSCRIPTION": "Платная подписка", + "SUBSCRIPTIONS_GLOBAL": "Глобальные параметры подписок", + "TRAFFIC": "Настройки трафика", + "PERIODS": "Периоды подписки", + "SUBSCRIPTION_PRICES": "Цены подписки", + "TRAFFIC_PACKAGES": "Пакеты трафика", + "DISCOUNTS": "Скидки промогрупп", + "REFERRAL": "Реферальная система", "AUTOPAY": "Автопродление", - "MONITORING": "Мониторинг", - "SERVER": "Статус серверов", - "MAINTENANCE": "Техработы", - "PAYMENT": "Оплаты", + "TELEGRAM": "Telegram Stars", + "TRIBUTE": "Tribute", "YOOKASSA": "YooKassa", "CRYPTOBOT": "CryptoBot", "MULENPAY": "MulenPay", - "PAL24": "PayPalych", - "CONNECT": "Кнопка подключения", - "HAPP": "Happ", - "VERSION": "Версии", + "PAL24": "PayPalych / Pal24", + "PAYMENT": "Описания платежей", + "INTERFACE_BRANDING": "Брендинг и логотип", + "INTERFACE_SUBSCRIPTION": "Блок подписки", + "CONNECT_BUTTON": "Кнопка «Подключиться»", + "HAPP": "Happ CryptoLink", + "SKIP": "Пропуски onboarding", + "MONITORING": "Мониторинг", + "NOTIFICATIONS": "Уведомления", + "SERVER": "Статус серверов", + "MAINTENANCE": "Технические работы", + "LOCALIZATION": "Локализация", + "ADDITIONAL": "Дополнительные настройки", "BACKUP": "Бекапы", + "VERSION": "Проверка обновлений", + "LOG": "Логирование", "WEBHOOK": "Вебхуки", - "LOG": "Логи", - "DEBUG": "Отладка", - "TRIBUTE": "Tribute", - "TELEGRAM": "Telegram Stars", + "DEBUG": "Режим разработки", + } + + CATEGORY_KEY_OVERRIDES: Dict[str, str] = { + "DATABASE_URL": "DATABASE", + "DATABASE_MODE": "DATABASE", + "LOCALES_PATH": "DATABASE", + "DEFAULT_DEVICE_LIMIT": "PAID_SUBSCRIPTION", + "DEFAULT_TRAFFIC_LIMIT_GB": "PAID_SUBSCRIPTION", + "MAX_DEVICES_LIMIT": "PAID_SUBSCRIPTION", + "PRICE_PER_DEVICE": "PAID_SUBSCRIPTION", + "DEFAULT_TRAFFIC_RESET_STRATEGY": "SUBSCRIPTIONS_GLOBAL", + "TRAFFIC_SELECTION_MODE": "TRAFFIC", + "FIXED_TRAFFIC_LIMIT_GB": "TRAFFIC", + "AVAILABLE_SUBSCRIPTION_PERIODS": "PERIODS", + "AVAILABLE_RENEWAL_PERIODS": "PERIODS", + "BASE_SUBSCRIPTION_PRICE": "SUBSCRIPTION_PRICES", + "PRICE_14_DAYS": "SUBSCRIPTION_PRICES", + "PRICE_30_DAYS": "SUBSCRIPTION_PRICES", + "PRICE_60_DAYS": "SUBSCRIPTION_PRICES", + "PRICE_90_DAYS": "SUBSCRIPTION_PRICES", + "PRICE_180_DAYS": "SUBSCRIPTION_PRICES", + "PRICE_360_DAYS": "SUBSCRIPTION_PRICES", + "PRICE_TRAFFIC_5GB": "TRAFFIC_PACKAGES", + "PRICE_TRAFFIC_10GB": "TRAFFIC_PACKAGES", + "PRICE_TRAFFIC_25GB": "TRAFFIC_PACKAGES", + "PRICE_TRAFFIC_50GB": "TRAFFIC_PACKAGES", + "PRICE_TRAFFIC_100GB": "TRAFFIC_PACKAGES", + "PRICE_TRAFFIC_250GB": "TRAFFIC_PACKAGES", + "PRICE_TRAFFIC_500GB": "TRAFFIC_PACKAGES", + "PRICE_TRAFFIC_1000GB": "TRAFFIC_PACKAGES", + "PRICE_TRAFFIC_UNLIMITED": "TRAFFIC_PACKAGES", + "TRAFFIC_PACKAGES_CONFIG": "TRAFFIC_PACKAGES", + "BASE_PROMO_GROUP_PERIOD_DISCOUNTS_ENABLED": "DISCOUNTS", + "BASE_PROMO_GROUP_PERIOD_DISCOUNTS": "DISCOUNTS", + "REFERRED_USER_REWARD": "REFERRAL", + "DEFAULT_AUTOPAY_DAYS_BEFORE": "AUTOPAY", + "MIN_BALANCE_FOR_AUTOPAY_KOPEKS": "AUTOPAY", + "TRIAL_WARNING_HOURS": "NOTIFICATIONS", + "ENABLE_NOTIFICATIONS": "NOTIFICATIONS", + "NOTIFICATION_RETRY_ATTEMPTS": "NOTIFICATIONS", + "NOTIFICATION_CACHE_HOURS": "NOTIFICATIONS", + "MONITORING_LOGS_RETENTION_DAYS": "MONITORING", + "ENABLE_LOGO_MODE": "INTERFACE_BRANDING", + "LOGO_FILE": "INTERFACE_BRANDING", + "HIDE_SUBSCRIPTION_LINK": "INTERFACE_SUBSCRIPTION", + "CONNECT_BUTTON_MODE": "CONNECT_BUTTON", + "MINIAPP_CUSTOM_URL": "CONNECT_BUTTON", + "APP_CONFIG_PATH": "ADDITIONAL", + "ENABLE_DEEP_LINKS": "ADDITIONAL", + "APP_CONFIG_CACHE_TTL": "ADDITIONAL", + "DEFAULT_LANGUAGE": "LOCALIZATION", + "AVAILABLE_LANGUAGES": "LOCALIZATION", + "PAYMENT_SERVICE_NAME": "PAYMENT", + "PAYMENT_BALANCE_DESCRIPTION": "PAYMENT", + "PAYMENT_SUBSCRIPTION_DESCRIPTION": "PAYMENT", + "PAYMENT_BALANCE_TEMPLATE": "PAYMENT", + "PAYMENT_SUBSCRIPTION_TEMPLATE": "PAYMENT", + "INACTIVE_USER_DELETE_MONTHS": "MONITORING", + } + + CATEGORY_PREFIX_OVERRIDES: Dict[str, str] = { + "SUPPORT_": "SUPPORT", + "ADMIN_NOTIFICATIONS": "ADMIN_NOTIFICATIONS", + "ADMIN_REPORTS": "ADMIN_REPORTS", + "CHANNEL_": "CHANNEL", + "POSTGRES_": "POSTGRES", + "SQLITE_": "SQLITE", + "REDIS_": "REDIS", + "REMNAWAVE": "REMNAWAVE", + "TRIAL_": "TRIAL", + "TRAFFIC_PACKAGES": "TRAFFIC_PACKAGES", + "PRICE_TRAFFIC": "TRAFFIC_PACKAGES", + "TRAFFIC_": "TRAFFIC", + "REFERRAL_": "REFERRAL", + "AUTOPAY_": "AUTOPAY", + "TELEGRAM_STARS": "TELEGRAM", + "TRIBUTE_": "TRIBUTE", + "YOOKASSA_": "YOOKASSA", + "CRYPTOBOT_": "CRYPTOBOT", + "MULENPAY_": "MULENPAY", + "PAL24_": "PAL24", + "PAYMENT_": "PAYMENT", + "CONNECT_BUTTON_HAPP": "HAPP", + "HAPP_": "HAPP", + "SKIP_": "SKIP", + "MONITORING_": "MONITORING", + "NOTIFICATION_": "NOTIFICATIONS", + "SERVER_STATUS": "SERVER", + "MAINTENANCE_": "MAINTENANCE", + "VERSION_CHECK": "VERSION", + "BACKUP_": "BACKUP", + "WEBHOOK_": "WEBHOOK", + "LOG_": "LOG", + "DEBUG": "DEBUG", } CHOICES: Dict[str, List[ChoiceOption]] = { @@ -221,6 +326,16 @@ class BotConfigurationService: @classmethod def _resolve_category_key(cls, key: str) -> str: + override = cls.CATEGORY_KEY_OVERRIDES.get(key) + if override: + return override + + for prefix, category in sorted( + cls.CATEGORY_PREFIX_OVERRIDES.items(), key=lambda item: len(item[0]), reverse=True + ): + if key.startswith(prefix): + return category + if "_" not in key: return key.upper() prefix = key.split("_", 1)[0]