Files
remnawave-bedolaga-telegram…/CHANGELOG.md
T
2026-04-18 00:58:34 +00:00

250 KiB
Raw Blame History

Changelog

3.49.0 (2026-04-18)

New Features

  • integrate AuraPay payment provider (9717936)

Bug Fixes

  • add missing RollyPay CRUD wrappers and guest payment flow (0f814be)
  • align campaign top registrations revenue with period comparison (16bc1d4)
  • handle edge case when all tariffs are daily in legacy renewal (29877fc)
  • rate-limit daily subscription insufficient balance notifications to 6 hours (ecc4a61)
  • redirect legacy users without tariff to tariff selection on renewal (5986c00)
  • register PayPear and RollyPay in admin panel settings (2aa5927)

Documentation

  • add AuraPay to README with partner block (25ea5c6)
  • add PayPear and RollyPay to README with partner blocks (1c696c6)
  • add PayPear and RollyPay to README with partner blocks (b531959)

3.48.0 (2026-04-16)

New Features

  • integrate PayPear payment provider (a18f6ca)
  • integrate RollyPay payment provider (SBP via USDT) (ccc2f4e)

Bug Fixes

  • increase nalogo receipt queue retry window to 12 hours (92eaf45)
  • low balance alerts disabled by default, add quiet hours, expiry filter, top-up button (2d5afe5)
  • show menu buttons for limited (traffic exhausted) subscriptions (0c54549)
  • show menu buttons for limited subscriptions in back-to-menu paths (61cf495)
  • support payment_method selection for RollyPay (sbp/card/crypto) (a598582)

Documentation

  • add SEVERPAY, PAYPEAR, ROLLYPAY to .env.example (25447ed)

3.47.0 (2026-04-15)

New Features

  • multi-tariff sync fix, daily discount fix, campaign links, TELEGRAM_API_URL (4db9e85)

3.46.1 (2026-04-13)

Bug Fixes

  • add checkfirst guards to cabinet_refresh_tokens migration (8587f03)
  • add missing migration for cabinet_refresh_tokens table (4707cdf)
  • cabinet_refresh_tokens migration + notification_settings jsonb (0274738)
  • change notification_settings from json to jsonb for DISTINCT compatibility (e74fda9)

3.46.0 (2026-04-13)

New Features

  • add broadcast category (system/news/promo) + filter recipients by user prefs (931abfe)
  • add category field to broadcast API schemas and routes (0300044)
  • add RemnaWave retry queue for failed API calls (BUG-2, BUG-10) (abdf296)
  • add remnawave_resync_service for identity-change sync (b57f185)
  • add traffic % warning check using user's threshold preference (1d96f80)
  • add user notification preferences helper utility (e0e2edf)
  • implement low balance alert + respect user notification preferences (4e50419)
  • respect user subscription_expiry notification preferences (63fdfe4)
  • respect user traffic_warning notification preference in webhook handler (7208a52)
  • save campaign_slug during standalone email registration (a8e2b62)
  • start RemnaWave retry queue on app startup (8f1882f)

Bug Fixes

  • add retry queue to all remaining RemnaWave error handlers (7e920fa)
  • add retry queue to cabinet subscription operation RemnaWave errors (1b376ba)
  • add retry queue to classic mode bot purchase handler (970dc54)
  • add retry queue to daily subscription service RemnaWave errors (65120f0)
  • add retry queue to payment webhook and renewal service RemnaWave errors (91a756a)
  • add TRAFFIC_WARNING_ALERT and LOW_BALANCE_ALERT localization keys to all locales (2321667)
  • always sync squads in auto-purchase renewal (BUG-4) (8542a39)
  • default sync_squads=True in update_remnawave_user (BUG-4) (6aed7d3)
  • enforce max_attempts limit in NaloGO receipt queue (16d9163)
  • enqueue retry on RemnaWave API failure in all purchase flows (BUG-2, BUG-10) (9cb559f)
  • exclude users with active subscriptions from expired broadcast (1eeeb39)
  • handle TelegramBadRequest when deleting old ticket notifications (eb18b3a)
  • match tariff_id when creating subscriptions from panel sync (BUG-11) (646ac4c)
  • protect OAuth users with remnawave_uuid from sync deactivation (BUG-6) (cf19e4e)
  • raise MAX_BUTTONS_PER_ROW to 8 and allow tg:// deep links in menu editor (570af82)
  • resync RemnaWave after account merge (BUG-7) (9c08ce6)
  • resync RemnaWave after Telegram account linking (BUG-1) (d465ccb)
  • sync connected_squads from panel during sync (BUG-5) (35412e9)
  • trial activation fallback to trial-eligible servers when tariff has no squads (BUG-12) + fix misleading button text (be32010)
  • upsert refresh tokens (ON CONFLICT) + periodic cleanup of expired/revoked tokens (fb8d2b3)
  • use 'is not None' for telegram_id in create_user API (BUG-9) (8623521)
  • use MAX_DEVICES_LIMIT instead of hardcoded 10 for device buttons (bc3893b)
  • use update_remnawave_user when UUID exists in tariff_purchase (BUG-3) (a1b6d9b)

3.45.2 (2026-04-08)

Bug Fixes

  • batch bug fixes from user complaints (31adcfd)
  • batch bug fixes from user complaints (78f963b)
  • исправление парсинга черного списка (поддержка '#' и извлечение username) (357d94d)
  • исправление парсинга черного списка (поддержка '#' и извлечение username) (2f71846)

3.45.1 (2026-04-03)

Bug Fixes

  • add missing WEBHOOK_TORRENT_DETECTED mapping + dedup before uniq… (4165eae)
  • add missing WEBHOOK_TORRENT_DETECTED mapping + dedup before unique index in migration 0053 (3b5d5a1)

3.45.0 (2026-04-03)

New Features

  • send torrent blocker notification to user (not just admin) (2f9d003)

Bug Fixes

  • resolve multiple subscription bugs — LIMITED status, trial tariff blocking, traffic reset strategy, classic mode pricing, 100% discount support (9b7ac47)
  • restore missing import + rewrite user.deleted webhook to properly deactivate all subscriptions (819f09a)
  • subscription system bugfixes + torrent notifications + user deletion cleanup (7d24e8d)

3.44.0 (2026-04-02)

New Features

  • add SberPay as KassaAI sub-method (payment_system_id=43) (9d63635)

Bug Fixes

  • address review issues in PR #2829 webhook intentional deletion guard (977950b)
  • autopay failure notifications ignoring 6h cooldown (991f0b4)
  • middleware disables panel VPN for all subs ignoring per-channel settings (f284351)
  • NameError in SeverPay guest payment flow (2d42152)
  • notification sent for non-deactivated subs + webhook race condition (b04157c)
  • Pal24 card/sbp option not passed to API in cabinet balance topup (6713921)
  • prevent nested state saves and None state loss in promo handler (b607993)
  • promo code activation destroys balance input FSM state (2466590)
  • remove non-existent Platega method code 10, rename 11 to Карты (RUB) (033d0da)
  • send telegram_id@telegram.org as email to Kassa AI (3dc72b0)
  • send telegram_id@telegram.org as email to SeverPay (08ca947)

3.43.1 (2026-03-31)

Bug Fixes

  • prevent MissingGreenlet on subscription.tariff lazy load in webhook handlers (72170b3)
  • use subscription-level remnawave_uuid in multi-tariff mode for sync and detail pages (0c284b9)

Documentation

  • add Platega partnership to README, highlight partner payment providers (312cc72)

3.43.0 (2026-03-29)

New Features

  • add Remnawave panel 2.7.0 API support (565c083)
  • add SeverPay support to cabinet balance top-up (092b9f6)
  • add subscription_id to admin sync endpoints for multi-tariff (54a19a9)
  • add tariff identification to all notifications for multi-tariff mode (7dd67e3)
  • add tariff_id to promo codes for trial subscription type (63e4296)
  • api: expose email field in UserResponse (23d1830)
  • DELETE /subscriptions/:id for expired/disabled subscriptions (c27f144)
  • expose MULTI_TARIFF_ENABLED and MAX_ACTIVE_SUBSCRIPTIONS in admin settings (2628012)
  • expose per-inbound traffic breakdown in nodes realtime API (5d173c8)
  • include countryEmoji and providerName in realtime metrics (b59c581)
  • multi-subscription support (1099c52)
  • multi-subscription support (1 user = N subscriptions) (335be66)
  • return is_daily and is_daily_paused in subscription list API (4dd8170)
  • support email/OAuth users in referral editing and add remove endpoints (7f60196)
  • trial lifecycle + purchase-options filter for multi-tariff (048d208)
  • wheel subscription picker for multi-tariff mode (24edfb6)

Bug Fixes

  • accept subscription_id from query param in renew endpoint (consistent with other endpoints) (824d54b)
  • account linking broken in multi-tariff mode (MULTI_TARIFF_ENABLED=true) (2c12a47)
  • account merge no longer nulls transferred subscriptions' remnawave_uuid (b0273dc)
  • add missing ADMIN_PAYMENTS localization keys for ru and en (4f76f53)
  • add period_days validation and zero-price guard to tariff purchase (cefdfc5)
  • add redirect_slashes=False to prevent HTTP 307 redirects on subscription endpoints (f7f8ea8)
  • add selectinload for GuestPurchase.user/tariff in gift activation (84357a1)
  • add tariff identification to remaining notification gaps (cddb8d6)
  • add_traffic handler passes FSM state to resolve_subscription for multi-tariff context (684f286)
  • address remaining review issues in device limit patch (9726145)
  • address review issues in device limit patch (34aec03)
  • admin handlers use _resolve_admin_subscription + per-subscription UUID (147ef6b)
  • admin panel per-subscription UUID in multi-tariff mode (56fffc2)
  • admin server/devices/traffic buttons pass subscription_id in multi-tariff (9a27e6d)
  • admin tariff purchase now creates separate RemnaWave user per tariff (95ba739)
  • assign promo group from tariff on guest purchase (da11ec6)
  • async tariff loading in promocode serialization (3bec662)
  • auto-purchase processes each autopay subscription independently (f89e326)
  • back button in subscriptions list uses correct callback (382e29d)
  • back buttons in devices/traffic return to subscription detail in multi-tariff (319941d)
  • block classic subscription renewal/autopay when tariff mode enabled (cd6913c)
  • block legacy subscription renewal bypass in tariff mode (78209c8)
  • cabinet admin create subscription now creates new RemnaWave user in multi-tariff mode (31c67d1)
  • cabinet purchase_tariff — handle IntegrityError with compensating refund (1bc2581)
  • cabinet routes use smart subscription fallback + per-subscription UUID (f83ff26)
  • centralize trial cleanup in CRUD + shared subscription resolver for bot (355fef8)
  • comprehensive multi-subscription audit fixes across routes, handlers, and services (d071269)
  • comprehensive tariff switch/extend/back button fixes for multi-tariff (e42bddb)
  • contest prize applies to best non-daily subscription in multi-tariff (d2bbeb8)
  • daily tariff switch uses _resolve_subscription instead of searching by new tariff_id (4e12ab3)
  • delete subscription from RemnaWave panel + prevent phantom webhook notifications (a12ffb1)
  • device limit decrease, HWID pagination, tariff max enforcement (931eeb3)
  • devices button shows menu with buy + manage options in multi-tariff (f925efb)
  • disable redirect_slashes globally to prevent HTTP 307 on subscription endpoints (06feb3f)
  • distinguish cabinet gift notifications from landing page (48eaa6b)
  • eligibility and display use best non-daily subscription in multi-tariff (76ba19d)
  • fix MiniApp renewal options 500 error for legacy subscriptions (aa36549)
  • gift code activation and multi-tariff subscription sync (f93c51a)
  • harden node info display against injection and type errors (6d167d2)
  • harden webhook signature verification across all payment providers (8295880)
  • import Subscription in wheel_service to fix NameError (34bb87c)
  • improve UX for legacy users migrating to tariff mode (f6f330d)
  • load buyer relationship before gift notification, clean up recipient logic (adb39c6)
  • multi-subscription support for promocodes, contests, phantom merge (6d468e9)
  • multi-subscription UUID resolution and ownership validation (d87fb47)
  • multi-tariff code review — 13 critical/high bugs fixed across 14 files (5724906)
  • multi-tariff MEDIUM/LOW batch — 20 issues across 17 files (94ed282)
  • multi-tariff Stage 2 critical fixes — panel sync, guest purchase, cart isolation (4259ba1)
  • multi-tariff Stage 2 HIGH fixes — 18 issues across 12 files (c6bedc6)
  • multi-tariff Stage 3 critical fixes — panel sync UUID, admin grant, wheel (49db5f5)
  • multi-tariff Stage 3 HIGH fixes — phantom, cart, yookassa, auto-extend (aa7e461)
  • multi-tariff Stage 4 critical fixes — keyboards, guest purchase, monitoring, tariff deletion (a49e52c)
  • multi-tariff Stage 5 fixes — auth sync, notifications, cart, race guard (948e479)
  • multi-tariff sync auto-links legacy user-level UUIDs to subscriptions (dbe247b)
  • notifications include tariff name for multi-subscription clarity (05d1ae0)
  • parse_bytes now handles IEC units (GiB, MiB, KiB) from API (1471320)
  • pass FSM state to _resolve_subscription across all subscription handlers (90fb0a2)
  • pass sub_id to show_devices_page to fix NameError in multi-tariff (59d4b35)
  • persist referral to Redis on /start to prevent loss when user opens miniapp (6d9bd99)
  • post-payment keyboard checks all subscriptions instead of LIMIT 1 (25b853d)
  • prevent sync from overwriting wrong subscription traffic in multi-tariff mode (78a7eaf)
  • prevent sync/from-panel cross-subscription data mismatch (960aa44)
  • promocode system broken in multi-tariff mode (3cbe09d)
  • re-fetch subscription after lock_user_for_pricing to prevent selectinload reset (71082f4)
  • remnawave service uses per-subscription UUID throughout multi-tariff (afd7b6d)
  • RemnaWave sync finds user by Subscription.remnawave_uuid in multi-tariff (c3c2b81)
  • remove unused imports and variables after rebase (b6cf361)
  • remove user.subscription setter - use local variable instead (2f88b07)
  • remove UUID fallback override in admin_tariffs + restore promo on IntegrityError (a232d21)
  • rename refresh('subscription') to refresh('subscriptions') in all files (e99f3d9)
  • renewal handlers use _resolve_subscription + store subscription_id in FSM (87bf65c)
  • renewal status check, int() safety, daily charge atomicity (58d899a)
  • renumber multi-subscription migrations to avoid conflicts with dev (5a7b3d5)
  • resolve MissingGreenlet error on article detail view (004dac5)
  • services use smart subscription selection + per-subscription UUID (0866c2e)
  • set is_daily_paused=True when admin cancels/disables daily subscription to prevent auto-resume (d04f2fc)
  • show all subscriptions in main menu for multi-tariff mode (e39c358)
  • show subscription picker for traffic/connect buttons with multiple subs (a39e355)
  • suppress empty reward alerts and clean up referral notifications (e3d8d21)
  • tariff purchase shows purchased tariffs and blocks re-buying in multi-tariff (9644135)
  • tariff_purchase next() fallbacks use None instead of active_subs[0] in multi-tariff (72d5bae)
  • test access promo applies to all active subscriptions in multi-tariff (181ef15)
  • transliterate Cyrillic slugs instead of stripping to 'untitled' (c805cfd)
  • trial promo extends existing subscription with same tariff (b8662b8)
  • trial reset in multi-tariff only deletes trial subscriptions, keeps paid (424fff4)
  • trial subscription lifecycle — autopay, cleanup on purchase, bonus days (344852b)
  • use '/' instead of empty path in subscription sub-routers (07ebc43)
  • use empty path instead of '/' for multi-tariff list endpoint to avoid 404 (c8ecec4)
  • UUID check in servers/tariff_switch, start.py refresh, delegation state passing (bd46b4c)
  • UUID warnings, phantom merge, yookassa validation, contest prize notification (fe03b58)
  • validate_and_clean_subscription uses per-subscription UUID in multi-tariff mode, not user-level UUID (18f31c5)
  • web API routes use multi-subscription resolution for operations (a1623d9)

