Commit Graph

203 Commits

Author SHA1 Message Date
Fringg
1f0fef114b refactor: complete structlog migration with contextvars, kwargs, and logging hardening
- Add ContextVarsMiddleware for automatic user_id/chat_id/username binding
  via structlog contextvars (aiogram) and http_method/http_path (FastAPI)
- Use bound_contextvars() context manager instead of clear_contextvars()
  to safely restore previous state instead of wiping all context
- Register ContextVarsMiddleware as outermost middleware (before GlobalError)
  so all error logs include user context
- Replace structlog.get_logger() with structlog.get_logger(__name__) across
  270 calls in 265 files for meaningful logger names
- Switch wrapper_class from BoundLogger to make_filtering_bound_logger()
  for pre-processor level filtering (performance optimization)
- Migrate 1411 %-style positional arg logger calls to structlog kwargs
  style across 161 files via AST script
- Migrate log_rotation_service.py from stdlib logging to structlog
- Add payment module prefixes to TelegramNotifierProcessor.IGNORED_LOGGER_PREFIXES
  and ExcludePaymentFilter.PAYMENT_MODULES to prevent payment data leaking
  to Telegram notifications and general log files
- Fix LoggingMiddleware: add from_user null-safety for channel posts,
  switch time.time() to time.monotonic() for duration measurement
- Remove duplicate logger assignments in purchase.py, config.py,
  inline.py, and admin/payments.py
2026-02-16 09:18:12 +03:00
Fringg
64a684cd2f fix: filter out traffic packages with zero price from purchase options 2026-02-15 23:32:15 +03:00
Fringg
80914c1af7 fix: daily tariff subscriptions stuck in expired/disabled with no resume path
- Keyboard now shows "Возобновить" for disabled/expired daily tariffs
  instead of useless "Приостановить"
- resume_daily_subscription handles EXPIRED→ACTIVE (not only DISABLED)
- Pause handler detects inactive status and calls resume directly
- subscription_extend redirects daily tariffs to subscription info
  (daily tariffs have no period_prices, so extend page was empty)
2026-02-15 23:17:45 +03:00
Fringg
68773b7e77 feat: add per-button enable/disable toggle and custom labels per locale
- Add enabled flag to hide/show each button section in main menu
- Add per-locale custom labels (ru, en, ua, zh, fa) for button text
- Deep-copy nested labels dict in cache to prevent reference leaks
- Validate label entries from DB (type + locale key checks)
- Use selective merge in PATCH handler instead of blind .update()
2026-02-12 23:42:55 +03:00
Fringg
10538e7351 feat: add 'default' (no color) option for button styles
Allow admins to set buttons to Telegram's default style with no color
override. Refactors style resolution from or-chain to explicit if/elif/else
so that 'default' does not fall through to global config or hardcoded defaults.
2026-02-12 23:25:42 +03:00
Fringg
a9687912df feat: add per-section button style and emoji customization via admin API
Add cabinet admin API for configuring button colors (primary/success/danger)
and custom emoji IDs per menu section (home, subscription, balance, referral,
support, info, admin). Styles are stored as JSON in system_settings and cached
in-process for fast resolution.

Style resolution chain: explicit param > per-section DB > global config > defaults.
2026-02-12 23:15:58 +03:00
Fringg
46c1a69456 fix: pre-validate CABINET_BUTTON_STYLE to prevent invalid values from suppressing per-section defaults 2026-02-12 22:43:30 +03:00
Fringg
bf2b2f1c56 feat: add button style and emoji support for cabinet mode (Bot API 9.4)
- Upgrade aiogram to 3.25.0 for style/icon_custom_emoji_id support
- Add CABINET_BUTTON_STYLE config for global color override
- Per-section default styles: subscription (green), balance (blue),
  referral (green), admin (red), home (blue)
- Style priority: explicit > CABINET_BUTTON_STYLE > per-section default
- Add icon_custom_emoji_id pass-through for Premium bot owners
- Admin panel setting for button style with color picker
2026-02-12 22:34:38 +03:00
Fringg
9ac6da490d feat: add web admin button for admins in cabinet mode 2026-02-12 22:22:28 +03:00
Fringg
ad87c5fb5e feat: rename MAIN_MENU_MODE=text to cabinet with deep-linking to frontend sections
- Rename mode from 'text' to 'cabinet' (text/text_only/minimal kept as aliases)
- Add build_cabinet_url() for joining MINIAPP_CUSTOM_URL with section paths
- Cabinet main menu now has section-specific buttons: subscription, balance,
  referral, support, info — each opens the corresponding cabinet page
- Add CALLBACK_TO_CABINET_PATH mapping for automatic deep-linking from
  callback_data to cabinet routes (/subscription, /balance, /referral, etc.)
