Skip to main content

Обзор

Бот использует PostgreSQL через SQLAlchemy 2.x async ORM. Все модели определены в app/database/models.py.

Миграции (Alembic)

Миграции хранятся в migrations/alembic/versions/.
# Применить миграции
make migrate

# Создать новую миграцию
make migration m="add_new_table"

# Отметить текущую БД как актуальную (без DDL)
make migrate-stamp

# История миграций
make migrate-history
При запуске бот автоматически выполняет alembic upgrade head через app/database/migrations.py.
Для существующих production баз после перехода на Alembic выполните make migrate-stamp один раз.

Настройка подключения

DATABASE_URL=postgresql+asyncpg://user:password@localhost:5432/bedolaga
Бот поддерживает как PostgreSQL, так и SQLite (для разработки).

CRUD операции

Каждая сущность имеет свой CRUD-модуль в app/database/crud/:
from app.database.crud.user import create_user, get_user_by_telegram_id

async with get_session() as session:
    user = await get_user_by_telegram_id(session, telegram_id=123456)

Enum-типы

EnumЗначения
UserStatusactive, blocked, deleted
SubscriptionStatustrial, active, expired, disabled, pending
TransactionTypedeposit, withdrawal, subscription_payment, refund, referral_reward, poll_reward
PromoCodeTypebalance, subscription_days, trial_subscription, promo_group, discount
PaymentMethodtelegram_stars, tribute, yookassa, cryptobot, heleket, mulenpay, pal24, wata, platega, cloudpayments, freekassa, kassa_ai, manual, balance
TicketStatusopen, answered, closed, pending
PartnerStatusnone, pending, approved, rejected
WithdrawalRequestStatuspending, approved, rejected, completed, cancelled
GameTypequest_buttons, lock_hack, letter_cipher, server_lottery, blitz_reaction, emoji_guess, anagram

Схема по доменам

Пользователи (3 таблицы)

users — центральная таблица, к ней привязаны все остальные сущности.
Группа полейКлючевые поля
Идентификацияid, telegram_id (UNIQUE, nullable), auth_type (telegram/email)
Профильusername, first_name, last_name, language, status
Балансbalance_kopeks, has_had_paid_subscription, has_made_first_topup
Рефералreferred_by_id (FK self), referral_code (UNIQUE), referral_commission_percent
RemnaWaveremnawave_uuid (UNIQUE), trojan_password, vless_uuid, ss_password
Email-авторизацияemail (UNIQUE), email_verified, password_hash, email_verification_token
OAuthgoogle_id, yandex_id, discord_id, vk_id (все UNIQUE)
Промоpromo_group_id (FK), promo_offer_discount_percent, auto_promo_group_assigned
Ограниченияrestriction_topup, restriction_subscription, restriction_reason
Партнерpartner_status
Связи: subscription (1:1), transactions (1:N), referrals (self 1:N), user_promo_groups (1:N), tickets (1:N), referral_earnings (1:N), discount_offers (1:N) cabinet_refresh_tokens — JWT refresh-токены для Cabinet.
ПолеОписание
user_idFK -> users
token_hashSHA-256 хеш (UNIQUE)
expires_atСрок действия
revoked_atВремя отзыва (nullable)
partner_applications — заявки на партнерскую программу.
ПолеОписание
user_idFK -> users
company_name, website_url, telegram_channelДанные заявки
statusPartnerStatus
approved_commission_percentУтвержденная комиссия

Подписки (5 таблиц)

subscriptions — VPN-подписка (1:1 с пользователем).
Группа полейКлючевые поля
Основныеuser_id (UNIQUE FK), status, is_trial, start_date, end_date
Трафикtraffic_limit_gb (0 = безлимит), traffic_used_gb, purchased_traffic_gb, traffic_reset_at
Устройстваdevice_limit, modem_enabled
Серверыconnected_squads (JSON), subscription_url, subscription_crypto_link
Автоплатежautopay_enabled, autopay_days_before
Тарифtariff_id (FK, SET NULL)
Суточныйis_daily_paused, last_daily_charge_at
subscription_servers — привязка подписки к серверам.
ПолеОписание
subscription_idFK -> subscriptions
server_squad_idFK -> server_squads
paid_price_kopeksЦена за подключение к серверу
subscription_conversions — конверсия триала в платную подписку. subscription_events — журнал событий подписки (event_type, amount_kopeks, message, extra JSON). traffic_purchases — докупки трафика (traffic_gb, expires_at = дата покупки + 30 дней).