Refactoring

  • remove dead multi-tariff check in guest purchase activation (34b5a9a)
  • update remnawave API integration for v2.7.0 (173cc37)

Documentation

  • add Stage 3+4 audit results to multi-tariff review (6dc5879)
  • update multi-tariff review with Stage 2 full audit results (40d2ec6)

3.42.0 (2026-03-23)

New Features

  • add managed news categories and tags with DB-backed CRUD (51392d1)
  • add media upload/delete API for news articles (a0d40ad)
  • add news articles module with admin CRUD and public API (b932403)
  • enforce single featured news article — unfeature others on toggle/create/update (b5853ec)
  • show Platega payment methods inline on main screen (#2720) (334db53)

Bug Fixes

  • add explicit File(...) to UploadFile param to fix 422 on media upload (89bfdc8)
  • add Literal type to SavedMedia and close orphaned PIL Image objects (ce554cb)
  • add user ID to payment descriptions for all providers and fix tuple bug (2f19c76)
  • catch DecompressionBombError, hoist MP4 brands to module level (172924d)
  • comprehensive html.escape() for all user/admin data in Telegram HTML messages (9de3490)
  • comprehensive security hardening across payment and API layers (8175bc8)
  • correctly price unlimited traffic (0 GB) in classic subscription mode (aec04f0)
  • create uploads subdirectories in Dockerfile for correct permissions (5ed3780)
  • media upload security hardening from 6-agent review (165d25e)
  • news module security hardening, perf optimizations, bug fixes (2b91808)
  • phantom user merge on claim failure, referral assignment, account merge hardening (fad77f8)
  • register categories/tags/media routers before news to avoid route conflict (d9cda3a)
  • reject HEIC as MP4, close UploadFile, narrow exception handling (7ff73e8)
  • remove future annotations breaking UploadFile, harden media URL generation (0225fa1)
  • replace asyncio.gather with sequential queries on shared session (3e69efe)
  • respect per-channel disable_on_leave settings in monitoring service (958ec48)
  • respect X-Forwarded-Proto in media URL generation to prevent mixed content (fd41009)
  • restore connected_squads and admin notification on daily subscription resume (89341ba)
  • simplify 0046 migration downgrade to just drop_table (015c2da)
  • suppress harmless TelegramBadRequest errors and fix discount promo display (0fe3c21)
  • use IF EXISTS in downgrade for FK indexes (76b1f9b)
  • validate FK existence, add FK indexes, expand video brand whitelist (f0cdd5d)
  • validate period_days against tariff in purchase-tariff and auto-purchase (4660ca5)

Refactoring

  • extract phantom service, replace lightweight merge with execute_merge (6658af6)
  • simplify referral invite text to single template (cbe630c)

3.41.0 (2026-03-22)

New Features

  • add subscription status to referral network graph nodes (de91d32)
  • add total subscription revenue to referral network stats (2bdb764)

Bug Fixes

  • add abs() to all remaining subscription payment sum queries (1eb4e18)
  • add missing total_subscription_revenue_kopeks in scoped graph early return (bcc761f)
  • consider subscription status field in network graph (454dc93)
  • superadmin role managed exclusively via env config (e0bedc8)
  • treat expired and limited subscription statuses as inactive in referral network graph (5ed2f0c)
  • use abs() for subscription payment amounts in referral network (056c13b)

Refactoring

  • extract _compute_subscription_status shared helper (8b8f1b9)

3.40.0 (2026-03-22)

New Features

  • allow inactive tariffs for trial subscription activation (cce3b0c)
  • custom broadcast buttons and fix home button to use bot menu (13ea376)

Bug Fixes

  • accept stale Telegram initData to prevent MiniApp auth failures (4c2cb63)
  • daily subscription pause not persisting in cabinet and miniapp (d3c9940)
  • handle spurious user.deleted webhooks — preserve active subscriptions and prevent orphaned panel users (9eab802)
  • prevent MESSAGE_TOO_LONG in promo groups list (c307278)
  • referral system — self-referral protection, race condition fix, deleted user re-registration (ed5a92a)
  • sanitize email dots in RemnaWave username generation (6c20858)
  • send DISABLED instead of EXPIRED status to RemnaWave API (79cfcbc)

3.39.0 (2026-03-21)

New Features

  • add NaloGO fiscal receipts for code-only gift purchases (90209eb)

Bug Fixes

  • add NaloGO fiscal receipt creation for landing page purchases (4244962)
  • manual admin top-ups missing from sales statistics (ab43e74)
  • skip non-JSON payload rows in cryptobot payment index and query (ba79d03)

3.38.0 (2026-03-21)

New Features

  • add SOCKS proxy support for nalogo (tax service) module (3c5bf4f)

Bug Fixes

  • add diagnostic payload logging in create_user error path (4990ddf)
  • retry Remnawave API calls without externalSquadUuid on A039 FK violation (de00612)
  • sanitize proxy credentials in all nalogo error paths (3bf3105)

3.37.0 (2026-03-21)

New Features

  • add SOCKS5 proxy support for Telegram API traffic (82b6a8b)
  • broadcast caption validation + landing daily created stats (d400cd7)
  • expose cabinet_email/password vars in subscription delivered template admin UI (f82a713)
  • include cabinet credentials in subscription delivered email (fedcf25)
  • show both bot and cabinet referral links everywhere (67da390)

Bug Fixes

  • default payment_method to BALANCE for bot subscription payments (226d3f2)
  • derive income_today from revenue_chart to ensure consistency (1882909)
  • include landing page revenue in dashboard statistics (c6c1599)
  • include SUBSCRIPTION_PAYMENT in dashboard revenue (5f71eaa)
  • include SUBSCRIPTION_PAYMENT in dashboard revenue calculations (13dba5a)
  • include SUBSCRIPTION_PAYMENT in dashboard revenue calculations (d7f91c8)
  • include SUBSCRIPTION_PAYMENT in recent payments today/week totals (6982d27)
  • include SUBSCRIPTION_PAYMENT in sales summary and deposits stats (27ef752)
  • increase landing purchase rate limit from 5 to 30 req/min (801921f)
  • narrow exception handling and fix session leak in gift.py (3875335)
  • prevent bootstrap from reactivating revoked superadmin roles (9dd6b54)
  • prevent double balance credit on concurrent Platega webhooks (0e1296e)
  • prevent double-payment TOCTOU race in all payment providers (82c79c1)
  • resolve EmailService stale SMTP config causing NoneType crash on from_email (2a72dea)
  • resolve remaining TOCTOU issues in RioPay, SeverPay and restore paid_at (afefcc9)

Refactoring

  • centralize Bot instantiation via create_bot() factory (0a53b85)

3.36.1 (2026-03-20)

Bug Fixes

  • handle duplicate admin roles in RBAC bootstrap (877b1cd)
  • make migration 0042 idempotent for retry_count column (5faf701)

3.36.0 (2026-03-20)

New Features

  • add media attachment support for admin ticket replies (69bb399)
  • add multi-provider recovery, retry_count, amount verification, and indexes (3d78974)
  • add partner → campaign edges to referral network graph (01132a7)
  • add referral network graph visualization admin API (c08c903)
  • add scoped referral network graph with scope selector API (df086b0)
  • multi-select scope for referral network graph API (6a4ce3d)

Bug Fixes

  • address review findings for guest purchase recovery (57c5c67)
  • address review findings for multi-provider recovery (79c110f)
  • allow repeated auto-assignment of promo groups on each purchase (4a002b7)
  • correct revenue calculations in referral network (c8f4cca)
  • improve referral network query correctness and cleanup (ac9fcd8)
  • prevent duplicate promo groups during auto-assignment after purchase (da7a9cc)
  • prevent guest purchases from getting stuck in PENDING/FAILED status (2781236)
  • prevent premature commits in promocode promo group operations (8b26680)
  • propagate exceptions from get_primary_user_promo_group (3ec9e71)
  • use 'kassa_ai' base model name for guest metadata patch (182667e)
  • use base model name for KassaAI guest metadata patch (b6d4373)

Performance

  • add covering indexes for referral network queries (b5471b7)

3.35.0 (2026-03-18)

New Features

  • add user_email to admin payments API response (7101555)
  • include manual admin top-ups in sales statistics revenue (b80eeea)
  • раздельные топики для админских уведомлений (e15b18f)

Bug Fixes

  • fix Platega and CryptoBot webhook verification (b40a812)
  • handle None autopay_days_before in autopayment processing (f1d4534)
  • remove forced white background from custom email template overrides (cb61014)
  • undefined currency variable in RioPay payment creation (5b33534)

3.34.1 (2026-03-18)

Bug Fixes

  • add null check for subscription in execute_change_devices (5081deb)
  • correct CryptoBot webhook signature verification and auto-fill topup amount from cart (d7ad9d7)
  • correct RioPay API header case and remove undocumented fields (1a87d43)
  • disable quick amount buttons in balance topup (d0eab3f)
  • reset device limit to new tariff base on tariff switch (aec01ce)
  • sync crypto link from happ.cryptoLink in webhook handlers (0ceff44)

Refactoring

  • remove quick amount buttons feature entirely (136f29c)

Documentation

  • add bot preview screenshot to README (d7931a2)
  • add cabinet preview screenshot to README (b032c8f)
  • add icons and list all 14+1 payment providers (1306c24)
  • add Redis to tech stack (c14d7ab)
  • add Redis to tech stack (e12cc9f)
  • add WATA partnership block to payments section (31bdf8a)
  • increase logo size to 800px (22e7f15)
  • redesign README — concise feature showcase, link to docs (38deb70)
  • replace header logo with new artwork (6888822)
  • WATA partnership block with logo and table card (8d5a002)

3.34.0 (2026-03-18)

New Features

  • добавлен SeverPay в админ-панель и настройки кабинета (06a00e3)
  • добавлена интеграция SeverPay для пополнения баланса (abaf279)
  • поиск платежей в админ-панели с фильтрами и статистикой (1804c28)

Bug Fixes

  • remove contains_eager conflicting with selectinload on user relationship (fddf8ef)
  • добавлен импорт MAX_ALL_TIME_DAYS в admin_payments routes (ad26832)
  • добавлены RioPay и SeverPay в REAL_PAYMENT_METHODS (f967c29)

3.33.0 (2026-03-17)

New Features

  • add SBP and Card sub-options for KassaAI payment method (5b722c5)
  • add SBP and Card sub-options to kassa_ai payment method (04419fd)
  • deep link авторизация в кабинете при блокировке oauth.telegram.org (322d457)
  • добавлена поддержка RioPay в кабинете (3d1fbc7)
  • добавлена поддержка RioPay для лендингов и подарков (04f4e6b)

Bug Fixes

  • add back button to payment amount validation errors (20eff61)
  • add sync_squads=True to admin tariff change handler (3f0b24c)
  • deep link auth security and reliability fixes (099391e)
  • enforce promo group authorization on country/server selection (641da94)
  • merge phantom users into active accounts on /start (77f1a76)
  • MissingGreenlet crash after subscription purchase in cabinet (a80a85c)
  • MissingGreenlet crash after subscription purchase in cabinet (1cc687a)
  • MissingGreenlet при изменении количества устройств на CLASSIC подписках (826accb)
  • protect external squads from deletion during server sync (b563796)
  • review findings — db.commit, isinstance guard, constants, ACTIVE check (72b5305)
  • sub-method enabled check, guest payment provider, silent FSM return (603b9a1)
  • subscription: remove stale extend promo state fields causing NameError (20a6fa1)
  • swap Caddy auth headers — api_key to Authorization, caddy_token to X-Api-Key (038c34e)
  • sync squads to Remnawave panel on tariff purchase/switch (c34fdd1)
  • защита внешних сквадов от удаления при синхронизации серверов (f84885c)
  • исправлен расчёт конверсии в статистике продаж (3089c17)
  • исправлены проблемы RioPay интеграции после ревью (4abb8cb)
  • миграция Tribute webhook с deprecated user_id на trb_user_id (9419941)
  • скрыть плашку верификации email при выключенной верификации (4966e39)

Refactoring

  • deduplicate KassaAI handlers with config dict and shared helpers (e4bb043)
  • move KASSA_AI_SUB_METHODS to service layer, add early enabled checks (cda2392)

3.32.4 (2026-03-16)

Bug Fixes

  • лог полного payload при ошибке PATCH /api/users для диагностики A039 (8d7f0ee)
  • не пересылать activeInternalSquads в рутинных обновлениях RemnaWave (A039) (4aaf0dd)
  • не пересылать externalSquadUuid в рутинных обновлениях RemnaWave (3d68db0)
  • расширен лог PATCH /api/users payload для диагностики A039 (db2f0c9)
  • режим «Контакт и тикеты» возвращает support_type='both' вместо 'tickets' (2f33e55)
  • реферальный бонус инвайтера — сумма вместо максимума, защита флага первого пополнения (e1bcb1b)
  • сохранение user_id до rollback чтобы избежать MissingGreenlet при lazy load (3f8e899)
  • убрана отправка externalSquadUuid=null в RemnaWave API и исправлен ложный лог синхронизации рулетки (f80912e)
  • уведомление об истечении подписки теперь учитывает autopay_enabled пользователя (c0b282a)
  • устранена отправка externalSquadUuid=null в RemnaWave API (A039) и исправлен reduce_devices (e453521)

Refactoring

  • централизация всех расчётов цен в PricingEngine (8d3cd50)

3.32.3 (2026-03-14)

Bug Fixes

  • campaign registration, revenue calculation, backup restore, autopay errors, referral links (7648707)
  • implement case-insensitive email checks in authentication and user retrieval (7e466ef)
  • implement case-insensitive email checks in authentication and user retrieval (ebee834)
  • payment: prioritize saved cart after topup over expired auto-extend (28321df)
  • refresh CLASSIC_PERIOD_PRICES when admin changes PRICE_*_DAYS or SALES_MODE (6adf70b)

3.32.2 (2026-03-13)

Bug Fixes

  • add nested selectinload and referrer eager loading to prevent MissingGreenlet (3306e02)
  • add selectinload to user lock queries to prevent MissingGreenlet (5442f28)
  • silence PARTICIPANT_ID_INVALID error in channel subscription check (14dceaa)

3.32.1 (2026-03-13)

Bug Fixes

  • invalid ISO date format in node usage stats API call (69a38da)
  • platega webhook ID fallback for SBP and card payments (aa3459b)
  • resolve MissingGreenlet in switch_tariff endpoint (4d695be)

3.32.0 (2026-03-13)

New Features

  • add _calculate_servers_price (fixed fallback) and _calculate_traffic_price (88369ee)
  • add CLASSIC_PERIOD_PRICES to config (c3bb63f)
  • add LIMITED subscription status and preserve extra devices on tariff switch (8f43452)
  • add RenewalPricing dataclass and PricingEngine discount methods (83ca51c)
  • implement calculate_renewal_price with tariff and classic modes (02e5401)

Bug Fixes

  • add missing settings import in admin_users tariff switch (b2ee6c7)
  • add per-category discounts and months multiplier to classic mode (1660b24)
  • add period_days whitelist validation and type annotations (18e2e78)
  • address 6-agent review findings for PricingEngine (c9f2dff)
  • address review findings from 5-agent audit (08bea70)
  • atomicity refactor, review fixes, and DELETED recovery logging (ba54819)
  • change None assignment to [] + add "or []" guards at all 5 call sites. (a5fbd74)
  • downgrade known-harmless RemnaWave 400s to warning level (0419781)
  • guard rollback on commit flag, add flush to promo_offer_log (b7775b7)
  • handle legacy telegram_id in YooKassa webhook recovery metadata (815a1d9)
  • harden remnawave API error handling and YooKassa user cross-validation (585baaf)
  • harden YooKassa webhook recovery user lookup (d35ee58)
  • payment providers — lock_user_for_update + commit=False atomicity (b4ef52c)
  • prevent balance loss on auto-purchase for DISABLED subscriptions and fix WATA expiration (266340a)
  • pricing audit — display/charge parity, race conditions, balance locks (ae99358)
  • resolve merge conflict with dev (accept calc_device_limit_on_tariff_switch) (ba049ca)
  • user deletion FK error + connected_squads None TypeError (a5fbd74)

Refactoring

  • add typed breakdowns + module-level singleton to PricingEngine (b551def)
  • extract shared formatting helpers into app/utils/formatting.py (5e9a462)
  • make finalize() accept both old and new pricing types (3efa24b)
  • migrate admin user price calculation to PricingEngine (49c0f3f)
  • migrate all callers to pricing_engine singleton + fix miniapp discount (e24b911)
  • migrate bot renewal display to PricingEngine (ce82c2c)
  • migrate bot renewal execute to PricingEngine (acf27a1)
  • migrate cabinet renewal display + execute to PricingEngine (28fc36d)
  • migrate cart auto-purchase to PricingEngine (fresh calc) (bd2e93a)
  • migrate menu.py renewal pricing to PricingEngine (652b6da)
  • migrate miniapp renewal display + execute to PricingEngine (cb43aca)
  • migrate recurrent and monitoring services to PricingEngine (978f68e)
  • migrate remaining callers to PricingEngine + cleanup dead CRUD (75dbd2b)
  • migrate try_auto_extend_expired to PricingEngine (e6ebc67)
  • remove dead pricing code and fix miniapp classic mode (c9a9816)
  • unify first-purchase discount algorithm with PricingEngine (fe4e6ac)

3.31.0 (2026-03-12)

New Features

  • add show_in_gift toggle for tariffs in admin panel (cb5126a)
  • add sync-squads endpoint for bulk updating subscription squads in Remnawave (b1e2146)
  • auto-sync squads to Remnawave when admin updates tariff (076290e)
  • referral links now point to web cabinet instead of bot (12ae871)

Bug Fixes

  • add post_update=True to User.referrals self-referential relationship (9957259)
  • add Telegram Stars payment support for gift subscriptions (5424d8c)
  • correct skipped_count in sync-squads circuit breaker and simplify ternary (8a362db)
  • preserve purchased devices when admin changes user tariff (bf72f24)
  • prevent account takeover via auto_login_token, ensure promo group on all purchase paths (b3f3eba)
  • reactivate subscription after traffic top-up when status is EXPIRED (8b35428)
  • update promo group via M2M table so admin changes persist (68bc8eb)

Refactoring

  • remove estimated price from balance, simplify server sync, fix HTML injection (a798f11)

3.30.0 (2026-03-11)

New Features

  • add gifts section to admin user detail API (bca8bab)
  • add promo group and promo offer discounts to gift subscriptions (2fd0f6a)

Bug Fixes

  • record transactions for free tariff switches and admin tariff changes (864a4ed)
  • reset subscription for paid users, trial-to-paid tariff conversion, gift purchase MissingGreenlet (e67b8e4)
  • use keyword args for Path.mkdir in asyncio.to_thread (2879996)

3.29.0 (2026-03-10)

New Features

  • gift subscription code-only purchase + activation via deep link (5ffce17)
  • prevent self-activation of gift codes (b30c73c)

Bug Fixes

  • 3 bugs — notification type, referral with channel sub, BOT_USERNAME (3c96c2a)
  • 3 critical issues from second-round review (a90d2d9)
  • add minimum 8-char length check for gift token in bot deep link (8a8337f)
  • address review findings from 6-agent audit (5c34656)
  • code-only gifts skip fulfillment in gateway webhook + retry service (05bcac5)
  • panel sync now updates end_date in both directions (def594b)
  • pass full token to svc_activate instead of truncated prefix (38c6adf)
  • refresh user subscription after gift activation in /start (363ccce)
  • remove begin_nested that breaks activate_purchase transaction (0005d59)
  • stars rate rounding + device/traffic purchase stats (641ff86)
  • support prefix-based gift code lookup for activation (4fb72ae)

Refactoring

  • deduplicate gift activation in start.py (769d3a0)
  • rename GIFTCODE_ start parameter prefix to GIFT_ (42b6c80)

3.28.1 (2026-03-10)

Bug Fixes

  • migrate pricing to days-based proration, fix promo revenue leaks, fix admin panel bugs (fcdeff1)

3.28.0 (2026-03-09)

New Features

  • add cabinet gift subscription API routes and schemas (6a61b09)
  • add cabinet menu layout editor with row arrangement, custom URL buttons, and drag-and-drop reordering (dd8d7f6)
  • add CABINET_GIFT_ENABLED branding toggle (759bfe1)
  • add open_in setting for custom buttons (external browser / webapp) (497a8ee)
  • add source and buyer_user_id fields to GuestPurchase model (0936d4a)
  • implement gateway payment for gifts, persist recipient warning (cd04f3b)

Bug Fixes

  • enforce HTTPS for webapp mode, deduplicate keyboard builder, fix long line (69dbd6a)
  • harden gift subscription feature after multi-agent review (6a4140e)
  • loyalty tiers current status based on spending, not assigned group (b815abf)
  • negate GIFT_PAYMENT amounts and remove dead code (f80b058)
  • normalize threshold 0→NULL in create_promo_group for consistency (b9089e6)
  • payment gateway issues — YooKassa polling, PAL24 card 500 (95a32e8)
  • support Telegram OIDC id_token in account linking endpoint (680c22c)

3.27.0 (2026-03-09)

New Features

  • auto-resume disabled daily subscriptions on balance topup (770b31d)

Bug Fixes

  • add method query param to return_url and latest-payment endpoint (32d58b0)
  • add table existence guards to migrations for optional payment tables (f4a7763)
  • admin tariff server selection - 64-byte overflow and callback routing conflicts (536525c)
  • align tariff pricing with calculate_renewal_price reference (6349b2f)
  • conditional log messages and sanitize panel_error in user deletion (289cbe9)
  • encode payment status in provider return URLs and wire failed_url (275f249)
  • enforce tariff device_price and max_device_limit across all purchase paths (f9f07f3)
  • keep DB session alive in Tribute payment notification handler (4186159)
  • latest-payment endpoint returns all payments, not just pending (7a9264b)
  • pass cabinet return_url to payment providers for top-up redirects (7ca9619)
  • propagate tariff squad changes to existing subscriptions and fix user deletion from Remnawave (7ccfb66)
  • renewal cost estimate double-counts servers and traffic in tariff mode (bfbefeb)
  • resolve concurrent AsyncSession bug and sanitize error responses (4a5cacd)
  • use parsed HTML length for Telegram caption limit checks (2649e12)

Refactoring

  • move squad propagation to service layer with parallel Remnawave sync (79161ea)

3.26.0 (2026-03-08)

New Features

  • add telegram gift notification with inline activation button (9ba61a0)

Bug Fixes

  • auto-purchase classic extend missing device_limit and traffic_limit_gb (7dc5e4a)
  • gift purchase notification and activation flow (330d1cb)
  • multiple payment and notification bugs (f4eeb9a)
  • quick topup buttons include device/server/traffic costs, broadcast button crash on media messages (5ebe107)
  • remove is_active_paid_subscription guard from admin deactivation (1f664a9)
  • respect send_before_menu flag for pinned messages during new user registration (20727b1)

3.25.0 (2026-03-07)

New Features

  • add configurable animated background for landing pages (11d3e63)
  • add landing page statistics endpoint with charts data (25478ce)
  • add paginated purchases list endpoint for landing pages (0ba1127)

Bug Fixes

  • add or [] guard to remaining connected_squads call site in fulfill_purchase (d9f9f3d)
  • align context_vars and SAMPLE_CONTEXTS with actual runtime context keys (ab5313a)
  • align subscription_renewed/activated context_vars with runtime keys (c507634)
  • correct device_limit and connected_squads in guest purchase fulfillment (44d46fe)
  • drop legacy prize_days column from contest_templates (5214f55)
  • handle expired subscription in guest purchase fulfillment (9e78509)
  • remaining context_vars/SAMPLE_CONTEXTS mismatches found by agents (d72ea6b)
  • resolve alembic migration failures on fresh database install (bbd353f)
  • resolve NameError in YooKassa successful payment processing (9d5329d)
  • strip newlines from subject substitution, fix subscription notification context (c9ea2b1)
  • substitute context variables in email template overrides (d52c87b)
  • substitute sample context in admin test email for template overrides (351d714)
  • support {total_amount} placeholder in cart notification templates (f4ab174)
  • use --frozen instead of --locked in Dockerfile to avoid version mismatch (923b36a)
  • use information_schema for constraint existence checks in migrations (fc65e2d)
  • use pg_class lookup for constraint existence checks in migrations (ba335fe)

3.24.0 (2026-03-07)

New Features

  • account linking and merge system for cabinet (dc7b8dc)
  • account merge system — atomic user merge with full FK coverage (2664b49)
  • add 'default' (no color) option for button styles (10538e7)
  • add admin campaign chart data endpoint with deposits/spending split (fa7de58)
  • add admin notifications for partner applications and withdrawals (cf7cc5a)
  • add admin partner settings API (withdrawal toggle, requisites text, partner visibility) (6881d97)
  • add admin sales statistics API with 6 analytics endpoints (58faf9e)
  • add admin topic notifications for landing page purchases (dbb9757)
  • add all remaining RemnaWave webhook events (node, service, crm, device) (1e37fd9)
  • add button style and emoji support for cabinet mode (Bot API 9.4) (bf2b2f1)
  • add cabinet admin API for pinned messages management (1a476c4)
  • add campaign_id to ReferralEarning for campaign attribution (0c07812)
  • add ChatTypeFilterMiddleware to ignore group/forum messages (25f014f)
  • add close button to all webhook notifications (d9de15a)
  • add daily deposits by payment method breakdown (d33c5d6)
  • add daily device purchases chart to addons stats (2449a5c)
  • add dedicated sales_stats RBAC permission section (8f29e2e)
  • add desired commission percent to partner application (7ea8fbd)
  • add discount system for landing pages (aa7d986)
  • add external squad support for tariffs (c10d678)
  • add GET /admin/rbac/users endpoint for listing all RBAC users (8b77cda)
  • add granular user permissions (balance, subscription, promo_group, referral, send_offer) (60c4fe2)
  • add landings to permission registry (c93dbec)
  • add lite mode functionality with endpoints for retrieval and update (7b0403a)
  • add LOG_COLORS env setting to toggle console ANSI colors (27309f5)
  • add MULENPAY_WEBSITE_URL setting for post-payment redirect (fe5f5de)
  • add multi-channel mandatory subscription system (8375d7e)
  • add partner system and withdrawal management to cabinet (58bfaea)
  • add per-button enable/disable toggle and custom labels per locale (68773b7)
  • add per-channel disable settings and fix CHANNEL_REQUIRED_FOR_ALL bug (3642462)
  • add per-section button style and emoji customization via admin API (a968791)
  • add Persian (fa) locale with complete translations (29a3b39)
  • add POST /auth/telegram/oidc endpoint for OIDC popup flow (3a400d9)
  • add quick purchase email templates to admin panel (6970340)
  • add RBAC + ABAC permission system for admin cabinet (3fee54f)
  • add referral code tracking to all cabinet auth methods + email_templates migration (18c2477)
  • add RemnaWave incoming webhooks for real-time subscription events (6d67cad)
  • add required channels button to admin settings submenu in bot (3af07ff)
  • add RESET_TRAFFIC_ON_TARIFF_SWITCH admin setting (4eaedd3)
  • add resource_type and request body to audit log entries (388fc7e)
  • add separate Freekassa SBP and card payment methods (0da0c55)
  • add server-complete OAuth linking endpoint for Mini App flow (f867989)
  • add startup warnings for missing HAPP_CRYPTOLINK_REDIRECT_TEMPLATE and MINIAPP_CUSTOM_URL (476b89f)
  • add sub_options support for landing page payment methods (220196f)
  • add Telegram account linking endpoint with security hardening (da40d56)
  • add Telegram OIDC id_token validation and code exchange (2f0a9dc)
  • add TELEGRAM_OIDC_* settings for new Telegram Login (833df51)
  • add validation to animation config API (a15403b)
  • add web admin button for admins in cabinet mode (9ac6da4)
  • add web campaign links with bonus processing in auth flow (d955279)
  • allow editing system roles (f6b6e22)
  • allow tariff deletion with active subscriptions (ebd6bee)
  • attribute campaign registrations to partner for referral earnings (767e965)
  • blocked user detection during broadcasts, filter blocked from all notifications (10e231e)
  • capture query params in audit log details for all requests (bea9da9)
  • colored channel subscription buttons via Bot API 9.4 style (0b3b2e5)
  • colored console logs via structlog + rich + FORCE_COLOR (bf64611)
  • configurable Telegram Login Widget with admin settings (084a3cd)
  • enforce 1-to-1 partner-campaign binding with partner info in campaigns (366df18)
  • enhance sales stats with device purchases, per-tariff daily breakdown, and registration tracking (31c7e2e)
  • expose oidc_enabled and oidc_client_id in telegram-widget config (000b0c0)
  • expose payment sub-options with labels in public landing API (c53e9af)
  • expose traffic_reset_mode in subscription response (59383bd)
  • expose traffic_reset_mode in tariff API response (5d4a94b)
  • guest purchase → cabinet account integration (f8edfd7)
  • guest purchase delivery & activation system (776fc3a)
  • handle errors.bandwidth_usage_threshold_reached_max_notifications webhook (8e85e24)
  • handle service.subpage_config_changed webhook event (43a326a)
  • include partner campaigns in /partner/status response (ea5d932)
  • link campaign registrations to partner for referral earnings (c4dc43e)
  • localization: add Persian (fa) locale support and wire it across app flows (cc54a7a)
  • notify users on partner/withdrawal approve/reject (327d4f4)
  • register TELEGRAM_OIDC category, hints in admin settings (3a36162)
  • rename MAIN_MENU_MODE=text to cabinet with deep-linking to frontend sections (ad87c5f)
  • replace pip with uv in Dockerfile (e23d69f)
  • rework guide mode with Remnawave API integration (5a269b2)
  • show all active webhook endpoints in startup log (9d71005)
  • unified notification delivery for webhook events (email + WS support) (26637f0)
  • webhook protection — prevent sync/monitoring from overwriting webhook data (184c52d)
  • мультиязычные лендинги + гостевые платежи для всех провайдеров (6deab7d)
  • публичные лендинг-страницы для быстрой покупки VPN-подписок (5e404cc)

Bug Fixes

  • 3 user deletion bugs — type cast, inner savepoint, lazy load (af31c55)
  • abs() for transaction amounts in admin notifications and subscription events (fd139b2)
  • add /start burst rate-limit to prevent spam abuse (61a9722)
  • add abs() to expenses query, display flip, contest stats, and recent payments (de6f806)
  • add action buttons to webhook notifications and fix empty device names (7091eb9)
  • add activate hint to gift pending activation email link (fa21549)
  • add blocked_count column migration to universal_migration.py (b4b10c9)
  • add diagnostic logging for device_limit sync to RemnaWave (97b3f89)
  • add exc_info traceback to sync user error log (efdf2a3)
  • add int32 overflow guards and strengthen auth validation (50a931e)
  • add IntegrityError handling on link commit and format fixes (0c1dc58)
  • add local traffic_used_gb reset in all tariff switch handlers (2cdbbc0)
  • add Message-ID and Date headers to outgoing emails (de541ea)
  • add Message-ID and Date headers to outgoing emails (e9b4d8e)
  • add migration for partner system tables and columns (4645be5)
  • add migration for partner system tables and columns (79ea398)
  • add min_length to state field, use exc_info for referral warning (062c486)
  • add missing broadcast_history columns and harden subscription logic (d4c4a8a)
  • add missing CHANNEL_CHECK_NOT_SUBSCRIBED localization key (a47ef67)
  • add missing mark_as_paid_subscription, fix operation order, remove dead code (5f2d855)
  • add missing payment providers to payment_utils and fix {total_amount} formatting (bdb6161)
  • add missing placeholders to Arabic SUBSCRIPTION_INFO template (fe54640)
  • add missing subscription columns migration (b96e819)
  • add naive datetime guards to fromisoformat() in Redis cache readers (1b3e6f2)
  • add naive datetime guards to fromisoformat() in Redis cache readers (6fa4948)
  • add naive datetime guards to parsers and fix test datetime literals (0946090)
  • add passive_deletes to Subscription relationships to prevent NOT NULL violation on cascade delete (bfd66c4)
  • add pending_activation to purchase stats and show total count (8510597)
  • add promo code anti-abuse protections (97ec39a)
  • add referral_code pattern validation, email login rate limiting, and Retry-After headers (5499ad6)
  • add selectinload for campaign registrations in list query (4d74afd)
  • add selectinload for subscription in campaign user list (eb9dba3)
  • add startup warning for missing HAPP_CRYPTOLINK_REDIRECT_TEMPLATE in guide mode (1d43ae5)
  • add X-CSRF-Token and X-Telegram-Init-Data to CORS allow_headers (77456ef)
  • address code review findings for Telegram OIDC (da1cc4f)
  • address code review issues in guide mode rework (fae6f71)
  • address RBAC review findings (CRITICAL + HIGH) (1646f04)
  • address remaining abs() issues from review (ff21b27)
  • address review findings for guest purchase admin notifications (770f19e)
  • address review findings from agent verification (cc5be70)
  • address review issues in backup, updates, and webhook handlers (2094886)
  • address security review findings (6feec1e)
  • align RBAC route prefixes with frontend API paths (5a7dd3f)
  • allow email change for unverified emails (93bb8e0)
  • allow non-HTTP deep links in crypto link webhook updates (f779225)
  • allow purchase when recalculated price is lower than cached (19dabf3)
  • allow tariff switch when less than 1 day remains (67f3547)
  • always include details in successful audit log entries (3dc0b93)
  • AttributeError in withdrawal admin notification (send_to_admins → send_admin_notification) (c75ec0b)
  • auth middleware catches all commit errors, not just connection errors (6409b0c)
  • auto-convert naive datetimes to UTC-aware on model load (f7d33a7)
  • auto-update permissions for system roles on bootstrap (eff74be)
  • backup restore fails on FK constraints and transaction poisoning (ff1c872)
  • build composite device name from platform + hwid short suffix (17ce640)
  • callback routing safety and cache invalidation order (6a50013)
  • campaign web link uses ?campaign= param, not ?start= (28f524b)
  • cap expected_monthly_referrals to prevent int32 overflow (2ef6185)
  • centralize balance deduction and fix unchecked return values (0466528)
  • centralize has_had_paid_subscription into subtract_user_balance (e4a6aad)
  • change CryptoBot URL priority to bot_invoice_url for Telegram opening (3193ffb)
  • classic mode prices overridden by active tariff prices (628a99e)
  • clean email verification and password fields from secondary user during merge (7b4e948)
  • clean stale squad UUIDs from tariffs during server sync (fcaa9df)
  • clear subscription data when user deleted from Remnawave panel (b0fd38d)
  • close remaining daily subscription expire paths (618c936)
  • code style and formatting from review (a539d69)
  • complete datetime.utcnow() → datetime.now(UTC) migration (eb18994)
  • complete FK migration — add 27 missing constraints, fix broadcast_history nullable (fe393d2)
  • comprehensive security and quality fixes from 7-agent review (5c55662)
  • comprehensive security hardening from 7-agent review (e96fe1e)
  • connected_squads stores UUIDs, not int IDs — use get_server_ids_by_uuids (d7039d7)
  • consume promo offer in miniapp tariff-mode renewal path (b8857e7)
  • consume promo offer in tariff_purchase.py, fix negative transaction amount (c8ef808)
  • correct broadcast button deep-links for cabinet mode (e5fa45f)
  • correct cart notification after balance top-up (2fab50c)
  • correct referral withdrawal balance formula and commission transaction type (83c6db4)
  • correct subscription_service import in broadcast cleanup (6c4e035)
  • count sales from completed payment transactions instead of subscription created_at (06c3996)
  • critical OIDC fixes from 7-agent review (b78c01c)
  • critical security and data integrity fixes for partner system (8899749)
  • cross-validate Telegram identity on every authenticated request (973b3d3)
  • CryptoBot guest payment — remove is_paid @property write, use correct status (6f871ed)
  • daily tariff subscriptions stuck in expired/disabled with no resume path (80914c1)
  • deadlock on user deletion + robust migration 0002 (b7b83ab)
  • delete cross-referral earnings before bulk reassignment, clear secondary.referred_by_id (f204b67)
  • delete subscription_servers before subscription to prevent FK violation (7d9ced8)
  • device_limit fallback 1→0 для корректного отображения безлимита (3e26832)
  • don't delete Heleket invoice message on status check (9943253)
  • downgrade Telegram timeout errors to warning in monitoring service (e43a8d6)
  • downgrade transient API errors (502/503/504) to warning level (ec8eaf5)
  • eliminate deadlock by matching lock order with webhook (d651a6c)
  • eliminate double panel API call on tariff change, harden cart notification (b2cf4aa)
  • eliminate referral system inconsistencies (60c97f7)
  • email verification bypass, ban-notifications size limit, referral balance API (256cbfc)
  • empty JSONB values exported as None in backup (57aaca8)
  • enforce user restrictions in cabinet API and fix poll history crash (faba3a8)
  • expand backup coverage to all 68 models and harden restore (02e40bd)
  • extend naive datetime guard to all model properties (bd11801)
  • extract device name from nested hwidUserDevice object (79793c4)
  • extract real client IP from X-Forwarded-For/X-Real-IP headers (af6686c)
  • filter out traffic packages with zero price from purchase options (64a684c)
  • flood control handling in pinned messages and XSS hardening in HTML sanitizer (454b831)
  • force basicConfig to replace pre-existing handlers (7eb8d4e)
  • freekassa OP-SP-7 error and missing telegram notification (200f91e)
  • from redis.exceptions import NoScriptError (667291a)
  • generate missing crypto link on the fly and skip unresolved templates (4c72058)
  • grant legacy config-based admins full RBAC access (8893fc1)
  • handle duplicate remnawave_uuid on email sync (eaeee7a)
  • handle expired callback queries and harden middleware error handling (f52e6ae)
  • handle expired ORM attributes in sync UUID mutation (9ae5d7b)
  • handle naive datetime in raw SQL row comparison (payment/common) (38f3a9a)
  • handle naive datetimes in Subscription properties (e512e5f)
  • handle NULL used_promocodes for migrated users (cdcabee)
  • handle nullable traffic_limit_gb and end_date in subscription model (e94b93d)
  • handle photo message in ticket creation flow (e182280)
  • handle RemnaWave API errors in traffic aggregation (ed4624c)
  • handle StaleDataError in webhook user.deleted server counter decrement (c30c2fe)
  • handle StaleDataError in webhook when user already deleted (d58a80f)
  • handle tariff_extend callback without period (back button crash) (ba0a5e9)
  • handle TelegramBadRequest in ticket edit_message_text calls (8e61fe4)
  • handle time/date types in backup JSON serialization (27365b3)
  • handle unique constraint conflicts during backup restore without clear_existing (5893874)
  • handle YooKassa NotFoundError gracefully in get_payment_info (df5b1a0)
  • harden account merge security and correctness (d855e9e)
  • harden backup create/restore against serialization and constraint errors (fc42916)
  • hide traffic topup button when tariff doesn't support it (399ca86)
  • HTML parse fallback, email change race condition, username length limit (d05ff67)
  • HTML-escape all externally-sourced text in guide messages (711ec34)
  • ignore 'message is not modified' on privacy policy decline (be1da97)
  • improve campaign notifications and ticket media in admin topics (a594a0f)
  • improve campaign routes, schemas, and add database indexes (ded5c89)
  • improve deduplication log message wording in monitoring service (2aead9a)
  • include desired_commission_percent in admin notification (dc3d22f)
  • initialize logger in bot_configuration.py (988d0e5)
  • invalidate app config cache on local file saves (978726a)
  • limit Rich traceback output to prevent console flood (11ef714)
  • make migration 0002 robust with table existence checks (f076269)
  • make migrations 0010/0011 idempotent, escape HTML in crash notification (a696896)
  • make users.promo_group_id nullable — sync DB with model (e0f2243)
  • medium-priority fixes for partner system (7c20fde)
  • merge: validate before consuming token, add flush, defensive balance (bc1e6fb)
  • migrate all remaining naive timestamp columns to timestamptz (708bb9e)
  • migrate VK OAuth to VK ID OAuth 2.1 with PKCE (1dfa780)
  • MissingGreenlet on campaign registrations access (018f18f)
  • move PartnerStatus enum before User class to fix NameError (acc1323)
  • NameError in set_user_devices_button — undefined action_text (1b8ef69)
  • negative balance transfer, linking state validation, referrer migration (531d5cf)
  • normalize transaction amount signs across all aggregations (4247981)
  • nullify payment FK references before deleting transactions in user restoration (0b86f37)
  • partner system — CRUD nullable fields, per-campaign stats, atomic unassign, diagnostic logging (ed3ae14)
  • pass return_url to all payment providers for guest purchases (b85646a)
  • payment race conditions, balance atomicity, renewal rollback safety (c5124b9)
  • photo handling in QR messages (1afcd84)
  • pre-existing bugs found during review (1bb939f)
  • pre-validate CABINET_BUTTON_STYLE to prevent invalid values from suppressing per-section defaults (46c1a69)
  • preserve connected_squads during subscription replacement cleanup (d86c29a)
  • preserve payment initiation time in transaction created_at (90d9df8)
  • preserve purchased traffic when extending same tariff (b167ed3)
  • prevent 'caption is too long' error in logo mode (6e28a1a)
  • prevent cascading greenlet errors after sync rollback (a1ffd5b)
  • prevent concurrent device purchases exceeding max device limit (1cfede2)
  • prevent daily subscriptions from being expired by middleware/CRUD/webhook (0ed6397)
  • prevent fileConfig from destroying structlog handlers (e78b104)
  • prevent infinite reuse of first_purchase_only promo code discounts (2cec8dc)
  • prevent negative amounts in spent display and balance history (c30972f)
  • prevent partner self-referral via own campaign link (115c0c8)
  • prevent race condition expiring active daily subscriptions (bfef7cc)
  • prevent self-referral loops, invalidate all sessions on merge (db61365)
  • prevent squad drop on admin subscription type change, require subscription for wheel spins (59f0e42)
  • prevent sync from overwriting end_date for non-ACTIVE panel users (49871f8)
  • prevent sync from overwriting subscription URLs with empty strings (9c00479)
  • promo code max_uses=0 conversion and trial UX after promo activation (1cae713)
  • protect active paid subscriptions from being disabled in RemnaWave (1b6bbc7)
  • protect server counter callers and fix tariff change detection (bee4aa4)
  • RBAC API response format fixes and audit log user info (4598c27)
  • RBAC audit log action filter and legacy admin level (c1da8a4)
  • read discount overrides from landing model instead of response DTO (6d65e15)
  • read OIDC enabled setting from DB in auth endpoint (2405dc5)
  • reassign orphaned records on merge, eliminate TOCTOU race (d7a9d2b)
  • redis cache uses sync client due to import shadowing (667291a)
  • reject promo codes for days when user has no subscription or trial (e32e2f7)
  • remove @username channel ID input, auto-prefix -100 for bare digits (a7db469)
  • remove decorative cloudpayments sub-options (694aecc)
  • remove DisplayNameRestrictionMiddleware (640da34)
  • remove executable bit from email_service.py (372d628)
  • remove gemini-effect and noise from allowed background types (731eb24)
  • remove local UTC re-imports shadowing module-level import in purchase.py (e68760c)
  • remove premature tariff_id assignment in _apply_extension_updates (b47678c)
  • remove redundant trial inactivity monitoring checks (d712ab8)
  • remove subscription connection links from guest purchase emails (9217352)
  • remove unused PaymentService from MonitoringService init (491a7e1)
  • renewals stats empty on all-time filter (e25fcfc)
  • reorder button_click_logs migration to nullify before ALTER TYPE (df5415f)
  • repair missing DB columns and make backup resilient to schema mismatches (c20355b)
  • replace deprecated Query(regex=) with pattern= (871ceb8)
  • reset QR photo when returning to referral (3ee108f)
  • reset traffic purchases on expired subscription renewal + pricing fixes (dce9eaa)
  • resolve deadlock on server_squads counter updates and add webhook notification toggles (57dc1ff)
  • resolve exc_info for admin notifications, clean log formatting (11f8af0)
  • resolve GROUP BY mismatch for daily_by_tariff query (e5f29eb)
  • resolve HIGH-priority performance and security issues in partner system (fcf3a2c)
  • resolve MissingGreenlet error when accessing subscription.tariff (a93a32f)
  • resolve ruff lint errors (import sorting, unused variable) (b2d7abf)
  • resolve sync 404 errors, user deletion FK constraint, and device limit not sent to RemnaWave (1ce9174)
  • restore merge token on DB failure, fix partner_status priority (9582758)
  • restore panel user discovery on admin tariff change, localize cart reminder (1256ddc)
  • restore RemnaWave config management endpoints (6f473de)
  • restore subscription_url and crypto_link after panel sync (26efb15)
  • return zeroed stats dict when withdrawal is disabled (7883efc)
  • review findings — exception chaining, redundant unquote, validator tightening (467dea1)
  • safe HTML preview truncation and lazy-load subscription fallback (40d8a6d)
  • second round review fixes for account merge (64ee045)
  • security and architecture fixes for webhook handlers (dc1e96b)
  • separate base and purchased traffic in renewal pricing (739ba29)
  • show negative amounts for withdrawals in admin transaction list (5ee45f9)
  • skip blocked users in trial notifications and broadcasts without DB status change (493f315)
  • skip users with active subscriptions in admin inactive cleanup (e79f598)
  • specify foreign_keys on User.admin_roles_rel to resolve ambiguous join (bc7d061)
  • stack promo group + promo offer discounts in bot (matching cabinet) (628997f)
  • stop CryptoBot webhook retry loop and save cabinet payments to DB (2cb6d73)
  • suppress 'message is not modified' error in updates panel (3a680b4)
  • suppress bot-blocked-by-user error in AuthMiddleware (fda9f3b)
  • suppress expired callback query error in AuthMiddleware (2de4384)
  • suppress startup log noise (~350 lines → ~30) (8a6650e)
  • suppress web page preview when logo mode is disabled (1f4430f)
  • sync subscription status from panel in user.modified webhook (5156d63)
  • sync support mode from cabinet admin to SupportSettingsService (516be6e)
  • sync SUPPORT_SYSTEM_MODE between SystemSettings and SupportSettings (0807a9f)
  • sync traffic reset across all tariff switch code paths (d708365)
  • sync uv.lock version with pyproject.toml 3.23.1 (8eb6a8c)
  • sync uv.lock version with pyproject.toml 3.23.1 (bc52fd2)
  • ticket creation crash and webhook PendingRollbackError (760c833)
  • traceback in Telegram notifications + reduce log padding (909a403)
  • transaction boundary and CORS in webapi (6495384)
  • translate required channels handler to Russian, add localization keys (1bc9074)
  • treat empty icon_url as None in payment method validation (ab981dc)
  • unassign all campaigns when revoking partner status (d39063b)
  • UnboundLocalError for get_logo_media in required_sub_channel_check (d3c14ac)
  • UniqueViolation при мерже аккаунтов с общим OAuth/telegram/email ID (1c89bd8)
  • uploaded backup restore button not triggering handler (ebe5083)
  • use .is_(True) and add or 0 guards per code review (69b5ca0)
  • use actual DB columns for subscription fallback query (f0e7f8e)
  • use aiogram 3.x bot.download() instead of document.download() (205c8d9)
  • use AwareDateTime TypeDecorator for all datetime columns (a7f3d65)
  • use callback fallback when MINIAPP_CUSTOM_URL is not set (eaf3a07)
  • use direct is_trial access, add missing error codes to promo APIs (69a9899)
  • use event field directly as event_name (already includes scope prefix) (9aa22af)
  • use float instead of int | float (PYI041) (310edae)
  • use flush instead of commit in server counter functions (6cec024)
  • use get_rendered_override for proper variable substitution in guest email overrides (c165cca)
  • use SAVEPOINT instead of full rollback in sync user creation (2a90f87)
  • use selection.period.days instead of selection.period_days (4541016)
  • use short TTL fallback in restore_merge_token on parse error (0e8c61a)
  • use sync context manager for structlog bound_contextvars (25e8c9f)
  • use traffic topup config and add WATA 429 retry (b5998ea)
  • validate payment sub-option suffix and harden payment method handling (5f01783)
  • webhook notification 'My Subscription' button uses unregistered callback_data (1e2a7e3)
  • webhook:close button not working due to channel check timeout (019fbc1)
  • wrap user deletion steps in savepoints to prevent transaction cascade abort (a38dfcb)
  • безопасность и качество кода лендингов — 16 исправлений (ef45095)
  • гарантировать положительный доход от подписок и исправить общий доход (93a55df)
  • дедупликация promocode_uses при мерже аккаунтов (00a7db2)
  • добавить create_transaction для 6 потоков оплаты с баланса (374907b)
  • добавить create_transaction и admin-уведомления для автопродлений (9f35088)
  • добавить ON DELETE CASCADE/SET NULL на все FK к users.id (34c82c3)
  • добавить пробелы в формат тарифов (1000 ГБ / 2 📱) (900be65)
  • дубликаты системных ролей при переименовании и сброс permissions (7a7fb71)
  • изолировать stored_amount от downstream consumers в create_transaction (b87535a)
  • исправления системы реферальных конкурсов (6713b34)
  • кнопка «Назад» в тарифах ведёт в админ панель, а не в настройки (04562fd)
  • миграция 0016 падает если FK constraint отсутствует в БД (15fe45d)
  • миграция 0021 — drop server_default перед сменой типа на JSON (3d3bb3b)
  • передать явный диапазон дат для all_time_stats в дашборде (968d147)
  • показывать кнопку покупки тарифа вместо ошибки для триальных подписок (acfa4b3)
  • показывать только активные провайдеры на странице /profile/accounts (9d7a557)
  • промокоды — конвертация триалов, race condition, savepoints (7fb839a)
  • реактивация DISABLED подписок при покупке трафика для LIMITED пользователей (7d28f55)
  • реактивация DISABLED подписок при покупке устройств и в REST API (b9e17be)
  • синхронизация версии pyproject.toml с main и обновление uv в Dockerfile (b31a893)
  • убрать WITHDRAWAL из автонегации, добавить abs() в агрегации, исправить all_time_stats (6da61d7)
  • убрать избыточный минус в amount_kopeks для create_transaction (849b3a7)
  • устранение race condition при покупке устройств через re-lock после коммита (a7a18dd)
  • устранение race conditions и атомарность платёжной системы (4984f20)
  • устранение каскадного PendingRollbackError при восстановлении бэкапа (8259278)

Performance

  • cache logo file_id to avoid re-uploading on every message (142ff14)

Refactoring

  • complete structlog migration with contextvars, kwargs, and logging hardening (1f0fef1)
  • extract shared OAuth linking logic, add Literal types for providers (f7caf0d)
  • improve log formatting — logger name prefix and table alignment (f637204)
  • remove "both" mode from BOT_RUN_MODE, keep only polling and webhook (efa3a5d)
  • remove Flask, use FastAPI exclusively for all webhooks (119f463)
  • remove legacy app-config.json system (295d2e8)
  • remove modem functionality from classic subscriptions (ee2e79d)
  • remove smart auto-activation & activation prompt, fix production bugs (a3903a2)
  • replace universal_migration.py with Alembic (b6c7f91)
  • replace universal_migration.py with Alembic (784616b)

3.23.2 (2026-03-06)

Bug Fixes

  • device_limit fallback 1→0 для корректного отображения безлимита (3e26832)
  • sync uv.lock version with pyproject.toml 3.23.1 (8eb6a8c)
  • sync uv.lock version with pyproject.toml 3.23.1 (bc52fd2)
  • миграция 0016 падает если FK constraint отсутствует в БД (15fe45d)

3.23.1 (2026-03-06)

Bug Fixes

  • complete FK migration — add 27 missing constraints, fix broadcast_history nullable (fe393d2)
  • UniqueViolation при мерже аккаунтов с общим OAuth/telegram/email ID (1c89bd8)
  • дедупликация promocode_uses при мерже аккаунтов (00a7db2)
  • добавить ON DELETE CASCADE/SET NULL на все FK к users.id (34c82c3)
  • дубликаты системных ролей при переименовании и сброс permissions (7a7fb71)
  • исправления системы реферальных конкурсов (6713b34)
  • кнопка «Назад» в тарифах ведёт в админ панель, а не в настройки (04562fd)
  • промокоды — конвертация триалов, race condition, savepoints (7fb839a)
  • устранение race conditions и атомарность платёжной системы (4984f20)

3.23.0 (2026-03-05)

New Features

  • account linking and merge system for cabinet (dc7b8dc)
  • account merge system — atomic user merge with full FK coverage (2664b49)
  • add dedicated sales_stats RBAC permission section (8f29e2e)
  • add server-complete OAuth linking endpoint for Mini App flow (f867989)
  • add Telegram account linking endpoint with security hardening (da40d56)

Bug Fixes

  • abs() for transaction amounts in admin notifications and subscription events (fd139b2)
  • add abs() to expenses query, display flip, contest stats, and recent payments (de6f806)
  • add IntegrityError handling on link commit and format fixes (0c1dc58)
  • add missing mark_as_paid_subscription, fix operation order, remove dead code (5f2d855)
  • auto-update permissions for system roles on bootstrap (eff74be)
  • centralize balance deduction and fix unchecked return values (0466528)
  • centralize has_had_paid_subscription into subtract_user_balance (e4a6aad)
  • clean email verification and password fields from secondary user during merge (7b4e948)
  • consume promo offer in miniapp tariff-mode renewal path (b8857e7)
  • consume promo offer in tariff_purchase.py, fix negative transaction amount (c8ef808)
  • delete cross-referral earnings before bulk reassignment, clear secondary.referred_by_id (f204b67)
  • from redis.exceptions import NoScriptError (667291a)
  • harden account merge security and correctness (d855e9e)
  • merge: validate before consuming token, add flush, defensive balance (bc1e6fb)
  • negative balance transfer, linking state validation, referrer migration (531d5cf)
  • prevent concurrent device purchases exceeding max device limit (1cfede2)
  • prevent infinite reuse of first_purchase_only promo code discounts (2cec8dc)
  • prevent self-referral loops, invalidate all sessions on merge (db61365)
  • reassign orphaned records on merge, eliminate TOCTOU race (d7a9d2b)
  • redis cache uses sync client due to import shadowing (667291a)
  • restore merge token on DB failure, fix partner_status priority (9582758)
  • review findings — exception chaining, redundant unquote, validator tightening (467dea1)
  • second round review fixes for account merge (64ee045)
  • use short TTL fallback in restore_merge_token on parse error (0e8c61a)
  • гарантировать положительный доход от подписок и исправить общий доход (93a55df)
  • добавить create_transaction для 6 потоков оплаты с баланса (374907b)
  • добавить create_transaction и admin-уведомления для автопродлений (9f35088)
  • добавить пробелы в формат тарифов (1000 ГБ / 2 📱) (900be65)
  • изолировать stored_amount от downstream consumers в create_transaction (b87535a)
  • передать явный диапазон дат для all_time_stats в дашборде (968d147)
  • показывать кнопку покупки тарифа вместо ошибки для триальных подписок (acfa4b3)
  • показывать только активные провайдеры на странице /profile/accounts (9d7a557)
  • реактивация DISABLED подписок при покупке трафика для LIMITED пользователей (7d28f55)
  • реактивация DISABLED подписок при покупке устройств и в REST API (b9e17be)
  • синхронизация версии pyproject.toml с main и обновление uv в Dockerfile (b31a893)
  • убрать WITHDRAWAL из автонегации, добавить abs() в агрегации, исправить all_time_stats (6da61d7)
  • убрать избыточный минус в amount_kopeks для create_transaction (849b3a7)
  • устранение race condition при покупке устройств через re-lock после коммита (a7a18dd)
  • устранение каскадного PendingRollbackError при восстановлении бэкапа (8259278)

Refactoring

  • extract shared OAuth linking logic, add Literal types for providers (f7caf0d)

3.22.0 (2026-03-04)

New Features

  • replace pip with uv in Dockerfile (e23d69f)

Bug Fixes

  • add selectinload for campaign registrations in list query (4d74afd)
  • backup restore fails on FK constraints and transaction poisoning (ff1c872)
  • classic mode prices overridden by active tariff prices (628a99e)
  • close remaining daily subscription expire paths (618c936)
  • empty JSONB values exported as None in backup (57aaca8)
  • handle duplicate remnawave_uuid on email sync (eaeee7a)
  • MissingGreenlet on campaign registrations access (018f18f)
  • prevent daily subscriptions from being expired by middleware/CRUD/webhook (0ed6397)
  • reset traffic purchases on expired subscription renewal + pricing fixes (dce9eaa)

3.21.0 (2026-03-02)

New Features

  • add admin campaign chart data endpoint with deposits/spending split (fa7de58)
  • add admin sales statistics API with 6 analytics endpoints (58faf9e)
  • add daily deposits by payment method breakdown (d33c5d6)
  • add daily device purchases chart to addons stats (2449a5c)
  • add desired commission percent to partner application (7ea8fbd)
  • add RESET_TRAFFIC_ON_TARIFF_SWITCH admin setting (4eaedd3)
  • enhance sales stats with device purchases, per-tariff daily breakdown, and registration tracking (31c7e2e)

Bug Fixes

  • add exc_info traceback to sync user error log (efdf2a3)
  • add local traffic_used_gb reset in all tariff switch handlers (2cdbbc0)
  • add min_length to state field, use exc_info for referral warning (062c486)
  • add missing subscription columns migration (b96e819)
  • address review findings from agent verification (cc5be70)
  • correct cart notification after balance top-up (2fab50c)
  • correct referral withdrawal balance formula and commission transaction type (83c6db4)
  • count sales from completed payment transactions instead of subscription created_at (06c3996)
  • eliminate double panel API call on tariff change, harden cart notification (b2cf4aa)
  • eliminate referral system inconsistencies (60c97f7)
  • email verification bypass, ban-notifications size limit, referral balance API (256cbfc)
  • enforce user restrictions in cabinet API and fix poll history crash (faba3a8)
  • freekassa OP-SP-7 error and missing telegram notification (200f91e)
  • generate missing crypto link on the fly and skip unresolved templates (4c72058)
  • handle expired callback queries and harden middleware error handling (f52e6ae)
  • handle expired ORM attributes in sync UUID mutation (9ae5d7b)
  • handle NULL used_promocodes for migrated users (cdcabee)
  • hide traffic topup button when tariff doesn't support it (399ca86)
  • improve campaign routes, schemas, and add database indexes (ded5c89)
  • include desired_commission_percent in admin notification (dc3d22f)
  • migrate VK OAuth to VK ID OAuth 2.1 with PKCE (1dfa780)
  • partner system — CRUD nullable fields, per-campaign stats, atomic unassign, diagnostic logging (ed3ae14)
  • prevent squad drop on admin subscription type change, require subscription for wheel spins (59f0e42)
  • prevent sync from overwriting subscription URLs with empty strings (9c00479)
  • reject promo codes for days when user has no subscription or trial (e32e2f7)
  • remove premature tariff_id assignment in _apply_extension_updates (b47678c)
  • renewals stats empty on all-time filter (e25fcfc)
  • resolve GROUP BY mismatch for daily_by_tariff query (e5f29eb)
  • restore panel user discovery on admin tariff change, localize cart reminder (1256ddc)
  • separate base and purchased traffic in renewal pricing (739ba29)
  • sync traffic reset across all tariff switch code paths (d708365)
  • use .is_(True) and add or 0 guards per code review (69b5ca0)
  • use direct is_trial access, add missing error codes to promo APIs (69a9899)
  • use float instead of int | float (PYI041) (310edae)
  • use SAVEPOINT instead of full rollback in sync user creation (2a90f87)

3.20.1 (2026-02-25)

Bug Fixes

  • make migrations 0010/0011 idempotent, escape HTML in crash notification (a696896)
  • prevent race condition expiring active daily subscriptions (bfef7cc)

3.20.0 (2026-02-25)

New Features

  • add separate Freekassa SBP and card payment methods (0da0c55)
  • add validation to animation config API (a15403b)

Bug Fixes

  • initialize logger in bot_configuration.py (988d0e5)
  • remove gemini-effect and noise from allowed background types (731eb24)
  • resolve ruff lint errors (import sorting, unused variable) (b2d7abf)
  • resolve sync 404 errors, user deletion FK constraint, and device limit not sent to RemnaWave (1ce9174)

3.19.0 (2026-02-25)

New Features

  • add granular user permissions (balance, subscription, promo_group, referral, send_offer) (60c4fe2)
  • add per-channel disable settings and fix CHANNEL_REQUIRED_FOR_ALL bug (3642462)
  • add RBAC + ABAC permission system for admin cabinet (3fee54f)
  • add resource_type and request body to audit log entries (388fc7e)
  • allow editing system roles (f6b6e22)
  • capture query params in audit log details for all requests (bea9da9)

Bug Fixes

  • address RBAC review findings (CRITICAL + HIGH) (1646f04)
  • align RBAC route prefixes with frontend API paths (5a7dd3f)
  • always include details in successful audit log entries (3dc0b93)
  • extract real client IP from X-Forwarded-For/X-Real-IP headers (af6686c)
  • grant legacy config-based admins full RBAC access (8893fc1)
  • improve campaign notifications and ticket media in admin topics (a594a0f)
  • RBAC API response format fixes and audit log user info (4598c27)
  • RBAC audit log action filter and legacy admin level (c1da8a4)
  • restore subscription_url and crypto_link after panel sync (26efb15)
  • specify foreign_keys on User.admin_roles_rel to resolve ambiguous join (bc7d061)
  • stack promo group + promo offer discounts in bot (matching cabinet) (628997f)

3.18.0 (2026-02-24)

New Features

  • add ChatTypeFilterMiddleware to ignore group/forum messages (25f014f)
  • add multi-channel mandatory subscription system (8375d7e)
  • add required channels button to admin settings submenu in bot (3af07ff)
  • colored channel subscription buttons via Bot API 9.4 style (0b3b2e5)
  • rework guide mode with Remnawave API integration (5a269b2)

Bug Fixes

  • add missing CHANNEL_CHECK_NOT_SUBSCRIBED localization key (a47ef67)
  • address code review issues in guide mode rework (fae6f71)
  • address security review findings (6feec1e)
  • callback routing safety and cache invalidation order (6a50013)
  • correct broadcast button deep-links for cabinet mode (e5fa45f)
  • HTML-escape all externally-sourced text in guide messages (711ec34)
  • improve deduplication log message wording in monitoring service (2aead9a)
  • invalidate app config cache on local file saves (978726a)
  • pre-existing bugs found during review (1bb939f)
  • remove @username channel ID input, auto-prefix -100 for bare digits (a7db469)
  • restore RemnaWave config management endpoints (6f473de)
  • translate required channels handler to Russian, add localization keys (1bc9074)

Refactoring

  • remove legacy app-config.json system (295d2e8)

3.17.1 (2026-02-23)

Bug Fixes

  • add diagnostic logging for device_limit sync to RemnaWave (97b3f89)
  • add int32 overflow guards and strengthen auth validation (50a931e)
  • add missing broadcast_history columns and harden subscription logic (d4c4a8a)
  • allow tariff switch when less than 1 day remains (67f3547)
  • cap expected_monthly_referrals to prevent int32 overflow (2ef6185)
  • cross-validate Telegram identity on every authenticated request (973b3d3)
  • handle RemnaWave API errors in traffic aggregation (ed4624c)
  • migrate all remaining naive timestamp columns to timestamptz (708bb9e)
  • prevent partner self-referral via own campaign link (115c0c8)
  • protect active paid subscriptions from being disabled in RemnaWave (1b6bbc7)
  • repair missing DB columns and make backup resilient to schema mismatches (c20355b)
  • show negative amounts for withdrawals in admin transaction list (5ee45f9)
  • suppress web page preview when logo mode is disabled (1f4430f)
  • uploaded backup restore button not triggering handler (ebe5083)
  • use aiogram 3.x bot.download() instead of document.download() (205c8d9)

3.17.0 (2026-02-18)

New Features

  • add referral code tracking to all cabinet auth methods + email_templates migration (18c2477)

Bug Fixes

  • prevent 'caption is too long' error in logo mode (6e28a1a)
  • skip blocked users in trial notifications and broadcasts without DB status change (493f315)

3.16.3 (2026-02-18)

Bug Fixes

  • 3 user deletion bugs — type cast, inner savepoint, lazy load (af31c55)
  • auth middleware catches all commit errors, not just connection errors (6409b0c)
  • connected_squads stores UUIDs, not int IDs — use get_server_ids_by_uuids (d7039d7)
  • deadlock on user deletion + robust migration 0002 (b7b83ab)
  • eliminate deadlock by matching lock order with webhook (d651a6c)
  • make migration 0002 robust with table existence checks (f076269)
  • wrap user deletion steps in savepoints to prevent transaction cascade abort (a38dfcb)

3.16.2 (2026-02-18)

Bug Fixes

  • auto-convert naive datetimes to UTC-aware on model load (f7d33a7)
  • extend naive datetime guard to all model properties (bd11801)
  • handle naive datetime in raw SQL row comparison (payment/common) (38f3a9a)
  • handle naive datetimes in Subscription properties (e512e5f)
  • use AwareDateTime TypeDecorator for all datetime columns (a7f3d65)

3.16.1 (2026-02-18)

Bug Fixes

  • add migration for partner system tables and columns (4645be5)
  • add migration for partner system tables and columns (79ea398)

3.16.0 (2026-02-18)

New Features

  • add admin notifications for partner applications and withdrawals (cf7cc5a)
  • add admin partner settings API (withdrawal toggle, requisites text, partner visibility) (6881d97)
  • add campaign_id to ReferralEarning for campaign attribution (0c07812)
  • add partner system and withdrawal management to cabinet (58bfaea)
  • attribute campaign registrations to partner for referral earnings (767e965)
  • blocked user detection during broadcasts, filter blocked from all notifications (10e231e)
  • enforce 1-to-1 partner-campaign binding with partner info in campaigns (366df18)
  • expose traffic_reset_mode in subscription response (59383bd)
  • expose traffic_reset_mode in tariff API response (5d4a94b)
  • include partner campaigns in /partner/status response (ea5d932)
  • link campaign registrations to partner for referral earnings (c4dc43e)
  • notify users on partner/withdrawal approve/reject (327d4f4)

Bug Fixes

  • add blocked_count column migration to universal_migration.py (b4b10c9)
  • add missing payment providers to payment_utils and fix {total_amount} formatting (bdb6161)
  • add selectinload for subscription in campaign user list (eb9dba3)
  • campaign web link uses ?campaign= param, not ?start= (28f524b)
  • correct subscription_service import in broadcast cleanup (6c4e035)
  • critical security and data integrity fixes for partner system (8899749)
  • handle YooKassa NotFoundError gracefully in get_payment_info (df5b1a0)
  • medium-priority fixes for partner system (7c20fde)
  • move PartnerStatus enum before User class to fix NameError (acc1323)
  • prevent fileConfig from destroying structlog handlers (e78b104)
  • reorder button_click_logs migration to nullify before ALTER TYPE (df5415f)
  • resolve HIGH-priority performance and security issues in partner system (fcf3a2c)
  • return zeroed stats dict when withdrawal is disabled (7883efc)
  • unassign all campaigns when revoking partner status (d39063b)

Refactoring

  • replace universal_migration.py with Alembic (b6c7f91)
  • replace universal_migration.py with Alembic (784616b)

3.15.1 (2026-02-17)

Bug Fixes

  • add naive datetime guards to fromisoformat() in Redis cache readers (1b3e6f2)
  • add naive datetime guards to fromisoformat() in Redis cache readers (6fa4948)

3.15.0 (2026-02-17)

New Features

  • add LOG_COLORS env setting to toggle console ANSI colors (27309f5)
  • add web campaign links with bonus processing in auth flow (d955279)

Bug Fixes

  • AttributeError in withdrawal admin notification (send_to_admins → send_admin_notification) (c75ec0b)
  • remove local UTC re-imports shadowing module-level import in purchase.py (e68760c)

3.14.1 (2026-02-17)

Bug Fixes

  • add naive datetime guards to parsers and fix test datetime literals (0946090)
  • address remaining abs() issues from review (ff21b27)
  • complete datetime.utcnow() → datetime.now(UTC) migration (eb18994)
  • normalize transaction amount signs across all aggregations (4247981)
  • prevent negative amounts in spent display and balance history (c30972f)

3.14.0 (2026-02-16)

New Features

  • show all active webhook endpoints in startup log (9d71005)

Bug Fixes

  • force basicConfig to replace pre-existing handlers (7eb8d4e)
  • NameError in set_user_devices_button — undefined action_text (1b8ef69)
  • remove unused PaymentService from MonitoringService init (491a7e1)
  • resolve MissingGreenlet error when accessing subscription.tariff (a93a32f)
  • sync support mode from cabinet admin to SupportSettingsService (516be6e)
  • sync SUPPORT_SYSTEM_MODE between SystemSettings and SupportSettings (0807a9f)

Refactoring

  • improve log formatting — logger name prefix and table alignment (f637204)

3.13.0 (2026-02-16)

New Features

  • colored console logs via structlog + rich + FORCE_COLOR (bf64611)

Bug Fixes

  • limit Rich traceback output to prevent console flood (11ef714)
  • resolve exc_info for admin notifications, clean log formatting (11f8af0)
  • suppress startup log noise (~350 lines → ~30) (8a6650e)
  • traceback in Telegram notifications + reduce log padding (909a403)
  • use sync context manager for structlog bound_contextvars (25e8c9f)

Refactoring

  • complete structlog migration with contextvars, kwargs, and logging hardening (1f0fef1)

3.12.1 (2026-02-16)

Bug Fixes

  • add /start burst rate-limit to prevent spam abuse (61a9722)
  • add promo code anti-abuse protections (97ec39a)
  • handle TelegramBadRequest in ticket edit_message_text calls (8e61fe4)
  • replace deprecated Query(regex=) with pattern= (871ceb8)

3.12.0 (2026-02-15)

New Features

  • add 'default' (no color) option for button styles (10538e7)
  • add button style and emoji support for cabinet mode (Bot API 9.4) (bf2b2f1)
  • add per-button enable/disable toggle and custom labels per locale (68773b7)
  • add per-section button style and emoji customization via admin API (a968791)
  • add web admin button for admins in cabinet mode (9ac6da4)
  • rename MAIN_MENU_MODE=text to cabinet with deep-linking to frontend sections (ad87c5f)

Bug Fixes

  • daily tariff subscriptions stuck in expired/disabled with no resume path (80914c1)
  • filter out traffic packages with zero price from purchase options (64a684c)
  • handle photo message in ticket creation flow (e182280)
  • handle tariff_extend callback without period (back button crash) (ba0a5e9)
  • pre-validate CABINET_BUTTON_STYLE to prevent invalid values from suppressing per-section defaults (46c1a69)
  • remove redundant trial inactivity monitoring checks (d712ab8)
  • webhook notification 'My Subscription' button uses unregistered callback_data (1e2a7e3)

3.11.0 (2026-02-12)

New Features

  • add cabinet admin API for pinned messages management (1a476c4)
  • add startup warnings for missing HAPP_CRYPTOLINK_REDIRECT_TEMPLATE and MINIAPP_CUSTOM_URL (476b89f)

Bug Fixes

  • add passive_deletes to Subscription relationships to prevent NOT NULL violation on cascade delete (bfd66c4)
  • add startup warning for missing HAPP_CRYPTOLINK_REDIRECT_TEMPLATE in guide mode (1d43ae5)
  • flood control handling in pinned messages and XSS hardening in HTML sanitizer (454b831)
  • suppress expired callback query error in AuthMiddleware (2de4384)
  • ticket creation crash and webhook PendingRollbackError (760c833)

3.10.3 (2026-02-12)

Bug Fixes

  • handle unique constraint conflicts during backup restore without clear_existing (5893874)
  • harden backup create/restore against serialization and constraint errors (fc42916)
  • resolve deadlock on server_squads counter updates and add webhook notification toggles (57dc1ff)

3.10.2 (2026-02-12)

Bug Fixes

  • allow email change for unverified emails (93bb8e0)
  • clean stale squad UUIDs from tariffs during server sync (fcaa9df)
  • delete subscription_servers before subscription to prevent FK violation (7d9ced8)
  • handle StaleDataError in webhook user.deleted server counter decrement (c30c2fe)
  • handle time/date types in backup JSON serialization (27365b3)
  • HTML parse fallback, email change race condition, username length limit (d05ff67)
  • payment race conditions, balance atomicity, renewal rollback safety (c5124b9)
  • remove DisplayNameRestrictionMiddleware (640da34)
  • suppress bot-blocked-by-user error in AuthMiddleware (fda9f3b)
  • UnboundLocalError for get_logo_media in required_sub_channel_check (d3c14ac)
  • use traffic topup config and add WATA 429 retry (b5998ea)

Refactoring

  • remove modem functionality from classic subscriptions (ee2e79d)

3.10.1 (2026-02-11)

Bug Fixes

  • address review issues in backup, updates, and webhook handlers (2094886)
  • allow purchase when recalculated price is lower than cached (19dabf3)
  • change CryptoBot URL priority to bot_invoice_url for Telegram opening (3193ffb)
  • clear subscription data when user deleted from Remnawave panel (b0fd38d)
  • downgrade Telegram timeout errors to warning in monitoring service (e43a8d6)
  • expand backup coverage to all 68 models and harden restore (02e40bd)
  • handle nullable traffic_limit_gb and end_date in subscription model (e94b93d)
  • handle StaleDataError in webhook when user already deleted (d58a80f)
  • ignore 'message is not modified' on privacy policy decline (be1da97)
  • preserve purchased traffic when extending same tariff (b167ed3)
  • prevent cascading greenlet errors after sync rollback (a1ffd5b)
  • protect server counter callers and fix tariff change detection (bee4aa4)
  • suppress 'message is not modified' error in updates panel (3a680b4)
  • use callback fallback when MINIAPP_CUSTOM_URL is not set (eaf3a07)
  • use flush instead of commit in server counter functions (6cec024)

3.10.0 (2026-02-10)

New Features

  • add all remaining RemnaWave webhook events (node, service, crm, device) (1e37fd9)
  • add close button to all webhook notifications (d9de15a)
  • add MULENPAY_WEBSITE_URL setting for post-payment redirect (fe5f5de)
  • add RemnaWave incoming webhooks for real-time subscription events (6d67cad)
  • handle errors.bandwidth_usage_threshold_reached_max_notifications webhook (8e85e24)
  • handle service.subpage_config_changed webhook event (43a326a)
  • unified notification delivery for webhook events (email + WS support) (26637f0)
  • webhook protection — prevent sync/monitoring from overwriting webhook data (184c52d)

Bug Fixes

  • add action buttons to webhook notifications and fix empty device names (7091eb9)
  • add missing placeholders to Arabic SUBSCRIPTION_INFO template (fe54640)
  • allow non-HTTP deep links in crypto link webhook updates (f779225)
  • build composite device name from platform + hwid short suffix (17ce640)
  • downgrade transient API errors (502/503/504) to warning level (ec8eaf5)
  • extract device name from nested hwidUserDevice object (79793c4)
  • preserve payment initiation time in transaction created_at (90d9df8)
  • security and architecture fixes for webhook handlers (dc1e96b)
  • stop CryptoBot webhook retry loop and save cabinet payments to DB (2cb6d73)
  • sync subscription status from panel in user.modified webhook (5156d63)
  • use event field directly as event_name (already includes scope prefix) (9aa22af)
  • webhook:close button not working due to channel check timeout (019fbc1)

3.9.1 (2026-02-10)

Bug Fixes

  • don't delete Heleket invoice message on status check (9943253)
  • safe HTML preview truncation and lazy-load subscription fallback (40d8a6d)
  • use actual DB columns for subscription fallback query (f0e7f8e)

3.9.0 (2026-02-09)

New Features

  • add lite mode functionality with endpoints for retrieval and update (7b0403a)
  • add Persian (fa) locale with complete translations (29a3b39)
  • allow tariff deletion with active subscriptions (ebd6bee)
  • localization: add Persian (fa) locale support and wire it across app flows (cc54a7a)

Bug Fixes

  • nullify payment FK references before deleting transactions in user restoration (0b86f37)
  • prevent sync from overwriting end_date for non-ACTIVE panel users (49871f8)
  • promo code max_uses=0 conversion and trial UX after promo activation (1cae713)
  • skip users with active subscriptions in admin inactive cleanup (e79f598)
  • use selection.period.days instead of selection.period_days (4541016)

Performance

  • cache logo file_id to avoid re-uploading on every message (142ff14)

Refactoring

  • remove "both" mode from BOT_RUN_MODE, keep only polling and webhook (efa3a5d)
  • remove Flask, use FastAPI exclusively for all webhooks (119f463)
  • remove smart auto-activation & activation prompt, fix production bugs (a3903a2)

3.8.0 (2026-02-08)

New Features

  • add admin device management endpoints (c57de10)
  • add admin traffic packages and device limit management (2f90f91)
  • add admin updates endpoint for bot and cabinet releases (11b8ab1)
  • add endpoint for updating user referral commission percent (da6f746)
  • add enrichment data to CSV export (f2dbab6)
  • add server-side sorting for enrichment columns (15c7cc2)
  • add system info endpoint for admin dashboard (02c30f8)
  • add traffic usage enrichment endpoint with devices, spending, dates, last node (5cf3f2f)
  • admin panel enhancements & bug fixes (e6ebf81)

Bug Fixes

  • add debug logging for bulk device response structure (46da31d)
  • add email field to traffic table for OAuth/email users (94fcf20)
  • add email/UUID fallback for OAuth user panel sync (165965d)
  • add enrichment device mapping debug logs (5be82f2)
  • include additional devices in tariff renewal price and display (17e9259)
  • paginate bulk device endpoint to fetch all HWID devices (4648a82)
  • read bot version from pyproject.toml when VERSION env is not set (9828ff0)
  • revert device pagination, add raw user data field discovery (8f7fa76)
  • use bulk device endpoint instead of per-user calls (5f219c3)
  • use correct pagination params (start/size) for bulk HWID devices (17af51c)
  • use per-user panel endpoints for reliable device counts and last node data (9d39901)

3.7.2 (2026-02-08)

Bug Fixes

  • handle FK violation in create_yookassa_payment when user is deleted (55d281b)
  • remove dots from Remnawave username sanitization (d6fa86b)

3.7.1 (2026-02-08)

Bug Fixes

  • release-please config — remove blocked workflow files (d88ca98)
  • remove workflow files and pyproject.toml from release-please extra-files (5070bb3)
  • resolve HWID reset and webhook FK violation (5f3e426)
  • resolve HWID reset context manager bug and webhook FK violation (a9eee19)
  • resolve merge conflict in release-please config (0ef4f55)
  • resolve multiple production errors and performance issues (071c23d)

3.7.0 (2026-02-07)

Features

  • add admin traffic usage API (aa1cd38)
  • add admin traffic usage API with per-node statistics (6c2c25d)
  • add node/status filters and custom date range to traffic page (ad260d9)
  • add node/status filters, custom date range, connected devices to traffic page (9ea533a)
  • add node/status filters, date range, devices to traffic page (ad6522f)
  • add risk columns to traffic CSV export (7c1a142)
  • add tariff filter, fix traffic data aggregation (fa01819)
  • node/status filters + custom date range for traffic page (a161e2f)
  • tariff filter + fix traffic data aggregation (1021c2c)
  • traffic filters, date range & risk columns in CSV export (4c40b5b)

Bug Fixes

  • close unclosed HTML tags in version notification (0b61c7f)
  • close unclosed HTML tags when truncating version notification (b674550)
  • correct response parsing for non-legacy node-users endpoint (a076dfb)
  • correct response parsing for non-legacy node-users endpoint (91ac90c)
  • handle mixed types in traffic sort (eeed2d6)
  • handle mixed types in traffic sort for string fields (a194be0)
  • resolve 429 rate limiting on traffic page (b12544d)
  • resolve 429 rate limiting on traffic page (924d6bc)
  • use legacy per-node endpoint for traffic aggregation (cc1c8ba)
  • use legacy per-node endpoint with correct response format (b707b79)
  • use PaymentService for cabinet YooKassa payments (61bb8fc)
  • use PaymentService for cabinet YooKassa payments to save local DB record (ff5bba3)

3.6.0 (2026-02-07)

Features

  • add OAuth 2.0 authorization (Google, Yandex, Discord, VK) (97be4af)
  • add panel info, node usage endpoints and campaign to user detail (287a43b)
  • add panel info, node usage endpoints and campaign to user detail (0703212)
  • add TRIAL_DISABLED_FOR setting to disable trial by user type (c4794db)
  • add user_id filter to admin tickets endpoint (8886d0d)
  • add user_id filter to admin tickets endpoint (d3819c4)
  • block registration with disposable email addresses (9ca24ef)
  • block registration with disposable email addresses (116c845)
  • disable trial by user type (email/telegram/all) (4e7438b)
  • migrate OAuth state storage from in-memory to Redis (e9b98b8)
  • OAuth 2.0 authorization (Google, Yandex, Discord, VK) (3cbb9ef)
  • return 30-day daily breakdown for node usage (7102c50)
  • return 30-day daily breakdown for node usage (e4c65ca)

Bug Fixes

  • increase OAuth HTTP timeout to 30s (333a3c5)
  • parse bandwidth stats series format for node usage (557dbf3)
  • parse bandwidth stats series format for node usage (462f7a9)
  • pass tariff object instead of tariff_id to set_tariff_promo_groups (1ffb8a5)
  • query per-node legacy endpoint for user traffic breakdown (b94e3ed)
  • query per-node legacy endpoint for user traffic breakdown (51ca3e4)
  • reduce node usage to 2 API calls to avoid 429 rate limit (c68c4e5)
  • reduce node usage to 2 API calls to avoid 429 rate limit (f00a051)
  • use accessible nodes API and fix date format for node usage (943e9a8)
  • use accessible nodes API and fix date format for node usage (c4da591)

3.5.0 (2026-02-06)

Features

  • add tariff reorder API endpoint (4c2e11e)
  • pass platform-level fields from RemnaWave config to frontend (095bc00)
  • serve original RemnaWave config from app-config endpoint (43762ce)
  • tariff reorder API endpoint (085a617)

Bug Fixes

  • enforce blacklist via middleware (561708b)
  • enforce blacklist via middleware instead of per-handler checks (966a599)
  • exclude signature field from Telegram initData HMAC validation (5b64046)
  • improve button URL resolution and pass uiConfig to frontend (0ed98c3)
  • restore unquote for user data parsing in telegram auth (c2cabbe)

Reverts

  • remove signature pop from HMAC validation (4234769)