from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, update, and_, desc from app.models.social import ServiceProvider, Vote, ModerationStatus, Competition, UserScore from app.models.user import User from datetime import datetime async def vote_for_provider(db: AsyncSession, voter_id: int, provider_id: int, vote_value: int): """ Fő logika: Szavazás kezelése -> Validáció -> Jutalmazás vagy Büntetés """ # 1. Ellenőrizzük, szavazott-e már (Upsert logika helyett most egyszerű check) result = await db.execute(select(Vote).where(and_(Vote.user_id == voter_id, Vote.provider_id == provider_id))) existing_vote = result.scalars().first() if existing_vote: # Ha már szavazott, most kihagyjuk a módosítást az egyszerűség kedvéért, # de itt lehetne update-elni a szavazatot. return {"message": "User already voted"} # 2. Új szavazat rögzítése new_vote = Vote(user_id=voter_id, provider_id=provider_id, vote_value=vote_value) db.add(new_vote) # 3. Szolgáltató pontszámának frissítése provider_result = await db.execute(select(ServiceProvider).where(ServiceProvider.id == provider_id)) provider = provider_result.scalars().first() if not provider: return {"error": "Provider not found"} provider.validation_score += vote_value # --- THRESHOLD LOGIC (A Lényeg) --- # ESET A: JÓVÁHAGYÁS (Score >= 5) if provider.status == ModerationStatus.pending and provider.validation_score >= 5: provider.status = ModerationStatus.approved # Jutalmazás await _reward_submitter(db, provider.added_by_user_id) # ESET B: ELUTASÍTÁS (Score <= -3) elif provider.status == ModerationStatus.pending and provider.validation_score <= -3: provider.status = ModerationStatus.rejected # Büntetés await _penalize_user(db, provider.added_by_user_id) await db.commit() return {"message": "Vote cast successfully", "new_score": provider.validation_score, "status": provider.status} async def _reward_submitter(db: AsyncSession, user_id: int): """Jutalmazza a feltöltőt: Hírnév + Verseny Pontok""" if not user_id: return # 1. Hírnév növelése user_result = await db.execute(select(User).where(User.id == user_id)) user = user_result.scalars().first() if user: user.reputation_score += 1 print(f"--- REWARD: User {user_id} reputation increased to {user.reputation_score}") # 2. Gamification: Aktív verseny keresése now = datetime.utcnow() comp_result = await db.execute(select(Competition).where( and_(Competition.is_active == True, Competition.start_date <= now, Competition.end_date >= now) )) active_competition = comp_result.scalars().first() if active_competition: # Pontszerzés a versenyben score_result = await db.execute(select(UserScore).where( and_(UserScore.user_id == user_id, UserScore.competition_id == active_competition.id) )) user_score = score_result.scalars().first() if not user_score: user_score = UserScore(user_id=user_id, competition_id=active_competition.id, points=0) db.add(user_score) user_score.points += 10 print(f"--- GAMIFICATION: User {user_id} awarded 10 points in '{active_competition.name}'") async def _penalize_user(db: AsyncSession, user_id: int): """Bünteti a rossz feltöltőt: Hírnév csökkentés + Auto Ban""" if not user_id: return user_result = await db.execute(select(User).where(User.id == user_id)) user = user_result.scalars().first() if user: user.reputation_score -= 2 print(f"--- PENALTY: User {user_id} reputation decreased to {user.reputation_score}") # Auto-Ban logika if user.reputation_score <= -10: user.is_active = False print(f"--- SECURITY ALERT: User {user_id} has been AUTO-BANNED due to low reputation!") async def get_leaderboard(db: AsyncSession, competition_id: int): """Visszaadja a TOP 10 felhasználót""" result = await db.execute( select(UserScore, User.full_name) .join(User, UserScore.user_id == User.id) .where(UserScore.competition_id == competition_id) .order_by(desc(UserScore.points)) .limit(10) ) return result.all()