from sqlalchemy.orm import Session from fastapi import HTTPException from datetime import datetime from app.models.user import User, CreditTransaction def deduct_credits(db: Session, user: User, amount: int, concept: str, reference_id: str = None) -> int: """ Deduce `amount` de créditos del usuario y registra la transacción. Si no tiene suficientes créditos, lanza HTTPException 402 (Payment Required). Retorna la cantidad de créditos restantes. """ if user.credits < amount: raise HTTPException( status_code=402, detail=f"Créditos insuficientes. Se requieren {amount} créditos para esta operación (tienes {user.credits})." ) # Restar créditos del usuario user.credits -= amount # Crear transacción de deducción (monto negativo) tx = CreditTransaction( user_id=user.id, amount=-amount, concept=concept, reference_id=str(reference_id) if reference_id is not None else None, created_at=datetime.utcnow() ) db.add(tx) db.commit() db.refresh(user) # Notificar al usuario por WebSocket en tiempo real de su deducción de créditos try: from app.websocket_manager import send_sync_message send_sync_message({ "type": "user_credits_updated", "credits": user.credits }, user.id) except Exception: # Silenciamos cualquier error de WebSocket para no arruinar la transacción principal pass return user.credits