docs: update docs
This commit is contained in:
+20
-2
@@ -1,17 +1,35 @@
|
||||
# Админ-панель Web App
|
||||
|
||||
Админ-панель доступна пользователям, чей Telegram ID указан в `ADMIN_IDS`. В Web App такие пользователи видят раздел администрирования; все API `/api/admin/*` дополнительно проверяют сессию и `ADMIN_IDS` на сервере.
|
||||
Админ-панель доступна пользователям, чей Telegram ID указан в `ADMIN_IDS`. В Web App такие пользователи видят раздел администрирования; все API `/api/admin/*` дополнительно проверяют сессию и `ADMIN_IDS` на сервере. Доступ проверяется по **Telegram ID**, сохранённому у записи пользователя в базе: аккаунт только с email без привязки Telegram не получит права администратора, даже если его идентификатор ошибочно указан в `ADMIN_IDS`.
|
||||
|
||||
## Возможности
|
||||
|
||||
- дашборд со статистикой пользователей, платежей и синхронизации с Remnawave;
|
||||
- список пользователей, карточка активной подписки, обычный и premium-трафик, платежи и действия;
|
||||
- список пользователей с поиском, фильтрами и колонкой premium-трафика; карточка пользователя с активной подпиской, обычным и premium-трафиком, платежами и действиями (подробнее в разделе «Пользователи» ниже);
|
||||
- блокировка пользователей, рассылки, промокоды и просмотр логов;
|
||||
- ручная синхронизация с Remnawave;
|
||||
- редактор разрешенных настроек приложения из manifest-файла;
|
||||
- редактор JSON-каталога тарифов;
|
||||
- загрузка Internal Squads из Remnawave для выбора в тарифах.
|
||||
|
||||
## Пользователи
|
||||
|
||||
Раздел **Пользователи** — таблица с **пагинацией по 25 записей**. Строка поиска ищет по внутреннему числовому ID, Telegram ID, фрагменту `@username`, имени или email; применение — кнопка «Найти» или клавиша Enter в поле поиска.
|
||||
|
||||
**Фильтры:**
|
||||
|
||||
- состояние аккаунта: все / не забанены / забанены;
|
||||
- наличие Telegram или email;
|
||||
- связь с панелью Remnawave (`panel_user_uuid`);
|
||||
- **статус подписки в панели** для активной подписки в базе бота: active, expired, limited;
|
||||
- **premium-трафик**: все; без лимита premium в тарифе; безлимитный оверрайд; норма (ниже 85% квоты); предупреждение (от 85% до 100%); исчерпана квота.
|
||||
|
||||
**Сортировка:** по дате регистрации, имени, ID, а также по **доле использования premium-квоты** (если у активной подписки есть конечный premium-лимит).
|
||||
|
||||
В колонке premium для конечной квоты показывается израсходовано относительно лимита; лимит складывается из базовой premium-квоты тарифа, докупок и бонусов. Отображение **не опирается** на служебный флаг «limited» в базе как на признак «есть premium-трафик» — он отражает другую семантику на стороне панели.
|
||||
|
||||
Карточка пользователя по переходу из списка объединяет просмотр подписки, трафика, платежей и действий (блокировка, сообщения, продление, оверрайды и т.д.) в соответствии с доступными эндпоинтами `/api/admin/users/*`.
|
||||
|
||||
## Настройки
|
||||
|
||||
Раздел **Система -> Настройки** позволяет менять приложение без редактирования `.env`, но только в пределах allowlist из `bot/app/web/admin_settings_manifest.py`. Даже администратор не может менять через UI произвольные атрибуты `Settings`.
|
||||
|
||||
+21
-2
@@ -102,9 +102,11 @@ docker compose -f docker-compose-dev.yml up -d --build --force-recreate
|
||||
| `WEBAPP_SESSION_SECRET` | HMAC-секрет сессий Web App. |
|
||||
| `TELEGRAM_OAUTH_CLIENT_ID` / `TELEGRAM_OAUTH_CLIENT_SECRET` | Данные Telegram OAuth / OpenID Connect из BotFather. |
|
||||
| `TELEGRAM_OAUTH_REQUEST_ACCESS` | Дополнительные разрешения Telegram Login, например `write`. |
|
||||
| `SMTP_HOST`, `SMTP_PORT`, `SMTP_FALLBACK_PORTS` | SMTP-подключение для email-кодов. |
|
||||
| `SMTP_HOST`, `SMTP_PORT`, `SMTP_FALLBACK_PORTS` | SMTP-подключение для email-кодов; резервные порты перебираются при ошибке основного. |
|
||||
| `SMTP_TIMEOUT_SECONDS` | Таймаут одной попытки подключения и отправки. |
|
||||
| `SMTP_STARTTLS` / `SMTP_USE_SSL` | STARTTLS на обычном порту (например 587) и SSL-обёртка (часто порт 465). |
|
||||
| `SMTP_USERNAME` / `SMTP_PASSWORD` | Логин и пароль или SMTP key. |
|
||||
| `SMTP_FROM_EMAIL` / `SMTP_FROM_NAME` | Отправитель писем с кодом. |
|
||||
| `SMTP_FROM_EMAIL` / `SMTP_FROM_NAME` | Отправитель писем с кодом; адрес из `SMTP_FROM_EMAIL` должен быть разрешён у провайдера. |
|
||||
| `EMAIL_CODE_TTL_SECONDS` | Срок действия email-кода. |
|
||||
| `EMAIL_CODE_RESEND_SECONDS` | Пауза перед повторной отправкой кода. |
|
||||
| `EMAIL_CODE_MAX_ATTEMPTS` | Максимум попыток ввода одного кода. |
|
||||
@@ -115,6 +117,23 @@ docker compose -f docker-compose-dev.yml up -d --build --force-recreate
|
||||
|
||||
Настройка домена, BotFather и callback URL описана в [webapp.md](webapp.md).
|
||||
|
||||
### SMTP и вход по email
|
||||
|
||||
Вход по email в Web App включается только если заполнены все обязательные поля SMTP: **`SMTP_HOST`**, **`SMTP_PORT`**, **`SMTP_USERNAME`**, **`SMTP_PASSWORD`**, **`SMTP_FROM_EMAIL`**. Имя отправителя **`SMTP_FROM_NAME`** необязательно. Пока конфигурация неполная, интерфейс входа по email не показывается.
|
||||
|
||||
Рекомендуемый типичный вариант — **порт 587** с **STARTTLS** (`SMTP_STARTTLS=True`, `SMTP_USE_SSL=False`), как в примере для Brevo в `.env.example`. Для **порта 465** обычно используют обёртку SSL: выставьте `SMTP_USE_SSL=True` и при необходимости `SMTP_STARTTLS=False`; приложение также считает порт 465 SSL-режимом автоматически при отправке.
|
||||
|
||||
Если основной порт недоступен, перебираются порты из **`SMTP_FALLBACK_PORTS`** (список через запятую, после `SMTP_PORT`). Таймаут одной попытки подключения и отправки задаёт **`SMTP_TIMEOUT_SECONDS`**.
|
||||
|
||||
Порядок действий при подключении нового SMTP:
|
||||
|
||||
1. В панели почтового провайдера создайте SMTP-доступ и подтвердите адрес отправителя (**from**), совпадающий с `SMTP_FROM_EMAIL`.
|
||||
2. Перенесите хост, порт, логин и пароль (или API-ключ SMTP) в `.env`.
|
||||
3. Перезапустите контейнер приложения, чтобы подхватить переменные.
|
||||
4. Проверьте вход: на странице Web App запросите код на почту; при ошибках смотрите логи контейнера.
|
||||
|
||||
Для ограничений по частоте отправки кодов см. `EMAIL_CODE_*` и `BRUTE_FORCE_*` в таблице выше.
|
||||
|
||||
## Пробный период
|
||||
|
||||
| Переменная | Назначение |
|
||||
|
||||
@@ -19,6 +19,85 @@ IMAGE_TAG=3.1.0 docker compose -f docker-compose-remote-server.yml up -d
|
||||
|
||||
`docker-compose-remote-server.yml` можно использовать как шаблон и заменить `image:` на нужный образ. По умолчанию используется `ghcr.io/3252a8/remnawave-minishop:latest`.
|
||||
|
||||
## Обновление версии
|
||||
|
||||
Образ приложения: `ghcr.io/3252a8/remnawave-minishop`. Тег задаётся переменной окружения **`IMAGE_TAG`** (в Compose подставляется как `${IMAGE_TAG:-latest}`). Для продакшена разумно закрепить **конкретный тег релиза** вместо `latest`, чтобы обновляться осознанно и иметь откат.
|
||||
|
||||
**Запуск из готового образа** (`docker-compose-remote-server.yml` или свой файл с тем же шаблоном):
|
||||
|
||||
1. Сделайте резервную копию базы (особенно перед крупными обновлениями) — см. раздел «Резервная копия и восстановление PostgreSQL» ниже на этой странице.
|
||||
2. Укажите нужный тег, например в `.env`: `IMAGE_TAG=3.2.0` (или экспортируйте переменную перед командой).
|
||||
3. Подтяните образ и пересоздайте контейнер приложения (БД при этом не удаляется, том данных сохраняется):
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose-remote-server.yml pull remnawave-minishop
|
||||
docker compose -f docker-compose-remote-server.yml up -d --no-deps remnawave-minishop
|
||||
```
|
||||
|
||||
При необходимости перезапустите оба сервиса: `docker compose -f docker-compose-remote-server.yml up -d`. Флаг `--force-recreate` добавляют, если нужно гарантированно пересоздать контейнер при неизменённом образе.
|
||||
|
||||
**Локальная сборка из репозитория** (ваш `Dockerfile`):
|
||||
|
||||
```bash
|
||||
git pull
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
После обновления проверьте логи (`docker compose logs -f remnawave-minishop`), работу бота, вебхуков и Web App. Совместимость с панелью Remnawave — см. раздел «Совместимость» в [README.md](../README.md).
|
||||
|
||||
## Резервная копия и восстановление PostgreSQL
|
||||
|
||||
Имя контейнера БД в типичном Compose — `remnawave-minishop-db`. Подставьте значения **`POSTGRES_USER`** и **`POSTGRES_DB`** из `.env` (на хосте можно выполнить `set -a && source .env && set +a` перед командами или подставить вручную).
|
||||
|
||||
### Резервная копия (текстовый SQL)
|
||||
|
||||
Логическое дампирование в один файл:
|
||||
|
||||
```bash
|
||||
docker exec remnawave-minishop-db pg_dump -U "$POSTGRES_USER" "$POSTGRES_DB" > backup.sql
|
||||
```
|
||||
|
||||
Такой файл удобно хранить вне сервера. При необходимости добавьте к `pg_dump` параметры сжатия или расписание через cron.
|
||||
|
||||
### Восстановление из `backup.sql`
|
||||
|
||||
Дамп выше — **обычный текст SQL** без удаления существующих объектов. Чтобы накатить его на **чистую** базу с тем же именем:
|
||||
|
||||
1. Остановите приложение, чтобы не было записей в БД:
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose-remote-server.yml stop remnawave-minishop
|
||||
```
|
||||
|
||||
(или ваш файл Compose без `-f`, если работаете из каталога проекта.)
|
||||
|
||||
2. Удалите базу и создайте пустую с тем же именем — пользователь из `.env` в официальном образе PostgreSQL обычно суперпользователь и может это сделать:
|
||||
|
||||
```bash
|
||||
docker exec remnawave-minishop-db dropdb -U "$POSTGRES_USER" "$POSTGRES_DB" --if-exists
|
||||
docker exec remnawave-minishop-db createdb -U "$POSTGRES_USER" "$POSTGRES_DB"
|
||||
```
|
||||
|
||||
Если `dropdb` сообщает, что база занята, убедитесь, что остановлен сервис `remnawave-minishop` и к базе нет других подключений.
|
||||
|
||||
3. Восстановите данные из файла на хосте:
|
||||
|
||||
```bash
|
||||
docker exec -i remnawave-minishop-db psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" < backup.sql
|
||||
```
|
||||
|
||||
4. Запустите приложение снова:
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose-remote-server.yml start remnawave-minishop
|
||||
```
|
||||
|
||||
Проверьте логи и работу бота. При ошибках импорта убедитесь, что версия приложения совместима со схемой в дампе (после обновлений бота иногда нужны шаги из changelog релиза).
|
||||
|
||||
### Замечание про «накат поверх» без пересоздания БД
|
||||
|
||||
Если нужно применить дамп к уже заполненной базе без `dropdb`, создавайте резервные копии с **`pg_dump --clean --if-exists`** — в файл попадут команды `DROP` перед `CREATE`, и `psql` сможет перезаписать объекты. Это разрушительно для текущих данных; перед таким сценарием сделайте отдельный свежий бэкап.
|
||||
|
||||
## Порты
|
||||
|
||||
| Порт | Назначение |
|
||||
|
||||
+3
-1
@@ -14,7 +14,7 @@ Web App запускается в том же контейнере, что и б
|
||||
- реферальную ссылку и статистику приглашений;
|
||||
- привязку email и Telegram к одному аккаунту.
|
||||
|
||||
Для администраторов из `ADMIN_IDS` Web App также показывает админ-панель: статистику, пользователей, рассылки, промокоды, логи, настройки и редактор тарифов. Подробности: [admin.md](admin.md).
|
||||
Для администраторов из `ADMIN_IDS` Web App также показывает админ-панель: статистику, **пользователей** (поиск, фильтры, premium-трафик), рассылки, промокоды, логи, настройки и редактор тарифов. Подробности: [admin.md](admin.md).
|
||||
|
||||
## Настройки `.env`
|
||||
|
||||
@@ -74,6 +74,8 @@ Email-вход работает через одноразовый код:
|
||||
|
||||
Для Brevo обычно подходит порт `587` с STARTTLS. Если основной порт недоступен, приложение пробует порты из `SMTP_FALLBACK_PORTS`; порт `465` используется через SSL.
|
||||
|
||||
Полный список переменных, обязательные поля для включения email-входа и типичные ошибки подключения описаны в разделе **SMTP и вход по email** в [configuration.md](configuration.md).
|
||||
|
||||
## Проксирование
|
||||
|
||||
Web App должен проксироваться отдельно от вебхуков:
|
||||
|
||||
Reference in New Issue
Block a user