Files
remnawave-bedolaga-telegram…/app/webapi/app.py
T
PEDZEO 6b69ec750e feat: add cabinet (personal account) backend API
- Add JWT authentication for cabinet users
- Add Telegram WebApp authentication
- Add subscription management endpoints
- Add balance and transactions endpoints
- Add referral system endpoints
- Add tickets support for cabinet
- Add webhooks and websocket for real-time updates
- Add email verification service

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 23:20:20 +03:00

267 lines
10 KiB
Python

from __future__ import annotations
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from app.config import settings
from app.webapi.docs import add_redoc_endpoint
from .middleware import RequestLoggingMiddleware
from .routes import (
broadcasts,
backups,
campaigns,
config,
health,
main_menu_buttons,
media,
menu_layout,
miniapp,
partners,
pinned_messages,
polls,
promocodes,
promo_groups,
promo_offers,
user_messages,
welcome_texts,
pages,
remnawave,
contests,
servers,
subscription_events,
stats,
subscriptions,
tickets,
tokens,
transactions,
users,
logs,
webhooks,
websocket,
)
# Cabinet (Personal Account) routes
from app.cabinet.routes import router as cabinet_router
OPENAPI_TAGS = [
{
"name": "health",
"description": "Мониторинг состояния административного API и связанных сервисов.",
},
{
"name": "stats",
"description": "Сводные показатели по пользователям, подпискам и платежам.",
},
{
"name": "settings",
"description": "Получение и изменение конфигурации бота из административной панели.",
},
{
"name": "main-menu",
"description": "Управление кнопками и сообщениями главного меню Telegram-бота.",
},
{
"name": "menu-layout",
"description": "API конструктор меню: управление расположением и настройками кнопок.",
},
{
"name": "welcome-texts",
"description": "Создание, редактирование и управление приветственными текстами.",
},
{
"name": "users",
"description": "Управление пользователями, балансом и статусами подписок.",
},
{
"name": "subscriptions",
"description": "Создание, продление и настройка подписок бота.",
},
{
"name": "support",
"description": "Работа с тикетами поддержки, приоритетами и ограничениями на ответы.",
},
{
"name": "transactions",
"description": "История финансовых операций и пополнений баланса.",
},
{
"name": "promo-groups",
"description": "Создание и управление промо-группами и их участниками.",
},
{
"name": "servers",
"description": (
"Управление серверами RemnaWave, их доступностью, промогруппами и "
"ручная синхронизация данных.",
),
},
{
"name": "promo-offers",
"description": "Управление промо-предложениями, шаблонами и журналом событий.",
},
{
"name": "logs",
"description": (
"Журналы мониторинга бота, действий модераторов поддержки и системный лог-файл."
),
},
{
"name": "auth",
"description": "Управление токенами доступа к административному API.",
},
{
"name": "remnawave",
"description": (
"Интеграция с RemnaWave: статус панели, управление нодами, сквадами и синхронизацией "
"данных между ботом и панелью."
),
},
{
"name": "media",
"description": "Загрузка файлов в Telegram и получение ссылок на медиа.",
},
{
"name": "miniapp",
"description": "Endpoint для Telegram Mini App с информацией о подписке пользователя.",
},
{
"name": "partners",
"description": "Просмотр участников реферальной программы, их доходов и рефералов.",
},
{
"name": "polls",
"description": "Создание опросов, удаление, статистика и ответы пользователей.",
},
{
"name": "pages",
"description": "Управление контентом публичных страниц: оферта, политика, FAQ и правила.",
},
{
"name": "notifications",
"description": (
"Получение и просмотр уведомлений о покупках, активациях и продлениях подписок, "
"пополнениях баланса, активациях промокодов, переходах по реферальным ссылкам и "
"сменах промогрупп пользователей для административной панели."
),
},
{
"name": "contests",
"description": "Управление конкурсами: реферальными и ежедневными играми/раундами.",
},
{
"name": "webhooks",
"description": "Управление webhooks для подписки на события системы (пользователи, платежи, тикеты).",
},
{
"name": "websocket",
"description": "WebSocket подключения для real-time обновлений дашборда и уведомлений.",
},
{
"name": "pinned-messages",
"description": (
"Управление закреплёнными сообщениями: создание, обновление, рассылка и "
"настройка показа при /start."
),
},
]
def create_web_api_app() -> FastAPI:
docs_config = settings.get_web_api_docs_config()
# Убираем openapi_tags для предотвращения ошибок при генерации openapi.json
app = FastAPI(
title=settings.WEB_API_TITLE,
version=settings.WEB_API_VERSION,
docs_url=docs_config.get("docs_url"),
redoc_url=None,
openapi_url=docs_config.get("openapi_url"),
swagger_ui_parameters={"persistAuthorization": True},
)
add_redoc_endpoint(
app,
redoc_url=docs_config.get("redoc_url"),
openapi_url=docs_config.get("openapi_url"),
title=settings.WEB_API_TITLE,
)
allowed_origins = settings.get_web_api_allowed_origins()
cabinet_origins = settings.get_cabinet_allowed_origins()
all_origins = list(set(allowed_origins + cabinet_origins))
app.add_middleware(
CORSMiddleware,
allow_origins=["*"] if "*" in all_origins else all_origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
if settings.WEB_API_REQUEST_LOGGING:
app.add_middleware(RequestLoggingMiddleware)
app.include_router(health.router)
app.include_router(stats.router, prefix="/stats", tags=["stats"])
app.include_router(config.router, prefix="/settings", tags=["settings"])
app.include_router(users.router, prefix="/users", tags=["users"])
app.include_router(subscriptions.router, prefix="/subscriptions", tags=["subscriptions"])
app.include_router(tickets.router, prefix="/tickets", tags=["support"])
app.include_router(transactions.router, prefix="/transactions", tags=["transactions"])
app.include_router(promo_groups.router, prefix="/promo-groups", tags=["promo-groups"])
app.include_router(promo_offers.router, prefix="/promo-offers", tags=["promo-offers"])
app.include_router(servers.router, prefix="/servers", tags=["servers"])
app.include_router(contests.router, prefix="/contests", tags=["contests"])
app.include_router(
main_menu_buttons.router,
prefix="/main-menu/buttons",
tags=["main-menu"],
)
app.include_router(
menu_layout.router,
prefix="/menu-layout",
tags=["menu-layout"],
)
app.include_router(
user_messages.router,
prefix="/main-menu/messages",
tags=["main-menu"],
)
app.include_router(
welcome_texts.router,
prefix="/welcome-texts",
tags=["welcome-texts"],
)
app.include_router(pages.router, prefix="/pages", tags=["pages"])
app.include_router(promocodes.router, prefix="/promo-codes", tags=["promo-codes"])
app.include_router(broadcasts.router, prefix="/broadcasts", tags=["broadcasts"])
app.include_router(backups.router, prefix="/backups", tags=["backups"])
app.include_router(campaigns.router, prefix="/campaigns", tags=["campaigns"])
app.include_router(tokens.router, prefix="/tokens", tags=["auth"])
app.include_router(remnawave.router, prefix="/remnawave", tags=["remnawave"])
app.include_router(media.router, tags=["media"])
app.include_router(miniapp.router, prefix="/miniapp", tags=["miniapp"])
app.include_router(partners.router, prefix="/partners", tags=["partners"])
app.include_router(polls.router, prefix="/polls", tags=["polls"])
app.include_router(logs.router, prefix="/logs", tags=["logs"])
app.include_router(
pinned_messages.router,
prefix="/pinned-messages",
tags=["pinned-messages"],
)
app.include_router(
subscription_events.router,
prefix="/notifications/subscriptions",
tags=["notifications"],
)
app.include_router(webhooks.router, prefix="/webhooks", tags=["webhooks"])
app.include_router(websocket.router, tags=["websocket"])
# Cabinet (Personal Account) routes
if settings.is_cabinet_enabled():
app.include_router(cabinet_router)
return app