From cf13b49b3cf59f69effff3c848fed6cec5066bbe Mon Sep 17 00:00:00 2001 From: Egor Date: Wed, 8 Oct 2025 06:26:41 +0300 Subject: [PATCH] Fix server squad user counters on removal --- app/handlers/start.py | 25 ++++++++++++++ app/handlers/subscription.py | 28 ++++++++++++---- app/services/remnawave_service.py | 55 ++++++++++++++++++++++++++++++- app/services/user_service.py | 25 ++++++++++++++ 4 files changed, 126 insertions(+), 7 deletions(-) diff --git a/app/handlers/start.py b/app/handlers/start.py index 94367a60..796233b2 100644 --- a/app/handlers/start.py +++ b/app/handlers/start.py @@ -371,6 +371,31 @@ async def cmd_start(message: types.Message, state: FSMContext, db: AsyncSession, from sqlalchemy import delete if user.subscription: + try: + from app.database.crud.subscription import get_subscription_server_ids + from app.database.crud.server_squad import ( + get_server_ids_by_uuids, + remove_user_from_servers, + ) + + removed_server_ids = set( + await get_subscription_server_ids(db, user.subscription.id) + ) + + if user.subscription.connected_squads: + removed_server_ids.update( + await get_server_ids_by_uuids( + db, user.subscription.connected_squads + ) + ) + + if removed_server_ids: + await remove_user_from_servers(db, list(removed_server_ids)) + except Exception as counter_error: + logger.error( + f"❌ Ошибка обновления счетчиков серверов при повторной регистрации {user.telegram_id}: {counter_error}" + ) + await db.execute( delete(SubscriptionServer).where( SubscriptionServer.subscription_id == user.subscription.id diff --git a/app/handlers/subscription.py b/app/handlers/subscription.py index 53a4084d..2d9a848e 100644 --- a/app/handlers/subscription.py +++ b/app/handlers/subscription.py @@ -1610,19 +1610,35 @@ async def apply_countries_changes( description=f"Добавление стран к подписке: {', '.join(added_names)} на {charged_months} мес" ) - if added: - from app.database.crud.server_squad import get_server_ids_by_uuids, add_user_to_servers - from app.database.crud.subscription import add_subscription_servers + if added or removed: + from app.database.crud.server_squad import ( + get_server_ids_by_uuids, + add_user_to_servers, + remove_user_from_servers, + ) + from app.database.crud.subscription import ( + add_subscription_servers, + remove_subscription_servers, + ) - added_server_ids = await get_server_ids_by_uuids(db, added) + added_server_ids = await get_server_ids_by_uuids(db, added) if added else [] + removed_server_ids = await get_server_ids_by_uuids(db, removed) if removed else [] if added_server_ids: await add_subscription_servers(db, subscription, added_server_ids, added_server_prices) await add_user_to_servers(db, added_server_ids) logger.info( - f"📊 Добавлены серверы с ценами за {charged_months} мес: {list(zip(added_server_ids, added_server_prices))}") + f"📊 Добавлены серверы с ценами за {charged_months} мес: {list(zip(added_server_ids, added_server_prices))}" + ) + if removed_server_ids: + await remove_subscription_servers(db, subscription.id, removed_server_ids) + await remove_user_from_servers(db, removed_server_ids) + + logger.info( + f"📉 Удалены серверы из подписки {subscription.id}: {removed_server_ids}" + ) subscription.connected_squads = selected_countries subscription.updated_at = datetime.utcnow() await db.commit() @@ -6642,4 +6658,4 @@ def register_handlers(dp: Dispatcher): dp.callback_query.register( show_device_connection_help, F.data == "device_connection_help" - ) \ No newline at end of file + ) diff --git a/app/services/remnawave_service.py b/app/services/remnawave_service.py index 310513ae..79c033b1 100644 --- a/app/services/remnawave_service.py +++ b/app/services/remnawave_service.py @@ -621,7 +621,24 @@ class RemnaWaveService: try: from sqlalchemy import delete from app.database.models import SubscriptionServer - + from app.database.crud.subscription import get_subscription_server_ids + from app.database.crud.server_squad import ( + get_server_ids_by_uuids, + remove_user_from_servers, + ) + + removed_server_ids = set( + await get_subscription_server_ids(db, subscription.id) + ) + + if subscription.connected_squads: + removed_server_ids.update( + await get_server_ids_by_uuids(db, subscription.connected_squads) + ) + + if removed_server_ids: + await remove_user_from_servers(db, list(removed_server_ids)) + await db.execute( delete(SubscriptionServer).where( SubscriptionServer.subscription_id == subscription.id @@ -1174,6 +1191,42 @@ class RemnaWaveService: user.updated_at = self._now_in_panel_timezone() if user.subscription: + try: + from sqlalchemy import delete + from app.database.models import SubscriptionServer + from app.database.crud.subscription import get_subscription_server_ids + from app.database.crud.server_squad import ( + get_server_ids_by_uuids, + remove_user_from_servers, + ) + + removed_server_ids = set( + await get_subscription_server_ids(db, user.subscription.id) + ) + + if user.subscription.connected_squads: + removed_server_ids.update( + await get_server_ids_by_uuids( + db, user.subscription.connected_squads + ) + ) + + if removed_server_ids: + await remove_user_from_servers(db, list(removed_server_ids)) + + await db.execute( + delete(SubscriptionServer).where( + SubscriptionServer.subscription_id == user.subscription.id + ) + ) + logger.info( + f"🗑️ Удалены привязанные серверы подписки для пользователя {user.telegram_id}" + ) + except Exception as servers_error: + logger.error( + f"❌ Ошибка удаления серверов подписки при очистке пользователя {user.telegram_id}: {servers_error}" + ) + user.subscription.status = SubscriptionStatus.DISABLED.value user.subscription.is_trial = True user.subscription.end_date = self._now_in_panel_timezone() diff --git a/app/services/user_service.py b/app/services/user_service.py index 89a6139a..5c98510a 100644 --- a/app/services/user_service.py +++ b/app/services/user_service.py @@ -537,6 +537,31 @@ class UserService: if subscription_servers: logger.info(f"🔄 Удаляем {len(subscription_servers)} связей подписка-сервер") + + try: + from app.database.crud.server_squad import ( + get_server_ids_by_uuids, + remove_user_from_servers, + ) + + removed_server_ids = { + sub_server.server_squad_id for sub_server in subscription_servers + } + + if user.subscription.connected_squads: + removed_server_ids.update( + await get_server_ids_by_uuids( + db, user.subscription.connected_squads + ) + ) + + if removed_server_ids: + await remove_user_from_servers(db, list(removed_server_ids)) + except Exception as counter_error: + logger.error( + f"❌ Ошибка обновления счетчиков серверов при удалении пользователя {user.telegram_id}: {counter_error}" + ) + await db.execute( delete(SubscriptionServer).where( SubscriptionServer.subscription_id == user.subscription.id