# 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 (рекомендуется) ```bash cp .env.example .env # Отредактируйте .env (BOT_TOKEN, JWT_SECRET и т.д.) docker compose up -d ``` Приложение будет доступно на `http://localhost:8000`. ### 2. Локальный запуск для разработки ```bash # Только БД и 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 ``` ## Миграции Создание новой миграции: ```bash alembic revision --autogenerate -m "description" ``` Применение миграций: ```bash alembic upgrade head ``` Откат на одну: ```bash alembic downgrade -1 ``` ## Создание администратора Администратор создаётся напрямую в БД. Telegram ID — ваш числовой ID в Telegram. ```bash 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](https://t.me/BotFather), получите токен. 2. Укажите токен в `.env`: `BOT_TOKEN=ваш_токен`. 3. Узнайте свой Telegram ID (например, через @userinfobot). 4. Добавьте его в БД через скрипт выше. 5. Запустите — бот ответит на команды только администраторам из БД. Команды бота: ``` /start — приветствие /help — список команд /users — список активных пользователей /user — информация о пользователе /delete — деактивация пользователя /renew — статус подписки /expired — список просроченных подписок /expiring [N] — истекают в ближайшие N дней (по умолч. 3) /stats — статистика системы ``` ## Пример .env ```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 Авторизация: ```bash # Логин (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"} ``` Пользователи: ```bash # Список (требуется Bearer token) curl http://localhost:8000/api/v1/users \ -H "Authorization: Bearer " # Создать curl -X POST http://localhost:8000/api/v1/users \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{"telegram_id": 987654321, "username": "user", "full_name": "User Name"}' ``` Тарифы: ```bash curl http://localhost:8000/api/v1/tariffs # [{"id":1,"name":"Basic","duration_days":30,"price":500.0,"currency":"RUB",...}] ``` Платежи: ```bash curl -X POST http://localhost:8000/api/v1/payments \ -H "Authorization: Bearer " \ -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 " ``` Статистика: ```bash 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: ```bash 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