268 KiB
268 KiB
Changelog
3.53.0 (2026-04-29)
New Features
- add bulk_actions, info_pages, news to PERMISSION_REGISTRY (06db393)
- per-category enable/disable for admin notifications (fb857d7)
- protect active paid subscriptions from bulk delete (51dfc3a)
- subscription request history API + RemnaWave panel method (e22beb7)
Bug Fixes
- add 5 missing payment providers to pending-payments model_map (a506c6b)
- add 6 missing payment providers to payment_utils availability checks (83efc21)
- add RollyPay, PayPear, Overpay, AuraPay to REAL_PAYMENT_METHODS (ff7b190)
- autopay renewing trial subscriptions at classic-mode pricing (2fbdbf5)
- backup completeness — add 15 missing tables, accept .tar.gz uploads (eafb243)
- backup import crash + upload handler hardening (5cf19c7)
- block/unblock endpoints — correct args, response schema, panel sync (0bcb804)
- cabinet /block endpoint now disables panel user in RemnaWave (735e16a)
- cabinet autopay endpoint — same NULL-safe is_trial guard (29e177d)
- cabinet purchase fails after panel user deletion — stale UUID (f37eb9a)
- callback.answer() before heavy operations to prevent query timeout (579e4f2)
- create locales directory with correct permissions in Dockerfile (74999fe)
- deadlock on user deletion — webhook handler never checked intentional mark (62e7ecb)
- device/traffic addon pricing — use ceil instead of floor for days_left (cf60ae2)
- downgrade Pal24 API validation errors from error to debug (c905fa6)
- false subscription expiry notifications — 4 bugs fixed (134e7fb)
- handle A018 error code as user-not-found fallback to create_user (c619dbc)
- handle A018 error code in admin_users sync endpoints (2 more locations) (59080f7)
- media upload leaks staging photo to admin chat (1110d0c)
- panel sync subscription duration — ceil for days_remaining (527c5b4)
- PayPear webhook signature — strip signature field before hashing + IP fallback (443a826)
- PollResponse has no created_at — use sent_at for ordering (768e0b6)
- promo group discount applied to restricted tariffs in autopay (4ab5928)
- referral links now clickable — remove <code> wrapping (43dd0fd)
- remaining pricing-critical .days floor calculations → math.ceil (bada41e)
- replace all late callback.answer() with edit_text for error feedback (c743fc8)
- retry queue action uses _should_create instead of stale subscription UUID (422844d)
- send admin notification on promo code activation from cabinet (1c38b31)
- subscription-request-history — correct API client usage, add ownership check (1fc04d8)
- traffic addon discount also bypassed tariff-promo-group check (47c7d45)
- traffic addon price mismatch — keyboard showed prorated, handler charged full month (a88e3c8)
- update cabinet_last_login on every request (throttled, 5 min) (91de6d0)
Refactoring
- remove unused EXTERNAL_ADMIN_TOKEN functionality (b9b6957)
3.52.1 (2026-04-24)
Bug Fixes
- broadcast preview count — add .correlate(User) to EXISTS subqueries (63e1127)
- ignore bot's own messages in unknown message handlers (52bf2a9)
- unpin messages in Telegram BEFORE deactivating in DB (ab4661b)
- use fresh DB session for deactivate after long unpin loop (5ed9a0d)
3.52.0 (2026-04-24)
New Features
- admin bulk actions API — mass operations on users (fb2773f)
- bulk actions — campaign/partner filters, delete_user action (d77fd81)
- bulk actions — SSE streaming progress, grant subscription, multi-tariff info (c0e0756)
- bulk delete_subscription action — removes from bot DB + RemnaWave (605f202)
- bulk set_devices action + device info in subscription list (be787a8)
- FAQ support in info pages — page_type field + migration (d394565)
- info page tab replacement — replaces_tab field + API (bdb8cab)
- information pages — CRUD model, admin API, public API (e4b4a54)
- multi-tariff bulk actions — subscription-level targeting (e78177b)
- support multiple tariff_ids in user list filter (0d2b1df)
Bug Fixes
- /reorder route unreachable — move before /{page_id} path param (122d12d)
- add subscription/tariff/promo_group filters to admin user list API (daa4725)
- always return subscriptions list in user list API (cfbcc30)
- bulk actions review — rollback on error, multi-tariff constraint checks (5b45d43)
- bulk change_tariff not clearing squads when new tariff has none (db7b673)
- bulk delete_user — pass real admin_id, sanitize error messages (2e45a93)
- gift purchases no longer inflate promo group level (1522d35)
- info pages review — deduplicate slug index, type reorder items (2071a68)
- integrate Yandex Metrika offline conv + S2S postback hooks (7d512d2)
- MissingGreenlet in subscription-ids bulk actions (2ad893b)
- privacy policy and offer text display HTML links as plain text (59c54c9)
- restore HTTP Referer fallback for landing purchases (24dc8d2)
- restore referrer field in admin landing purchases response (2cde38c)
- sanitize error messages in all bulk action catch-all handlers (9217f41)
- server squad sync fails on fresh DB without default promo group (ae7feeb)
- stop printing tracebacks for warning-level logs inside except blocks (68d2350)
- suppress 'User already enabled' traceback in bulk add_traffic (ff41ea9)
Documentation
- add Overpay to README with partner block (bcf5519)
- add Overpay to README with partner block (70568f8)
3.51.0 (2026-04-23)
New Features
- integrate Overpay payment provider (pay.overpay.io) (2c3ffc8)
- respond to unknown media messages (photos, videos, documents) (29ae708)
Bug Fixes
- inactive user cleanup deletes users with paid subscriptions (7005052)
- pad short RemnaWave usernames to meet 3-char minimum (6f87563)
3.50.0 (2026-04-22)
New Features
- add WEBHOOK_IP to allow Telegram bypass DNS lookup for webhook (#2894) (7093d36)
- landing page analytics goals and sticky pay button (3272b4b)
- tariff switch direction control, fix device pricing within tariff limit (9ed4f08)
- tickets: multi-media message gallery (media_items JSONB) (36571c4)
- v3.50.0 release (a491fe3)
- Yandex Metrika offline conversions + S2S postbacks (1068c13)
Bug Fixes
- classic mode renewal resets device_limit to 1 via cart key mismatch (9ca3320)
- do not reset subscription_crypto_link when cryptoLink absent in webhook (#2891) (b71e58c)
- do not update first_name/last_name from OIDC claims (#2892) (1696e6f)
- FSM state loss on balance topup, PayPear confirmation_url, hidden trial tariff in renewal (7be404b)
- grant all available squads for unrestricted trials (#2897) (905cea6)
- menu layout schema icon limit, traffic_topup_enabled condition, shadowing imports (66f8577)
- tariff switch pricing showing free for upgrades, admin duplicate subscription guard (da855a7)
- ticket media_items review fixes (dd17710)
- validate analytics goal is set when analytics is enabled on landing (d316325)
- устранить MissingGreenlet в автоплатежах и починить traceback в логах (db79cc9)
- устранить root cause MissingGreenlet в автоплатежах через refetch по id (3b03c25)
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)