fix: устранена отправка externalSquadUuid=null в RemnaWave API (A039) и исправлен reduce_devices

- reduce_devices: убрано молчаливое проглатывание ошибки RemnaWave, теперь при неудаче делается rollback и возвращается HTTP 502
- Убрана отправка external_squad_uuid=None в 8 местах: subscription_service, monitoring_service, remnawave_service, admin/users, cabinet/admin_users
This commit is contained in:
Fringg
2026-03-16 03:25:24 +03:00
parent 8d3cd50098
commit e453521098
6 changed files with 33 additions and 31 deletions
+4 -6
View File
@@ -318,11 +318,10 @@ async def _sync_subscription_to_panel(
if hwid_limit is not None:
update_kwargs['hwid_device_limit'] = hwid_limit
# Внешний сквад: синхронизируем из тарифа или сбрасываем
# Внешний сквад: синхронизируем из тарифа (если задан)
# Не отправляем null — RemnaWave API не принимает null для externalSquadUuid (A039)
if ext_squad_uuid is not None:
update_kwargs['external_squad_uuid'] = ext_squad_uuid
else:
update_kwargs['external_squad_uuid'] = None
try:
updated_panel_user = await api.update_user(**update_kwargs)
@@ -2777,11 +2776,10 @@ async def sync_user_to_panel(
update_kwargs['hwid_device_limit'] = hwid_limit
changes['device_limit'] = hwid_limit
# Внешний сквад: синхронизируем из тарифа или сбрасываем
# Внешний сквад: синхронизируем из тарифа (если задан)
# Не отправляем null — RemnaWave API не принимает null для externalSquadUuid (A039)
if ext_squad_uuid is not None:
update_kwargs['external_squad_uuid'] = ext_squad_uuid
else:
update_kwargs['external_squad_uuid'] = None
try:
await api.update_user(**update_kwargs)
+18 -8
View File
@@ -3762,17 +3762,27 @@ async def reduce_devices(
old_device_limit = current_device_limit
# Update subscription
# Update subscription in memory (will be committed by update_remnawave_user on success)
subscription.device_limit = new_device_limit
subscription.updated_at = datetime.now(UTC)
await db.commit()
# Update RemnaWave
try:
subscription_service = SubscriptionService()
await subscription_service.update_remnawave_user(db, subscription)
except Exception as e:
logger.error('Error updating RemnaWave user', error=e)
# Update RemnaWave — commits on success, returns None on failure
subscription_service = SubscriptionService()
result = await subscription_service.update_remnawave_user(db, subscription)
if result is None:
# RemnaWave update failed — rollback local changes
await db.rollback()
logger.error(
'Failed to update RemnaWave after device limit reduction',
user_id=user.id,
old_device_limit=old_device_limit,
new_device_limit=new_device_limit,
)
raise HTTPException(
status_code=status.HTTP_502_BAD_GATEWAY,
detail='Не удалось обновить VPN-панель. Попробуйте позже.',
)
logger.info(
f'User {user.id} reduced device limit from {old_device_limit} to {new_device_limit}'
+2 -3
View File
@@ -4590,11 +4590,10 @@ async def admin_buy_subscription_execute(callback: types.CallbackQuery, db_user:
if hwid_limit is not None:
update_kwargs['hwid_device_limit'] = hwid_limit
# Внешний сквад: синхронизируем из тарифа или сбрасываем
# Внешний сквад: синхронизируем из тарифа (если задан)
# Не отправляем null — RemnaWave API не принимает null для externalSquadUuid (A039)
if ext_squad_uuid is not None:
update_kwargs['external_squad_uuid'] = ext_squad_uuid
else:
update_kwargs['external_squad_uuid'] = None
remnawave_user = await api.update_user(**update_kwargs)
else:
+2 -3
View File
@@ -390,11 +390,10 @@ class MonitoringService:
if hwid_limit is not None:
update_kwargs['hwid_device_limit'] = hwid_limit
# Внешний сквад: синхронизируем из тарифа или сбрасываем
# Внешний сквад: синхронизируем из тарифа (если задан)
# Не отправляем null — RemnaWave API не принимает null для externalSquadUuid (A039)
if subscription.tariff and subscription.tariff.external_squad_uuid:
update_kwargs['external_squad_uuid'] = subscription.tariff.external_squad_uuid
else:
update_kwargs['external_squad_uuid'] = None
updated_user = await api.update_user(**update_kwargs)
+4 -6
View File
@@ -1961,11 +1961,10 @@ class RemnaWaveService:
if hwid_limit is not None:
create_kwargs['hwid_device_limit'] = hwid_limit
# Внешний сквад: синхронизируем из тарифа или сбрасываем
# Внешний сквад: синхронизируем из тарифа (если задан)
# Не отправляем null — RemnaWave API не принимает null для externalSquadUuid (A039)
if sub.tariff and sub.tariff.external_squad_uuid:
create_kwargs['external_squad_uuid'] = sub.tariff.external_squad_uuid
else:
create_kwargs['external_squad_uuid'] = None
# Определяем UUID для обновления
panel_uuid = user.remnawave_uuid
@@ -2007,11 +2006,10 @@ class RemnaWaveService:
if hwid_limit is not None:
update_kwargs['hwid_device_limit'] = hwid_limit
# Внешний сквад: синхронизируем из тарифа или сбрасываем
# Внешний сквад: синхронизируем из тарифа (если задан)
# Не отправляем null — RemnaWave API не принимает null для externalSquadUuid (A039)
if sub.tariff and sub.tariff.external_squad_uuid:
update_kwargs['external_squad_uuid'] = sub.tariff.external_squad_uuid
else:
update_kwargs['external_squad_uuid'] = None
try:
await api.update_user(**update_kwargs)
+3 -5
View File
@@ -238,11 +238,10 @@ class SubscriptionService:
if hwid_limit is not None:
update_kwargs['hwid_device_limit'] = hwid_limit
# Внешний сквад: назначаем из тарифа или сбрасываем
# Внешний сквад: назначаем из тарифа (если задан)
# Не отправляем null — RemnaWave API не принимает null для externalSquadUuid (A039)
if ext_squad_uuid is not None:
update_kwargs['external_squad_uuid'] = ext_squad_uuid
else:
update_kwargs['external_squad_uuid'] = None
updated_user = await api.update_user(**update_kwargs)
@@ -872,10 +871,9 @@ class SubscriptionService:
if hwid_limit is not None:
update_kwargs['hwid_device_limit'] = hwid_limit
# Не отправляем null — RemnaWave API не принимает null для externalSquadUuid (A039)
if ext_squad_uuid is not None:
update_kwargs['external_squad_uuid'] = ext_squad_uuid
else:
update_kwargs['external_squad_uuid'] = None
updated_user = await api.update_user(**update_kwargs)