Платежи и транзакции (12 таблиц)

transactions — единый финансовый реестр.
ПолеОписание
user_idFK -> users
typeTransactionType
amount_kopeksСумма в копейках
payment_methodPaymentMethod
external_idID во внешней системе
is_completedЗавершена ли
receipt_uuidUUID фискального чека NaloGO
10 таблиц платежных провайдеров — по одной на каждый провайдер. Все содержат: user_id, status, transaction_id, сумму и ID во внешней системе. Telegram Stars и Tribute не имеют отдельных таблиц — используют transactions напрямую.
ТаблицаПровайдерУникальный ID
yookassa_paymentsYooKassayookassa_payment_id
cryptobot_paymentsCryptoBotinvoice_id
heleket_paymentsHeleketuuid, order_id
mulenpay_paymentsMulenPayuuid
pal24_paymentsPayPalychbill_id
wata_paymentsWATApayment_link_id
platega_paymentsPlategaplatega_transaction_id, correlation_id
cloudpayments_paymentsCloudPaymentstransaction_id_cp, invoice_id
freekassa_paymentsFreekassaorder_id, freekassa_order_id
kassa_ai_paymentsKassa AIorder_id, kassa_ai_order_id
payment_method_configs — настройки отображения платежных методов в Cabinet.
ПолеОписание
method_idID метода (UNIQUE)
sort_orderПорядок сортировки
is_enabledВключен ли
sub_optionsJSON: {"card": true, "sbp": false}
min_amount_kopeks, max_amount_kopeksЛимиты сумм
user_type_filterall, telegram, email

Промо-система (8 таблиц + 3 M2M)

promo_groups — группы со скидками.
ПолеОписание
nameНазвание (UNIQUE)
priorityПриоритет (выше = важнее)
server_discount_percent, traffic_discount_percent, device_discount_percentСкидки 0-100%
period_discountsJSON: {"30": 10, "90": 15}
auto_assign_total_spent_kopeksПорог автоназначения
is_defaultГруппа по умолчанию
M2M связи: server_squads, tariffs, payment_method_configs user_promo_groups — пользователь может состоять в нескольких группах (user_id + promo_group_id составной PK). promocodes — промокоды (5 типов).
ПолеОписание
codeКод (UNIQUE)
typePromoCodeType
balance_bonus_kopeks, subscription_daysПараметры бонуса
max_uses, current_usesЛимиты использования
valid_untilСрок действия
first_purchase_onlyТолько для первой покупки
promo_group_idFK -> promo_groups (дополнительная привязка)
promocode_uses — журнал активаций (promocode_id, user_id, used_at). discount_offers — персональные скидочные предложения.
ПолеОписание
user_idFK -> users
discount_percentПроцент скидки
expires_atСрок действия
is_active, claimed_atСтатус
effect_typeТип эффекта
extra_dataJSON с доп. параметрами
promo_offer_templates — шаблоны предложений (тип, текст сообщения, кнопка, часы действия, серверы для test_access). subscription_temporary_access — временный доступ к серверам через промо-предложения. promo_offer_logs — журнал действий с предложениями (claimed, consumed, disabled).

Реферальная система (3 таблицы)

referral_earnings — начисления реферальных комиссий.
ПолеОписание
user_idFK -> users (реферер)
referral_idFK -> users (приглашенный)
amount_kopeksСумма комиссии
reasonПричина начисления
campaign_idFK -> advertising_campaigns (nullable)
withdrawal_requests — заявки на вывод средств.
ПолеОписание
user_idFK -> users
amount_kopeksСумма
statusWithdrawalRequestStatus
risk_score0-100 (антифрод)
risk_analysisJSON с деталями анализа
sent_notifications — трекинг отправленных уведомлений (предотвращает дублирование).

Поддержка (5 таблиц)

tickets — тикеты поддержки (status, priority, user_reply_block_permanent, user_reply_block_until). ticket_messages — сообщения в тикетах (текст, медиа-вложения с media_file_id). ticket_notifications — уведомления для Cabinet (notification_type: new_ticket, admin_reply, user_reply). support_audit_logs — журнал действий модераторов (action, actor_user_id, target_user_id, details JSON). broadcast_history — история рассылок.
ПолеОписание
target_typeСегмент аудитории
channeltelegram, email, both
total_count, sent_count, failed_count, blocked_countСтатистика доставки
statusСтатус рассылки

Конкурсы (6 таблиц)

