Files
vpn-control-panel/README.md
smolkik-code 7c7c88621d Initial commit: VPN Control Panel
- FastAPI REST API with JWT auth
- aiogram 3 Telegram bot with admin middleware
- APScheduler daily tasks (expiry, reminders, revoke, sync)
- SQLAlchemy 2 async ORM with Alembic migrations
- Jinja2 admin panel (Dashboard, Users, Payments, Servers, Tariffs)
- VPN provider abstraction with MockProvider
- Stats service with revenue/subscription analytics
- Docker Compose (PostgreSQL + Redis + app)
- Healthcheck endpoint
2026-07-05 17:50:11 +07:00

8.0 KiB
Raw Permalink Blame History

VPN Control Panel

Система управления VPN-подписками: регистрация пользователей, тарифы, платежи, Telegram-бот, административная панель и фоновые задачи.

Стек

  • Python 3.13 / FastAPI + Uvicorn
  • SQLAlchemy 2 (async) + asyncpg
  • PostgreSQL 16 / Redis 7
  • Alembic — миграции БД
  • aiogram 3 — Telegram-бот
  • APScheduler — фоновые задачи
  • Jinja2 — админ-панель
  • Docker / Docker Compose

Структура

├── app/
│   ├── api/v1/           # REST API endpoints (users, payments, tariffs, servers, auth, stats)
│   ├── admin/            # Административная панель (Jinja2)
│   ├── bot/              # Telegram bot (handlers, middleware, dispatcher)
│   ├── models/           # SQLAlchemy ORM модели
│   ├── providers/        # VPN-провайдеры (абстракция + Mock)
│   ├── repositories/     # Слой доступа к данным (CRUD)
│   ├── scheduler/        # Фоновые задачи (APScheduler)
│   ├── schemas/          # Pydantic схемы запросов/ответов
│   ├── services/         # Бизнес-логика
│   └── utils/            # Вспомогательные функции
├── docker/
│   ├── Dockerfile        # Production-сборка
│   ├── Dockerfile.dev    # Dev-сборка
│   └── entrypoint.sh     # Точка входа (миграции + uvicorn)
├── migrations/           # Alembic миграции
├── tests/                # Тесты
├── .env.example
├── docker-compose.yml
└── docker-compose.dev.yml

Быстрый старт

1. Запуск через Docker (рекомендуется)

cp .env.example .env
# Отредактируйте .env (BOT_TOKEN, JWT_SECRET и т.д.)
docker compose up -d

Приложение будет доступно на http://localhost:8000.

2. Локальный запуск для разработки

# Только БД и Redis
docker compose -f docker-compose.dev.yml up -d

# Python окружение
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.dev.txt

# Миграции
alembic upgrade head

# Запуск
uvicorn app.main:app --reload --port 8000

Миграции

Создание новой миграции:

alembic revision --autogenerate -m "description"

Применение миграций:

alembic upgrade head

Откат на одну:

alembic downgrade -1

Создание администратора

Администратор создаётся напрямую в БД. Telegram ID — ваш числовой ID в Telegram.

docker compose exec app python -c "
import asyncio
from app.database import async_session_factory
from app.repositories.admin import AdminRepository
from app.models.admin import AdminRole

async def create():
    async with async_session_factory() as session:
        repo = AdminRepository(session)
        admin = await repo.create(
            telegram_id=123456789,   # Ваш Telegram ID
            username='admin',
            role=AdminRole.SUPERADMIN,
            is_active=True,
        )
        print(f'Admin created: id={admin.id} tg={admin.telegram_id}')

asyncio.run(create())
"

Настройка Telegram

  1. Создайте бота через @BotFather, получите токен.
  2. Укажите токен в .env: BOT_TOKEN=ваш_токен.
  3. Узнайте свой Telegram ID (например, через @userinfobot).
  4. Добавьте его в БД через скрипт выше.
  5. Запустите — бот ответит на команды только администраторам из БД.

Команды бота:

/start        — приветствие
/help         — список команд
/users        — список активных пользователей
/user <id>    — информация о пользователе
/delete <id>  — деактивация пользователя
/renew <id>   — статус подписки
/expired      — список просроченных подписок
/expiring [N] — истекают в ближайшие N дней (по умолч. 3)
/stats        — статистика системы

Пример .env

APP_NAME=VPN Control Panel
DEBUG=false
PORT=8000

POSTGRES_USER=vpn
POSTGRES_PASSWORD=vpn_secret
POSTGRES_DB=vpn_control
POSTGRES_HOST=db
POSTGRES_PORT=5432

REDIS_URL=redis://redis:6379/0

BOT_TOKEN=123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
ADMIN_IDS=[123456789]
ADMIN_GROUP_ID=-1001234567890
ADMIN_GROUP_THREAD_ID=

JWT_SECRET=случайная_строка_32_символа
JWT_ACCESS_EXPIRE_MINUTES=30
JWT_REFRESH_EXPIRE_DAYS=30

OUTLINE_API_PREFIX=https://example.com:1234/abc123
OUTLINE_CERT_SHA256=sha256hash...

Пример API

Авторизация:

# Логин (secret_key = JWT_SECRET из .env)
curl -X POST http://localhost:8000/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"telegram_id": 123456789, "secret_key": "change_me_to_random_string"}'

# Ответ:
# {"access_token": "...", "refresh_token": "...", "token_type": "bearer"}

Пользователи:

# Список (требуется Bearer token)
curl http://localhost:8000/api/v1/users \
  -H "Authorization: Bearer <access_token>"

# Создать
curl -X POST http://localhost:8000/api/v1/users \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{"telegram_id": 987654321, "username": "user", "full_name": "User Name"}'

Тарифы:

curl http://localhost:8000/api/v1/tariffs
# [{"id":1,"name":"Basic","duration_days":30,"price":500.0,"currency":"RUB",...}]

Платежи:

curl -X POST http://localhost:8000/api/v1/payments \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{"user_id": 1, "tariff_id": 1, "amount": 500, "provider": "manual"}'

# Подтвердить платёж (активирует подписку)
curl -X PATCH http://localhost:8000/api/v1/payments/1/confirm \
  -H "Authorization: Bearer <access_token>"

Статистика:

curl http://localhost:8000/api/v1/stats
# {"total_users":5,"active_users":3,"total_revenue":2500.0,...}

Административная панель:

http://localhost:8000/admin/        — Dashboard
http://localhost:8000/admin/users   — Пользователи
http://localhost:8000/admin/payments — Платежи
http://localhost:8000/admin/servers  — Серверы
http://localhost:8000/admin/tariffs  — Тарифы

Healthcheck:

curl http://localhost:8000/health
# {"status":"ok","database":"connected"}

Документация API (Swagger):

http://localhost:8000/docs
http://localhost:8000/redoc

Архитектура

Client → FastAPI (REST / Admin)
                ↓
           Service Layer
                ↓
          Repository Layer
                ↓
          PostgreSQL / Redis
                ↓
Telegram Bot ← aiogram ← APScheduler (daily tasks)
  • Service Layer — бизнес-логика, не содержит SQL.
  • Repository Layer — только CRUD, без логики.
  • Сервисы не вызывают друг друга — оркестрация на уровне handler.
  • Telegram-бот не содержит бизнес-логики — только отображение.
  • Scheduler не содержит Telegram-кода — только вызовы сервисов.

Планы

  • WireGuard / Outline / XRay провайдеры
  • Онлайн-оплата (ЮKassa, Stripe)
  • Рассылка уведомлений
  • Dashboard с графиками

Лицензия

MIT