Initial commit - MIDAS App educação financeira para apostadores (FastAPI + Next.js)

This commit is contained in:
bigtux
2026-02-10 18:52:23 -03:00
commit 954ebccdd6
31 changed files with 1701 additions and 0 deletions

View File

@@ -0,0 +1,79 @@
from datetime import datetime, timedelta
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func
from app.models.bet import Bet
from app.models.bankroll import Bankroll
async def calculate_risk_score(user_id, db: AsyncSession) -> dict:
score = 0
factors = []
now = datetime.utcnow()
# 1. Horário noturno (22h-5h) +15
hour = now.hour
if hour >= 22 or hour < 5:
score += 15
factors.append("Apostando em horário noturno")
# 2. Valor crescente +25
recent = await db.execute(
select(Bet).where(Bet.user_id == user_id).order_by(Bet.created_at.desc()).limit(5)
)
recent_bets = recent.scalars().all()
if len(recent_bets) >= 3:
amounts = [float(b.amount) for b in recent_bets[:3]]
if amounts[0] > amounts[1] > amounts[2]:
score += 25
factors.append("Valores de aposta crescentes")
# 3. Recuperação (aposta logo após loss) +30
if len(recent_bets) >= 2:
last = recent_bets[0]
prev = recent_bets[1]
if prev.result == "loss" and last.created_at and prev.created_at:
diff = (last.created_at - prev.created_at).total_seconds()
if diff < 1800: # 30 min
score += 30
factors.append("Tentativa de recuperação após perda")
# 4. Frequência alta (>5 apostas em 24h) +20
day_ago = now - timedelta(hours=24)
count_result = await db.execute(
select(func.count()).select_from(Bet).where(Bet.user_id == user_id, Bet.created_at >= day_ago)
)
bet_count = count_result.scalar() or 0
if bet_count > 5:
score += 20
factors.append(f"Alta frequência: {bet_count} apostas em 24h")
# 5. Limite estourado +25
br_result = await db.execute(select(Bankroll).where(Bankroll.user_id == user_id))
bankroll = br_result.scalar_one_or_none()
if bankroll and float(bankroll.month_spent) > float(bankroll.monthly_budget):
score += 25
factors.append("Limite mensal ultrapassado")
# 6. Emoção negativa +15
if recent_bets and recent_bets[0].emotion in ["😤", "😰", "tilt", "ansioso", "frustrado"]:
score += 15
factors.append("Emoção negativa detectada")
# 7. Sequência de perdas +20
loss_streak = 0
for b in recent_bets:
if b.result == "loss":
loss_streak += 1
else:
break
if loss_streak >= 3:
score += 20
factors.append(f"Sequência de {loss_streak} perdas consecutivas")
if score <= 30:
level = "green"
elif score <= 60:
level = "yellow"
else:
level = "red"
return {"score": score, "level": level, "factors": factors}