referral_contests — реферальные конкурсы (title, contest_type, start_at/end_at, daily_summary_times). referral_contest_events — события конкурса (UNIQUE: contest_id + referral_id). referral_contest_virtual_participants — виртуальные участники для буста лидерборда. contest_templates — шаблоны ежедневных игр (7 типов).
ПолеОписание
slugУникальный идентификатор игры
prize_typedays, balance, custom
schedule_timesРасписание (CSV “HH:MM”)
payloadJSON с конфигурацией игры
contest_rounds — раунды игр (status: active/finished, winners_count). contest_attempts — попытки участия (UNIQUE: round_id + user_id).

Кампании (2 таблицы)

advertising_campaigns — рекламные кампании с deep-link.
ПолеОписание
start_parameterDeep-link параметр (UNIQUE)
bonus_typebalance, subscription, tariff, none
tariff_idFK -> tariffs (для тарифных бонусов)
partner_user_idFK -> users (привязка к партнеру)
advertising_campaign_registrations — регистрации через кампании (UNIQUE: campaign_id + user_id).

Опросы (5 таблиц)

Цепочка: polls -> poll_questions -> poll_options -> poll_answers. polls — опросы (title, reward_enabled, reward_amount_kopeks). poll_responses — участие пользователя в опросе (UNIQUE: poll_id + user_id, reward_given).

Колесо фортуны (3 таблицы)

wheel_configs — конфигурация колеса (rtp_percent, spin_cost_stars, daily_spin_limit). wheel_prizes — призы (prize_type: subscription_days/balance_bonus/traffic_gb/promocode/nothing, manual_probability). wheel_spins — история вращений (user_id, prize_id, payment_type, is_applied).

Серверы и тарифы (3 таблицы)

tariffs — тарифные планы (см. Управление тарифами). server_squads — серверные группы.
ПолеОписание
squad_uuidUUID из RemnaWave (UNIQUE)
display_name, original_nameНазвания
country_codeКод страны
is_available, is_trial_eligibleДоступность
price_kopeksЦена подключения
max_users, current_usersЛимиты
squads — устаревшая таблица серверов (заменена на server_squads).

Системные и контентные (12 таблиц)

ТаблицаОписание
system_settingsKey-value хранилище рантайм-настроек
service_rulesПравила сервиса (по языкам)
privacy_policiesПолитика конфиденциальности (по языкам)
public_offersПубличная оферта (по языкам)
faq_settingsНастройки FAQ (по языкам)
faq_pagesСтраницы FAQ
user_messagesПользовательские сообщения от админа
welcome_textsПриветственные тексты
pinned_messagesЗакрепленные сообщения (текст, медиа)
main_menu_buttonsКастомные кнопки главного меню
menu_layout_historyИстория изменений конфигурации меню
monitoring_logsЖурнал мониторинга

Вебхуки (2 таблицы)

webhooks — настройки вебхуков (url, secret, event_type, failure_count, success_count). webhook_deliveries — история доставок (status: pending/success/failed, attempt_number, next_retry_at).

Web API и Cabinet (2 таблицы)

web_api_tokens — API-ключи (token_hash UNIQUE, token_prefix, expires_at, is_active). button_click_logs — журнал кликов по кнопкам меню (аналитика).

Сводка по доменам

ДоменТаблицОсновные сущности
Пользователи3users, cabinet_refresh_tokens, partner_applications
Подписки5subscriptions, subscription_servers, subscription_conversions, subscription_events, traffic_purchases
Платежи12transactions + 10 провайдеров + payment_method_configs
Промо8 + 3 M2Mpromo_groups, user_promo_groups, promocodes, discount_offers, promo_offer_templates
Реферал3referral_earnings, withdrawal_requests, sent_notifications
Поддержка5tickets, ticket_messages, ticket_notifications, support_audit_logs, broadcast_history
Конкурсы6contest_templates, contest_rounds, contest_attempts, referral_contests
Кампании2advertising_campaigns, advertising_campaign_registrations
Опросы5polls, poll_questions, poll_options, poll_responses, poll_answers
Колесо фортуны3wheel_configs, wheel_prizes, wheel_spins
Серверы и тарифы3tariffs, server_squads, squads
Системные12system_settings, service_rules, privacy_policies, faq_pages, main_menu_buttons, menu_layout_history и др.
Вебхуки2webhooks, webhook_deliveries
Web API2web_api_tokens, button_click_logs
Итого~66 + 3 M2M