- Unmapped callback_data gracefully falls back to regular Telegram callbacks
- Add startup validation warning when cabinet mode is active without MINIAPP_CUSTOM_URL
- Update admin broadcast buttons with section-specific routing
- Backward compatible: is_text_main_menu_mode() kept as alias for is_cabinet_mode()
2026-02-12 22:21:08 +03:00
Fringg
3dac332a9f chore: ruff format 7 files 2026-02-11 21:50:49 +03:00
Fringg
ee2e79db31 refactor: remove modem functionality from classic subscriptions
Remove all modem purchase/management code:
- Delete modem handler, service, and tests
- Remove modem button from keyboards and admin panel
- Remove modem pricing from calculations
- Remove modem REST API endpoint and schemas
- Remove modem decorator, config settings, and notification formatting
- Keep DB column and migration for backwards compatibility
2026-02-11 21:14:08 +03:00
Fringg
90d9df8f0e fix: preserve payment initiation time in transaction created_at
Transaction created_at and completed_at showed identical timestamps
because webhook handlers created transactions with is_completed=True
in a single step. Now all 10 payment providers pass payment.created_at
to the transaction so created_at reflects when the user initiated
the payment, not when the webhook processed it.

Also: remove duplicate datetime import in inline.py, upgrade button
stats DB error logging from debug to warning, add index on
button_click_logs.button_type for analytics queries.
2026-02-10 04:26:23 +03:00
Ali Morshedzadeh
5482e609f8 Add initial Persian locale support and language handling updates 2026-02-09 16:53:50 +03:30
Egor
3ebbb42096 Update inline.py 2026-02-04 02:57:12 +03:00
Egor
3dbaf99733 Update inline.py 2026-02-02 05:26:09 +03:00
Egor
7d9d1b0a6f Update inline.py 2026-02-01 17:16:28 +03:00
Egor
1bb5ef85aa Update inline.py 2026-01-31 17:04:59 +03:00
c0mrade
9a2aea038a chore: add uv package manager and ruff linter configuration
- Add pyproject.toml with uv and ruff configuration
- Pin Python version to 3.13 via .python-version
- Add Makefile commands: lint, format, fix
- Apply ruff formatting to entire codebase
- Remove unused imports (base64 in yookassa/simple_subscription)
- Update .gitignore for new config files
2026-01-24 17:45:27 +03:00
gy9vin
7aa64521d2 feat(payments): добавить KassaAI как отдельную платёжную систему
Новая платёжка KassaAI (api.fk.life) работает параллельно с Freekassa.

  Добавлено:
  - app/services/kassa_ai_service.py — API-сервис
  - app/database/crud/kassa_ai.py — CRUD-операции
  - app/services/payment/kassa_ai.py — KassaAiPaymentMixin
  - app/handlers/balance/kassa_ai.py — хендлеры пополнения

  Изменено:
  - config.py — настройки KASSA_AI_*
  - models.py — PaymentMethod.KASSA_AI, модель KassaAiPayment
  - payment_service.py — подключён KassaAiPaymentMixin
  - webserver/payments.py — webhook /kassa-ai-webhook
  - keyboards/inline.py — кнопка KassaAI
  - handlers/balance/main.py — регистрация хендлеров
  - universal_migration.py — миграция таблицы kassa_ai_payments
  - system_settings_service.py — настройки в админке
  - .env.example — примеры переменных

  Способы оплаты: 44=СБП, 36=Карты РФ, 43=SberPay
2026-01-20 19:09:27 +03:00
Egor
2090da3603 Update inline.py 2026-01-12 16:30:24 +03:00
Egor
7c4471a510 Update inline.py 2026-01-12 15:48:51 +03:00
Egor
42978e2a37 Update inline.py 2026-01-12 15:27:37 +03:00
Egor
b2577d5973 Update inline.py 2026-01-11 04:09:19 +03:00
Egor
2c4b77ff8c Update inline.py 2026-01-10 21:05:58 +03:00
Egor
e6676720f2 Update inline.py 2026-01-10 20:57:49 +03:00
Egor
e66944e2bf Update inline.py 2026-01-10 20:29:53 +03:00
gy9vin
3299d47b11 merge: resolve conflict in universal_migration.py 2026-01-07 15:05:14 +03:00
gy9vin
4afefcafa4 Добавлена система вывода реферального баланса
Новая функциональность вывода средств:
  - config.py: добавлены настройки вывода (минимальная сумма, кулдаун, анализ подозрительности, тестовый режим)
  - models.py: добавлена модель WithdrawalRequest с полями для заявок, анализа рисков и обработки админ
2026-01-07 14:54:50 +03:00
Egor
61fe7f0be4 Update inline.py 2026-01-07 03:49:31 +03:00
Egor
6c0c3f1b79 Update inline.py 2026-01-07 03:03:55 +03:00
Egor
e48ebca91e Update inline.py 2026-01-07 02:55:26 +03:00
Egor
738216cf9f Add tariff change button for tariff mode 2026-01-07 02:21:15 +03:00
Egor
e9ce583eb2 Add files via upload 2026-01-06 20:59:02 +03:00
gy9vin
ff51a984ef fix Параметризация callback_data в get_back_keyboard + поддержка модема в уведомлениях
1. app/keyboards/inline.py
  - Добавлен параметр callback_data: str = "back_to_menu" в get_back_keyboard()
  - Позволяет использовать кнопку "Назад" с разными callback'ами

