From 0b86f379b4e55e499ca3d189137e2aed865774b5 Mon Sep 17 00:00:00 2001 From: Fringg Date: Mon, 9 Feb 2026 17:19:45 +0300 Subject: [PATCH] fix: nullify payment FK references before deleting transactions in user restoration The user restoration flow deleted transactions without first clearing foreign key references from payment tables (yookassa_payments, cryptobot_payments, etc.) and referral_earnings. This caused IntegrityError when a deleted user had payment records linked to transactions. --- app/handlers/start.py | 47 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/app/handlers/start.py b/app/handlers/start.py index 4d8a0198..ba53a8c0 100644 --- a/app/handlers/start.py +++ b/app/handlers/start.py @@ -486,9 +486,24 @@ async def cmd_start(message: types.Message, state: FSMContext, db: AsyncSession, logger.info(f'🔄 Удаленный пользователь {user.telegram_id} начинает повторную регистрацию') try: - from sqlalchemy import delete + from sqlalchemy import delete, update as sa_update - from app.database.models import PromoCodeUse, ReferralEarning, SubscriptionServer, Transaction + from app.database.models import ( + CloudPaymentsPayment, + CryptoBotPayment, + FreekassaPayment, + HeleketPayment, + KassaAiPayment, + MulenPayPayment, + Pal24Payment, + PlategaPayment, + PromoCodeUse, + ReferralEarning, + SubscriptionServer, + Transaction, + WataPayment, + YooKassaPayment, + ) if user.subscription: await decrement_subscription_server_counts(db, user.subscription) @@ -503,9 +518,37 @@ async def cmd_start(message: types.Message, state: FSMContext, db: AsyncSession, await db.execute(delete(PromoCodeUse).where(PromoCodeUse.user_id == user.id)) + await db.execute( + sa_update(ReferralEarning) + .where(ReferralEarning.user_id == user.id) + .values(referral_transaction_id=None) + ) + await db.execute( + sa_update(ReferralEarning) + .where(ReferralEarning.referral_id == user.id) + .values(referral_transaction_id=None) + ) await db.execute(delete(ReferralEarning).where(ReferralEarning.user_id == user.id)) await db.execute(delete(ReferralEarning).where(ReferralEarning.referral_id == user.id)) + # Обнуляем transaction_id во всех таблицах платежей перед удалением транзакций + payment_models = [ + YooKassaPayment, + CryptoBotPayment, + HeleketPayment, + MulenPayPayment, + Pal24Payment, + WataPayment, + PlategaPayment, + CloudPaymentsPayment, + FreekassaPayment, + KassaAiPayment, + ] + for payment_model in payment_models: + await db.execute( + sa_update(payment_model).where(payment_model.user_id == user.id).values(transaction_id=None) + ) + await db.execute(delete(Transaction).where(Transaction.user_id == user.id)) user.status = UserStatus.ACTIVE.value