feat: premium squads inside one tariff
This commit is contained in:
@@ -79,6 +79,14 @@ nano .env
|
||||
|
||||
Если файл из `TARIFFS_CONFIG_PATH` существует, бот использует каталог тарифов. Если файла нет, применяется конфигурация из переменных `.env`.
|
||||
|
||||
В `docker-compose-dev.yml` каталог `./config` монтируется в контейнер как `/app/config`, чтобы Web App админка могла сохранять `config/tariffs.json`. После изменения compose-файла пересоздайте контейнер:
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose-dev.yml up -d --build --force-recreate
|
||||
```
|
||||
|
||||
Переопределения из веб-админки сохраняются в БД и применяются поверх `.env` без перезапуска. Для платежных методов кнопка отображается только если соответствующий `*_ENABLED=true` и сервис настроен.
|
||||
|
||||
## Web App и email-вход
|
||||
|
||||
| Переменная | Назначение |
|
||||
|
||||
+51
-7
@@ -41,10 +41,6 @@ JSON-каталог может содержать несколько тариф
|
||||
```json
|
||||
{
|
||||
"default_tariff": "standard",
|
||||
"topup_packages_default": {
|
||||
"rub": [{ "gb": 10, "price": 99 }],
|
||||
"stars": [{ "gb": 10, "price": 2500 }]
|
||||
},
|
||||
"tariffs": [
|
||||
{
|
||||
"key": "standard",
|
||||
@@ -55,6 +51,10 @@ JSON-каталог может содержать несколько тариф
|
||||
"monthly_gb": 500,
|
||||
"prices_rub": { "1": 150, "3": 400 },
|
||||
"enabled_periods": [1, 3],
|
||||
"topup_packages": {
|
||||
"rub": [{ "gb": 10, "price": 99 }],
|
||||
"stars": [{ "gb": 10, "price": 2500 }]
|
||||
},
|
||||
"enabled": true
|
||||
}
|
||||
]
|
||||
@@ -66,12 +66,14 @@ JSON-каталог может содержать несколько тариф
|
||||
| Поле | Назначение |
|
||||
| --- | --- |
|
||||
| `default_tariff` | Тариф по умолчанию для первичного выбора и привязки активных подписок без `tariff_key`. |
|
||||
| `topup_packages_default` | Пакеты докупки трафика для period-тарифов, у которых не задан `topup_packages`. |
|
||||
| `tariffs[].key` | Стабильный ключ тарифа. Используется в платежах, подписках и смене тарифа. |
|
||||
| `tariffs[].names` | Названия тарифа по языкам. |
|
||||
| `tariffs[].descriptions` | Описания тарифа по языкам. |
|
||||
| `tariffs[].enabled` | Доступность тарифа на витрине. |
|
||||
| `tariffs[].squad_uuids` | Internal Squads Remnawave для пользователей тарифа. |
|
||||
| `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[].billing_model` | Модель тарифа: `period` или `traffic`. |
|
||||
| `tariffs[].hwid_device_limit` | Базовый лимит HWID-устройств. `0` означает безлимит, отсутствие поля использует `USER_HWID_DEVICE_LIMIT`. |
|
||||
| `tariffs[].hwid_device_packages` | Пакеты докупки устройств: `{ "count": 1, "price": 99 }`. |
|
||||
@@ -84,7 +86,7 @@ JSON-каталог может содержать несколько тариф
|
||||
| `prices_rub` | Цены периодов в рублях, ключ - количество месяцев. |
|
||||
| `prices_stars` | Цены периодов в Telegram Stars. |
|
||||
| `enabled_periods` | Периоды, доступные для покупки. |
|
||||
| `topup_packages` | Пакеты докупки трафика именно для этого тарифа. |
|
||||
| `topup_packages` | Пакеты докупки трафика именно для этого тарифа. Если поле не задано или списки пустые, докупка для тарифа не показывается в Web App и Telegram-боте. |
|
||||
|
||||
Для `traffic`-тарифа используются:
|
||||
|
||||
@@ -115,6 +117,48 @@ JSON-каталог может содержать несколько тариф
|
||||
|
||||
Докупка трафика для period-тарифа увеличивает `topup_balance_bytes` и общий `traffic_limit_bytes`. Этот баланс сохраняется в подписке и учитывается при продлении period-тарифа. В панель отправляется актуальный лимит, а доступ переводится в `ACTIVE`.
|
||||
|
||||
## Premium-сквады и отдельный лимит
|
||||
|
||||
Тариф может включать дополнительный набор Internal Squads с отдельным лимитом трафика. Это удобно для сценария “обычные серверы без изменений, premium-серверы ограничены отдельно”.
|
||||
|
||||
```json
|
||||
{
|
||||
"squad_uuids": ["standard-squad-uuid"],
|
||||
"premium_squad_uuids": ["premium-squad-uuid"],
|
||||
"premium_monthly_gb": 50,
|
||||
"premium_topup_packages": {
|
||||
"rub": [{ "gb": 10, "price": 99 }],
|
||||
"stars": [{ "gb": 10, "price": 2500 }]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Правила:
|
||||
|
||||
- обычный лимит тарифа продолжает работать через `trafficLimitBytes` Remnawave;
|
||||
- premium-трафик считается отдельно по нодам, доступным из `premium_squad_uuids`;
|
||||
- список UUID нод не хранится в тарифе: бот запрашивает accessible nodes каждого premium-сквада у Remnawave и кеширует результат;
|
||||
- пока premium-лимит не исчерпан, пользователь получает `squad_uuids + premium_squad_uuids`;
|
||||
- при исчерпании premium-лимита бот убирает только premium-сквады, обычный доступ остается;
|
||||
- после докупки premium-трафика бот возвращает premium-сквады, если новый лимит снова больше использованного premium-трафика.
|
||||
- докупленный premium-трафик не сгорает в конце месяца: каждый месяц сначала расходуется `premium_monthly_gb`, а докупленный остаток уменьшается только на трафик сверх месячного лимита;
|
||||
- при новом календарном месяце счетчик premium-трафика и `premium_topup_used_bytes` сбрасываются, но `premium_topup_balance_bytes` переносится дальше.
|
||||
|
||||
Состояние хранится в подписке:
|
||||
|
||||
- `premium_baseline_bytes` - базовый premium-лимит тарифа;
|
||||
- `premium_topup_balance_bytes` - оставшийся докупленный premium-трафик;
|
||||
- `premium_topup_used_bytes` - часть докупленного premium-трафика, уже потраченная в текущем месяце;
|
||||
- `premium_used_bytes` - использованный premium-трафик за текущий календарный месяц;
|
||||
- `premium_period_start_at` - месяц, к которому относится `premium_used_bytes`;
|
||||
- `premium_is_limited` - признак, что premium-сквад временно снят.
|
||||
|
||||
В пользовательском Web App premium-лимит показывается отдельной карточкой: использовано, лимит, остаток, докупленный переносимый остаток и список серверов/сквадов, на которые действует отдельное ограничение. В Telegram-разделе “Моя подписка” выводится тот же блок.
|
||||
|
||||
Предупреждения по premium-лимиту отправляются отдельно от обычного трафика на тех же процентах `TARIFF_TRAFFIC_WARNING_LEVELS`. Сообщение объясняет, что это именно premium-серверы, перечисляет серверы/сквады и ведет пользователя в докупку premium-трафика.
|
||||
|
||||
В Web App админке premium-сквады можно выбрать из выпадающего списка. Список берется из API Remnawave, поэтому UUID не нужно копировать вручную.
|
||||
|
||||
## Traffic-тарифы
|
||||
|
||||
`traffic` продает объем трафика без пользовательского срока действия.
|
||||
@@ -197,7 +241,7 @@ limit_after = current_used + balance_after
|
||||
|
||||
| Поле | Назначение |
|
||||
| --- | --- |
|
||||
| `sale_mode` | Тип продажи: `subscription`, `traffic_package`, `topup`, `tariff_upgrade`, `hwid_devices`. |
|
||||
| `sale_mode` | Тип продажи: `subscription`, `traffic_package`, `topup`, `premium_topup`, `tariff_upgrade`, `hwid_devices`. |
|
||||
| `tariff_key` | Ключ тарифа, к которому относится платеж. |
|
||||
| `purchased_gb` | Купленный объем GB для traffic-пакетов и докупки трафика. |
|
||||
| `purchased_hwid_devices` | Количество устройств при докупке HWID. |
|
||||
|
||||
Reference in New Issue
Block a user