2. app/services/admin_notification_service.py
  - Добавлен тип "modem" в update_types с заголовком "📡 ИЗМЕНЕНИЕ МОД
2025-12-31 10:16:14 +03:00
Egor
5918f296ff Update inline.py 2025-12-30 18:33:18 +04:00
Egor
63ec894615 Update inline.py 2025-12-30 18:11:56 +04:00
gy9vin
cad9abd8bd feat(payments): умная автоактивация подписки после пополнения + округление цен
Добавлена функция умной автоактивации подписки после пополнения баланса:

  - Новая настройка AUTO_ACTIVATE_AFTER_TOPUP_ENABLED в .env
  - Функция auto_activate_subscription_after_topup() в subscription_auto_purchase_service.py:
    - Автоматически продлевает истёкшую подписку с теми же параметрами
    - Создаёт новую подписку с дефолтными параметрами если подписки нет
    - Проверяет достаточность баланса перед активацией
    - Интеграция с RemnaWave API
    - Уведомления пользователю и админам

  - Интеграция во все 9 платёжных провайдеров:
    - Stars, CryptoBot, YooKassa, CloudPayments
    - WATA, Platega, Pal24, MulenPay, Tribute

  - Исправлен handle_activate_button в menu.py:
    - Полная переработка с интеграцией RemnaWave
    - Корректная работа с балансом и транзакциями
    - Использование SubscriptionRenewalService

  Добавлено округление цен при отображении:

  - Новая настройка PRICE_ROUNDING_ENABLED в .env
  - Логика: ≤50 коп → вниз, >50 коп → вверх
  - Применяется везде: пополнения, партнёрки, скидки, промогруппы
2025-12-26 23:38:46 +03:00
gy9vin
bf9728352e feat(subscription): улучшение UX выбора серверов и устройств
- Кнопки устройств теперь в один столбец (вместо 2 колонок)
  - Автоматический предвыбор бесплатных серверов (price_kopeks == 0)
  - Вывод описания сквадов в тексте сообщения над кнопками

  Изменённые файлы:
  - keyboards/inline.py: get_devices_keyboard в 1 столбец
  - handlers/subscription/countries.py: хелперы _get_preselected_free_countries и _build_countries_selection_text
  - handlers/subscription/purchase.py, traffic.py, autopay.py: применение новой логики
2025-12-26 22:15:34 +03:00
Mikhail
fb9405cccd Merge branch 'BEDOLAGA-DEV:main' into main 2025-12-25 23:56:04 +03:00
Egor
a59a15af7f Update inline.py 2025-12-25 21:07:42 +03:00
gy9vin
0538d0e337 feat(traffic): улучшение системы докупки и сброса трафика
- Добавлен ENV переключатель TRAFFIC_TOPUP_ENABLED для вкл/выкл докупки
- Добавлена отдельная конфигурация пакетов TRAFFIC_TOPUP_PACKAGES_CONFIG
- Добавлено поле purchased_traffic_gb для отслеживания докупленного трафика
- Добавлены режимы расчета цены сброса (period/traffic/traffic_with_purchased)
- Исправлен абьюз: цена сброса теперь учитывает докупленный трафик
- Сброс purchased_traffic_gb при продлении/покупке подписки
- UX: меню сброса теперь показывает цену и баланс вместо alert
- UX: кнопка пополнения если не хватает средств на сброс
- Добавлена миграция для нового поля purchased_traffic_gb
- Добавлена локализация TRAFFIC_TOPUP_DISABLED (ru/en/ua/zh)
2025-12-25 14:48:24 +03:00
gy9vin
90c3df6331 Добавлен функционал подключения модема к подписке
Изменения:
- Добавлены настройки модема в .env.example и config.py (MODEM_ENABLED, MODEM_PRICE_PER_MONTH, MODEM_PERIOD_DISCOUNTS)
- Добавлено поле modem_enabled в модель Subscription
- Реализован модуль handlers/subscription/modem.py с обработчиками подключения/отключения модема
- Добавлено управ
2025-12-25 14:26:15 +03:00
Egor
f1be66d1a5 Update inline.py 2025-12-23 20:35:42 +03:00
Egor
63a9c1afd1 Update inline.py 2025-12-23 16:09:58 +03:00
Egor
65da3a57a7 Update inline.py 2025-12-22 19:32:36 +03:00
Egor
42759854c2 Use timezone-aware datetime for calculations 2025-12-21 08:07:31 +03:00
Egor
bc6e57765e Use UTC for registration days calculation 2025-12-21 07:18:31 +03:00
PEDZEO
10bc00d429 Merge pull request #2174 from BEDOLAGA-DEV/buttons
Buttons
2025-12-20 02:55:59 +03:00
PEDZEO
5fa627bd7f Refactor subscription days calculation and update autopay property naming in main menu keyboard 2025-12-20 02:31:52 +03:00