docs: update docs

This commit is contained in:
3252a8
2026-05-11 06:34:45 +03:00
parent 5a015fe8b4
commit 5243cc4284
7 changed files with 104 additions and 12 deletions
+53
View File
@@ -0,0 +1,53 @@
# Админ-панель Web App
Админ-панель доступна пользователям, чей Telegram ID указан в `ADMIN_IDS`. В Web App такие пользователи видят раздел администрирования; все API `/api/admin/*` дополнительно проверяют сессию и `ADMIN_IDS` на сервере.
## Возможности
- дашборд со статистикой пользователей, платежей и синхронизации с Remnawave;
- список пользователей, карточка активной подписки, обычный и premium-трафик, платежи и действия;
- блокировка пользователей, рассылки, промокоды и просмотр логов;
- ручная синхронизация с Remnawave;
- редактор разрешенных настроек приложения из manifest-файла;
- редактор JSON-каталога тарифов;
- загрузка Internal Squads из Remnawave для выбора в тарифах.
## Настройки
Раздел **Система -> Настройки** позволяет менять приложение без редактирования `.env`, но только в пределах allowlist из `bot/app/web/admin_settings_manifest.py`. Даже администратор не может менять через UI произвольные атрибуты `Settings`.
Изменения сохраняются как overrides в базе данных и применяются поверх `.env` без перезапуска. Если значение сброшено, снова используется значение из `.env`. После сохранения публичный кеш настроек Web App сбрасывается, поэтому пользователи видят изменения при следующих запросах.
В manifest сейчас входят:
- общие параметры: язык, валюта, ссылки поддержки, документы, обязательный канал и поведение `/start`;
- внешний вид и доступность Web App: название, цвет, логотип, emoji-логотип и `WEBAPP_ENABLED`;
- legacy-цены без JSON-каталога: периоды подписки, RUB/Stars цены и пакеты трафика;
- платежные провайдеры: включение методов, порядок кнопок, публичные параметры и секреты YooKassa, FreeKassa, Platega, SeverPay, CryptoPay и Stars;
- пробный период, реферальные бонусы, уведомления, логирование, раздел устройств, лимит устройств и legacy-лимиты трафика.
Секретные поля помечены как secret и не должны использоваться для произвольного просмотра старых значений. Настройки, которых нет в manifest, остаются только в `.env` или коде.
## Тарифы
Раздел **Система -> Тарифы** работает с файлом `TARIFFS_CONFIG_PATH` (по умолчанию `config/tariffs.json`). При сохранении backend валидирует payload через `TariffsConfig`, пишет JSON в UTF-8 и сбрасывает кеш публичных данных Web App.
Если файла еще нет, админка открывает пустой каталог. Перед сохранением должен быть хотя бы один включенный тариф, а `default_tariff` должен ссылаться на включенный тариф.
Редактор тарифа разделен на вкладки:
- **Основное**: ключ, модель `period`/`traffic`, видимость, названия и описания RU/EN, базовые Internal Squads, HWID-лимит, месячный лимит или курс конвертации;
- **Цены**: периоды и цены для `period`, пакеты GB и цены для `traffic`;
- **Докупки**: обычные пакеты докупки трафика для `period`; для `traffic` отдельные докупки не нужны, пользователь повторно покупает пакеты из `traffic_packages`;
- **Premium**: названия premium-раздела RU/EN, premium Internal Squads, месячный premium-лимит и RUB/Stars пакеты premium-докупки;
- **Устройства**: RUB/Stars пакеты докупки HWID-устройств.
Базовые и premium Internal Squads выбираются из Remnawave через `/api/admin/panel/internal-squads`. Если панель недоступна, можно сохранить уже существующие UUID в JSON, но выпадающий список не загрузится.
## Практические замечания
Не меняйте `key` опубликованного тарифа без миграции активных подписок: подписки, платежи и смена тарифа ссылаются на этот ключ.
Отключенный тариф исчезает с витрины, но активные подписки с его `tariff_key` продолжают существовать. Удаление тарифа безопасно только если не осталось активных подписок, которым нужна докупка, продление или смена с этого тарифа.
Для Docker важно, чтобы путь `TARIFFS_CONFIG_PATH` был доступен на запись контейнеру. В dev-compose каталог `./config` монтируется в `/app/config`, поэтому админка может сохранять `config/tariffs.json`.
+2
View File
@@ -87,6 +87,8 @@ docker compose -f docker-compose-dev.yml up -d --build --force-recreate
Переопределения из веб-админки сохраняются в БД и применяются поверх `.env` без перезапуска. Для платежных методов кнопка отображается только если соответствующий `*_ENABLED=true` и сервис настроен.
Редактор тарифов в админке сохраняет не override в БД, а сам JSON-файл `TARIFFS_CONFIG_PATH`. Редактор настроек админки, наоборот, работает через allowlist из `bot/app/web/admin_settings_manifest.py` и сохраняет overrides в БД. Через него можно менять только заявленные в manifest параметры приложения; остальные параметры остаются в `.env`. Подробнее: [admin.md](admin.md).
## Web App и email-вход
| Переменная | Назначение |
+21 -4
View File
@@ -7,6 +7,12 @@
JSON-каталог может содержать несколько тарифов разных моделей: подписки на срок, пакеты трафика без срока действия, разные наборы Internal Squads, лимиты устройств и пакеты докупки. Пример формата: [config/tariffs.example.json](../config/tariffs.example.json).
Коротко по моделям:
- `period` - подписка на срок с месячным лимитом трафика и опциональной докупкой GB поверх месячного лимита;
- `traffic` - покупка пакетов GB без пользовательского срока действия, где повторная покупка добавляет трафик к текущему остатку;
- premium-сквады - дополнительный набор Internal Squads внутри любого тарифа, с отдельным названием, счетчиком, месячным лимитом и отдельными пакетами докупки.
## Управление через админку
Каталог тарифов можно настраивать из Web App админки: раздел **Система → Тарифы**. Админка читает и сохраняет файл из `TARIFFS_CONFIG_PATH`, валидирует данные той же моделью `TariffsConfig`, что и бот, и атомарно перезаписывает JSON только после успешной проверки.
@@ -18,10 +24,14 @@ JSON-каталог может содержать несколько тариф
- выбор тарифа по умолчанию;
- настройка `period`-тарифов: месячный лимит, периоды, RUB/Stars цены, пакеты докупки трафика;
- настройка `traffic`-тарифов: пакеты GB, RUB/Stars цены, курс конвертации;
- настройка Internal Squads, базового HWID-лимита и пакетов докупки устройств.
- настройка базовых Internal Squads из списка Remnawave;
- настройка premium-раздела: названия RU/EN, premium Internal Squads, месячный premium-лимит и RUB/Stars пакеты докупки premium-трафика;
- настройка базового HWID-лимита и пакетов докупки устройств.
После сохранения изменения применяются к новым запросам Web App сразу, потому что конфиг тарифов загружается из JSON при обращении. Уже созданные подписки сохраняют свой `tariff_key`; при удалении или отключении тарифа проверьте, что активные подписки с этим ключом не требуют дальнейшего продления или смены.
Подробности по админ-панели, правам доступа, сохранению настроек и списку разделов есть в [admin.md](admin.md).
## Как выбирается режим
Если файл из `TARIFFS_CONFIG_PATH` существует и проходит валидацию, используется каталог тарифов. В этом режиме `TRAFFIC_PACKAGES` и цены подписок из `.env` не формируют витрину продаж, потому что цены и пакеты берутся из JSON.
@@ -46,6 +56,7 @@ JSON-каталог может содержать несколько тариф
"key": "standard",
"names": { "ru": "Стандарт", "en": "Standard" },
"descriptions": { "ru": "Базовый набор серверов" },
"premium_names": { "ru": "Premium-серверы", "en": "Premium servers" },
"squad_uuids": ["uuid-1"],
"billing_model": "period",
"monthly_gb": 500,
@@ -71,9 +82,10 @@ JSON-каталог может содержать несколько тариф
| `tariffs[].descriptions` | Описания тарифа по языкам. |
| `tariffs[].enabled` | Доступность тарифа на витрине. |
| `tariffs[].squad_uuids` | Internal Squads Remnawave для пользователей тарифа. |
| `tariffs[].premium_names` | Название premium-раздела по языкам. Используется в карточке лимита, модалке докупки premium-трафика и предупреждениях. Если поле не задано, используется `Premium-серверы` / `Premium servers`. |
| `tariffs[].premium_squad_uuids` | Internal Squads с отдельным premium-лимитом. Ноды для учета берутся автоматически из accessible nodes этих сквадов через API панели. |
| `tariffs[].premium_monthly_gb` | Отдельный месячный лимит трафика по premium-сквадам. `0` или отсутствие поля отключает отдельное ограничение. |
| `tariffs[].premium_topup_packages` | Пакеты докупки premium-трафика: `{ "gb": 10, "price": 99 }`. |
| `tariffs[].premium_topup_packages` | Пакеты докупки premium-трафика в формате `{ "rub": [{ "gb": 10, "price": 99 }], "stars": [...] }`. Требуют `premium_squad_uuids`. |
| `tariffs[].billing_model` | Модель тарифа: `period` или `traffic`. |
| `tariffs[].hwid_device_limit` | Базовый лимит HWID-устройств. `0` означает безлимит, отсутствие поля использует `USER_HWID_DEVICE_LIMIT`. |
| `tariffs[].hwid_device_packages` | Пакеты докупки устройств: `{ "count": 1, "price": 99 }`. |
@@ -124,6 +136,7 @@ JSON-каталог может содержать несколько тариф
```json
{
"squad_uuids": ["standard-squad-uuid"],
"premium_names": { "ru": "Premium-серверы", "en": "Premium servers" },
"premium_squad_uuids": ["premium-squad-uuid"],
"premium_monthly_gb": 50,
"premium_topup_packages": {
@@ -144,6 +157,8 @@ JSON-каталог может содержать несколько тариф
- докупленный premium-трафик не сгорает в конце месяца: каждый месяц сначала расходуется `premium_monthly_gb`, а докупленный остаток уменьшается только на трафик сверх месячного лимита;
- при новом календарном месяце счетчик premium-трафика и `premium_topup_used_bytes` сбрасываются, но `premium_topup_balance_bytes` переносится дальше.
Если `premium_squad_uuids` заданы, но `premium_monthly_gb` пустой или `0` и нет `premium_topup_packages`, premium-сквады работают как дополнительный доступ без отдельного ограничения. Если заданы `premium_topup_packages` или положительный `premium_monthly_gb`, `premium_squad_uuids` обязательны.
Состояние хранится в подписке:
- `premium_baseline_bytes` - базовый premium-лимит тарифа;
@@ -155,9 +170,11 @@ JSON-каталог может содержать несколько тариф
В пользовательском Web App premium-лимит показывается отдельной карточкой: использовано, лимит, остаток, докупленный переносимый остаток и список серверов/сквадов, на которые действует отдельное ограничение. В Telegram-разделе “Моя подписка” выводится тот же блок.
Предупреждения по premium-лимиту отправляются отдельно от обычного трафика на тех же процентах `TARIFF_TRAFFIC_WARNING_LEVELS`. Сообщение объясняет, что это именно premium-серверы, перечисляет серверы/сквады и ведет пользователя в докупку premium-трафика.
Обычная докупка и premium-докупка показываются отдельно. Обычная докупка использует `topup_packages` у `period`-тарифа или `traffic_packages` у `traffic`-тарифа. Premium-докупка использует только `premium_topup_packages`, получает `sale_mode=premium_topup` и в заголовке показывает `premium_names`, а не название обычной докупки.
В Web App админке premium-сквады можно выбрать из выпадающего списка. Список берется из API Remnawave, поэтому UUID не нужно копировать вручную.
Предупреждения по premium-лимиту отправляются отдельно от обычного трафика на тех же процентах `TARIFF_TRAFFIC_WARNING_LEVELS`. Сообщение использует название из `premium_names`, перечисляет серверы/сквады и ведет пользователя в докупку premium-трафика.
В Web App админке premium-сквады можно выбрать из выпадающего списка на вкладке **Premium** в редакторе тарифа. Список берется из API Remnawave (`/api/admin/panel/internal-squads`), поэтому UUID обычно не нужно копировать вручную.
## Traffic-тарифы
+4 -1
View File
@@ -7,12 +7,15 @@ Web App запускается в том же контейнере, что и б
- текущую ссылку подключения;
- статус и дату окончания подписки;
- использованный и доступный трафик;
- отдельную карточку premium-трафика, если у активного тарифа настроены premium-сквады и premium-лимит;
- доступные тарифы, способы оплаты и платежный статус;
- смену тарифа и докупку трафика при настроенном каталоге тарифов;
- смену тарифа, обычную докупку трафика и докупку premium-трафика при настроенном каталоге тарифов;
- раздел "Мои устройства" при `MY_DEVICES_SECTION_ENABLED=True`;
- реферальную ссылку и статистику приглашений;
- привязку email и Telegram к одному аккаунту.
Для администраторов из `ADMIN_IDS` Web App также показывает админ-панель: статистику, пользователей, рассылки, промокоды, логи, настройки и редактор тарифов. Подробности: [admin.md](admin.md).
## Настройки `.env`
```env