admin_szolgáltatók_
This commit is contained in:
@@ -286,8 +286,8 @@ class AssetService:
|
||||
))
|
||||
|
||||
# Gamification
|
||||
reward = await config.get_setting(db, "xp_reward_asset_register", default=250)
|
||||
await GamificationService.award_points(db, user_id, int(reward), "NEW_ASSET_REG")
|
||||
# A pontérték a point_rules táblából jön (action_key='ASSET_REGISTER')
|
||||
await GamificationService.award_points(db, user_id, amount=0, reason="ASSET_REGISTER", action_key="ASSET_REGISTER")
|
||||
|
||||
# Check if this is user's first vehicle and award "First Car" badge
|
||||
await AssetService._award_first_car_badge(db, user_id, target_org_id)
|
||||
|
||||
@@ -295,19 +295,21 @@ class AuthService:
|
||||
user.region_code = kyc_in.region_code
|
||||
|
||||
# Gamification XP jóváírás (commit=False, mert a külső metódus kezeli a tranzakciót)
|
||||
await GamificationService.award_points(db, user_id=user.id, amount=int(kyc_reward), reason="KYC_VERIFICATION", commit=False)
|
||||
# A pontérték a point_rules táblából jön (action_key='KYC_VERIFICATION')
|
||||
await GamificationService.award_points(db, user_id=user.id, amount=0, reason="KYC_VERIFICATION", commit=False, action_key="KYC_VERIFICATION")
|
||||
|
||||
# P2P Referral XP a meghívónak (ha van referred_by_id)
|
||||
if user.referred_by_id:
|
||||
p2p_xp = await config.get_setting(db, "gamification_p2p_invite_xp", default=50)
|
||||
# A pontérték a point_rules táblából jön (action_key='P2P_REFERRAL_SUCCESS')
|
||||
await GamificationService.award_points(
|
||||
db,
|
||||
user_id=user.referred_by_id,
|
||||
amount=int(p2p_xp),
|
||||
amount=0,
|
||||
reason="P2P_REFERRAL_SUCCESS",
|
||||
commit=False
|
||||
commit=False,
|
||||
action_key="P2P_REFERRAL_SUCCESS"
|
||||
)
|
||||
logger.info(f"P2P XP ({p2p_xp}) awarded to referrer ID {user.referred_by_id} for user {user.id}")
|
||||
logger.info(f"P2P XP awarded to referrer ID {user.referred_by_id} for user {user.id}")
|
||||
|
||||
await db.commit()
|
||||
return user
|
||||
|
||||
@@ -25,8 +25,6 @@ class CostService:
|
||||
try:
|
||||
# 1. Dinamikus konfiguráció lekérése
|
||||
base_currency = await config.get_setting(db, "finance_base_currency", default="EUR")
|
||||
base_xp = await config.get_setting(db, "xp_per_cost_log", default=50)
|
||||
ocr_multiplier = await config.get_setting(db, "xp_multiplier_ocr_cost", default=1.5)
|
||||
|
||||
# 2. Intelligens Árfolyamkezelés
|
||||
exchange_rate = Decimal("1.0")
|
||||
@@ -66,12 +64,10 @@ class CostService:
|
||||
await self._sync_telemetry(db, cost_in.asset_id, cost_in.mileage_at_cost)
|
||||
|
||||
# 5. Gamification (Értékesebb az adat, ha van róla fotó/OCR)
|
||||
final_xp = base_xp
|
||||
if new_cost.is_ai_generated:
|
||||
final_xp = int(base_xp * float(ocr_multiplier))
|
||||
|
||||
# A pontérték a point_rules táblából jön (action_key='EXPENSE_LOG')
|
||||
# Az OCR bónusz továbbra is érvényesül a process_activity szorzóin keresztül
|
||||
await GamificationService.award_points(
|
||||
db, user_id=user_id, amount=final_xp, reason=f"EXPENSE_LOG_{cost_in.cost_type}"
|
||||
db, user_id=user_id, amount=0, reason=f"EXPENSE_LOG_{cost_in.cost_type}", action_key="EXPENSE_LOG"
|
||||
)
|
||||
|
||||
await db.commit()
|
||||
|
||||
@@ -82,15 +82,17 @@ class FleetService:
|
||||
db.add(new_event)
|
||||
|
||||
# 6. DINAMIKUS GAMIFIKÁCIÓ
|
||||
# Kikeresjük a konkrét eseménytípushoz tartozó pontokat
|
||||
# A pontérték a point_rules táblából jön (action_key='FLEET_EVENT')
|
||||
# A social pont továbbra is az event_rewards konfigurációból jön
|
||||
rewards = event_rewards.get(event_data.event_type, event_rewards["default"])
|
||||
|
||||
await gamification_service.process_activity(
|
||||
db,
|
||||
user_id,
|
||||
xp_amount=rewards["xp"],
|
||||
social_amount=rewards["social"],
|
||||
reason=f"FLEET_EVENT_{event_data.event_type.upper()}"
|
||||
db,
|
||||
user_id,
|
||||
xp_amount=0,
|
||||
social_amount=rewards["social"],
|
||||
reason=f"FLEET_EVENT_{event_data.event_type.upper()}",
|
||||
action_key="FLEET_EVENT"
|
||||
)
|
||||
|
||||
await db.commit()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# /opt/docker/dev/service_finder/backend/app/services/gamification_service.py
|
||||
import logging
|
||||
import math
|
||||
from copy import deepcopy
|
||||
from decimal import Decimal
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select, desc
|
||||
@@ -12,6 +13,25 @@ from app.services.config_service import config # 2.0 Központi konfigurátor
|
||||
|
||||
logger = logging.getLogger("Gamification-Service-2.0")
|
||||
|
||||
|
||||
def _deep_merge_config(base: dict, overlay: dict) -> dict:
|
||||
"""
|
||||
Rekurzívan egyesít két dictionary-t.
|
||||
Az overlay kulcsai felülírják a base kulcsait, de a base-ben lévő
|
||||
hiányzó kulcsok megmaradnak az overlay-ből.
|
||||
|
||||
Ez biztosítja, hogy a GAMIFICATION_MASTER_CONFIG minden szükséges
|
||||
kulcsot tartalmazzon, még akkor is, ha az adatbázisban lévő konfiguráció
|
||||
hiányos (pl. régebbi verzióból származik).
|
||||
"""
|
||||
result = deepcopy(base)
|
||||
for key, value in overlay.items():
|
||||
if key in result and isinstance(result[key], dict) and isinstance(value, dict):
|
||||
result[key] = _deep_merge_config(result[key], value)
|
||||
elif key not in result:
|
||||
result[key] = deepcopy(value)
|
||||
return result
|
||||
|
||||
class GamificationService:
|
||||
"""
|
||||
Gamification Service 2.0 - A 'Jövevény' lelke.
|
||||
@@ -22,22 +42,24 @@ class GamificationService:
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
async def award_points(db: AsyncSession, user_id: int, amount: int, reason: str, social_points: int = 0, commit: bool = True):
|
||||
async def award_points(db: AsyncSession, user_id: int, amount: int, reason: str, social_points: int = 0, commit: bool = True, action_key: str | None = None):
|
||||
""" Statikus segédfüggvény a Robotok számára az egyszerűbb híváshoz.
|
||||
|
||||
Args:
|
||||
commit: If True (default), commits the transaction internally.
|
||||
Set to False when called from within a larger transaction
|
||||
(e.g., from AuthService.complete_kyc).
|
||||
action_key: Opcionális. Ha meg van adva, a point_rules táblából
|
||||
olvassa a pontértékeket a master config helyett.
|
||||
"""
|
||||
service = GamificationService()
|
||||
return await service.process_activity(db, user_id, xp_amount=amount, social_amount=social_points, reason=reason, commit=commit)
|
||||
return await service.process_activity(db, user_id, xp_amount=amount, social_amount=social_points, reason=reason, commit=commit, action_key=action_key)
|
||||
|
||||
async def _get_point_rule(self, db: AsyncSession, action_key: str) -> dict | None:
|
||||
"""Lekér egy pontszabályt a point_rules táblából action_key alapján.
|
||||
|
||||
Returns:
|
||||
dict with 'points' and 'description' or None if not found/inactive.
|
||||
dict with 'points', 'description', 'rule_id' or None if not found/inactive.
|
||||
"""
|
||||
stmt = select(PointRule).where(
|
||||
PointRule.action_key == action_key,
|
||||
@@ -46,7 +68,7 @@ class GamificationService:
|
||||
result = await db.execute(stmt)
|
||||
rule = result.scalar_one_or_none()
|
||||
if rule:
|
||||
return {"points": rule.points, "description": rule.description}
|
||||
return {"points": rule.points, "description": rule.description, "rule_id": rule.id}
|
||||
return None
|
||||
|
||||
async def process_activity(
|
||||
@@ -80,7 +102,7 @@ class GamificationService:
|
||||
try:
|
||||
# 1. ADMIN KONFIGURÁCIÓ BETÖLTÉSE
|
||||
# Minden paraméter az admin felületről módosítható JSON-ként
|
||||
cfg = await config.get_setting(db, "GAMIFICATION_MASTER_CONFIG", default={
|
||||
_DEFAULT_GAMIFICATION_CONFIG = {
|
||||
"xp_logic": {"base_xp": 500, "exponent": 1.5},
|
||||
"penalty_logic": {
|
||||
"recovery_rate": 0.5,
|
||||
@@ -89,15 +111,28 @@ class GamificationService:
|
||||
},
|
||||
"conversion_logic": {"social_to_credit_rate": 100},
|
||||
"level_rewards": {"credits_per_10_levels": 50}
|
||||
})
|
||||
}
|
||||
cfg = await config.get_setting(db, "GAMIFICATION_MASTER_CONFIG", default=_DEFAULT_GAMIFICATION_CONFIG)
|
||||
|
||||
# 🔐 HIÁNYZÓ KULCSOK VÉDELME (Deep Merge)
|
||||
# Ha a GAMIFICATION_MASTER_CONFIG már létezik az adatbázisban, de hiányoznak
|
||||
# belőle kulcsok (pl. penalty_logic egy régebbi verzióból), a default értékek
|
||||
# automatikusan kiegészítik a hiányzó részeket.
|
||||
# Ez megakadályozza a KeyError kivételeket a cfg["penalty_logic"] hívásoknál.
|
||||
if isinstance(cfg, dict):
|
||||
cfg = _deep_merge_config(cfg, _DEFAULT_GAMIFICATION_CONFIG)
|
||||
|
||||
# 1/b. POINT RULES TÁBLA LEKÉRÉSE (ha action_key meg van adva)
|
||||
# A point_rules tábla elsőbbséget élvez a master config-gal szemben!
|
||||
point_rule_id = None
|
||||
points_at_time = None
|
||||
if action_key:
|
||||
rule = await self._get_point_rule(db, action_key)
|
||||
if rule:
|
||||
# A point_rules-ból jövő pontok felülírják a paraméterként kapott értékeket
|
||||
xp_amount = rule["points"]
|
||||
point_rule_id = rule.get("rule_id")
|
||||
points_at_time = rule["points"]
|
||||
if rule.get("description"):
|
||||
reason = f"{action_key}: {rule['description']}"
|
||||
logger.debug(f"Point rule applied: {action_key} -> {xp_amount} XP")
|
||||
@@ -152,7 +187,18 @@ class GamificationService:
|
||||
stats.social_points %= rate # A maradék pont megmarad
|
||||
await self._add_earned_credits(db, user_id, credits_to_add, "SOCIAL_ACTIVITY_CONVERSION")
|
||||
|
||||
# 7. NAPLÓZÁS (kibővítve xp, source_type, source_id mezőkkel)
|
||||
# 7. NAPLÓZÁS (kibővítve xp, source_type, source_id, points_snapshot mezőkkel)
|
||||
# A points_snapshot JSONB tárolja a kiosztáskor érvényes point_rules adatokat,
|
||||
# hogy a pontértékek megőrződjenek a ledger-ben, még akkor is, ha a
|
||||
# point_rules táblában később módosítják a pontértékeket.
|
||||
snapshot = None
|
||||
if action_key and point_rule_id and points_at_time is not None:
|
||||
snapshot = {
|
||||
"action_key": action_key,
|
||||
"point_rule_id": point_rule_id,
|
||||
"points_at_time": points_at_time,
|
||||
"multiplier": multiplier,
|
||||
}
|
||||
db.add(PointsLedger(
|
||||
user_id=user_id,
|
||||
points=final_xp,
|
||||
@@ -160,6 +206,7 @@ class GamificationService:
|
||||
reason=reason,
|
||||
source_type=source_type,
|
||||
source_id=source_id,
|
||||
points_snapshot=snapshot,
|
||||
))
|
||||
|
||||
# Only commit if caller wants us to manage the transaction
|
||||
|
||||
@@ -40,7 +40,7 @@ from sqlalchemy.orm import joinedload
|
||||
|
||||
from app.models.marketplace.organization import Organization, OrgType, Branch, OrganizationMember, OrgUserRole
|
||||
from app.models.marketplace.service import ServiceProfile, ServiceStatus, ExpertiseTag, ServiceExpertise, ServiceStaging
|
||||
from app.models.identity.social import ServiceProvider
|
||||
from app.models.identity.social import ServiceProvider, ModerationStatus, SourceType
|
||||
from app.models.gamification.gamification import PointRule, UserStats
|
||||
from app.schemas.provider import (
|
||||
ProviderSearchResult,
|
||||
@@ -64,9 +64,12 @@ async def _award_provider_points(
|
||||
"""
|
||||
Dinamikus pontjóváírás a gamification.point_rules tábla alapján.
|
||||
|
||||
Ez a függvény az adatbázisból olvassa ki a pontértéket az action_key
|
||||
alapján, így a pontok NINCSENEK beégetve a kódba. Az admin felületről
|
||||
bármikor módosíthatók a point_rules táblában.
|
||||
REFAKTOR (2026-06-30): A duplikált point_rules olvasási logika eltávolításra
|
||||
került. A pontértékeket most a GamificationService.award_points() olvassa ki
|
||||
a point_rules táblából az action_key alapján a process_activity() hívás során.
|
||||
|
||||
Ez a függvény már csak a providers_added_count statisztikát kezeli.
|
||||
A pontok kiszámítása és naplózása a GamificationService-ben történik.
|
||||
|
||||
Args:
|
||||
db: AsyncSession
|
||||
@@ -76,39 +79,19 @@ async def _award_provider_points(
|
||||
Returns:
|
||||
int: A jóváírt pontok száma (0 ha a szabály nem található vagy inaktív)
|
||||
"""
|
||||
# 1. Pontszabály lekérdezése az adatbázisból (dinamikus!)
|
||||
rule_stmt = select(PointRule).where(
|
||||
PointRule.action_key == action_key,
|
||||
PointRule.is_active == True,
|
||||
)
|
||||
rule_result = await db.execute(rule_stmt)
|
||||
rule = rule_result.scalar_one_or_none()
|
||||
|
||||
if not rule:
|
||||
logger.warning(
|
||||
f"Pontszabály '{action_key}' nem található vagy inaktív. "
|
||||
f"Pontjóváírás kihagyva user_id={user_id}."
|
||||
)
|
||||
return 0
|
||||
|
||||
points_to_award = rule.points
|
||||
logger.info(
|
||||
f"Dinamikus pont lekérés: action_key='{action_key}', "
|
||||
f"points={points_to_award} (forrás: gamification.point_rules tábla)"
|
||||
)
|
||||
|
||||
# 2. Pontok jóváírása a Gamification Service-en keresztül
|
||||
# A GamificationService.award_points() kezeli a szorzókat, szintlépést,
|
||||
# büntetés ledolgozást és a naplózást (PointsLedger).
|
||||
# 1. Pontok jóváírása a Gamification Service-en keresztül (action_key alapján)
|
||||
# A GamificationService.award_points() kezeli a point_rules olvasást, szorzókat,
|
||||
# szintlépést, büntetés ledolgozást és a naplózást (PointsLedger).
|
||||
await gamification_service.award_points(
|
||||
db=db,
|
||||
user_id=user_id,
|
||||
amount=points_to_award,
|
||||
reason=f"ADD_NEW_PROVIDER: +{points_to_award} pont új szolgáltató rögzítéséért",
|
||||
commit=False, # A hívó (quick_add_provider) kezeli a commit-ot
|
||||
amount=0,
|
||||
reason=f"{action_key}",
|
||||
commit=False, # A hívó kezeli a commit-ot
|
||||
action_key=action_key,
|
||||
)
|
||||
|
||||
# 3. Statisztika növelése (providers_added_count)
|
||||
# 2. Statisztika növelése (providers_added_count)
|
||||
stats_stmt = select(UserStats).where(UserStats.user_id == user_id)
|
||||
stats = (await db.execute(stats_stmt)).scalar_one_or_none()
|
||||
|
||||
@@ -122,7 +105,7 @@ async def _award_provider_points(
|
||||
# Ha még nincs UserStats rekordja, létrehozzuk
|
||||
stats = UserStats(
|
||||
user_id=user_id,
|
||||
total_xp=points_to_award,
|
||||
total_xp=0,
|
||||
current_level=1,
|
||||
providers_added_count=1,
|
||||
)
|
||||
@@ -132,7 +115,102 @@ async def _award_provider_points(
|
||||
f"providers_added_count=1"
|
||||
)
|
||||
|
||||
return points_to_award
|
||||
return 0 # Visszatérési érték már nem a pontszám, mert az award_points kezeli
|
||||
|
||||
|
||||
async def find_or_create_provider_by_name(
|
||||
db: AsyncSession,
|
||||
name: str,
|
||||
added_by_user_id: int,
|
||||
) -> tuple:
|
||||
"""
|
||||
Keres vagy létrehoz egy ServiceProvider-t a megadott név alapján.
|
||||
|
||||
Ez a függvény az expense auto-discovery hook része. Amikor egy user
|
||||
költséget rögzít és megad egy external_vendor_name-t, ez a függvény
|
||||
megkeresi, hogy létezik-e már a provider, és ha nem, létrehozza.
|
||||
|
||||
Logika:
|
||||
1. Pontos match keresése ServiceProvider.name alapján (kisbetűs, space-sztrippelt)
|
||||
2. Ha nem létezik → új provider létrehozása PENDING státusszal,
|
||||
validation_score=10, source=import, vissza: PROVIDER_DISCOVERY
|
||||
3. Ha létezik és APPROVED → vissza: PROVIDER_VERIFIED_USE
|
||||
4. Ha létezik és nem APPROVED → vissza: PROVIDER_CONFIRMATION
|
||||
5. A függvény meghívja a _award_provider_points()-t a megfelelő action_key-kel
|
||||
|
||||
Args:
|
||||
db: AsyncSession
|
||||
name: A provider neve (external_vendor_name)
|
||||
added_by_user_id: A költséget rögzítő user ID-ja
|
||||
|
||||
Returns:
|
||||
tuple[ServiceProvider, str]: (provider, action_key)
|
||||
- action_key: "PROVIDER_DISCOVERY" | "PROVIDER_CONFIRMATION" | "PROVIDER_VERIFIED_USE"
|
||||
"""
|
||||
# 1. Pontos match keresése (kisbetűsen, space-sztrippelten)
|
||||
clean_name = name.strip()
|
||||
provider_stmt = select(ServiceProvider).where(
|
||||
func.lower(ServiceProvider.name) == func.lower(clean_name)
|
||||
)
|
||||
provider_result = await db.execute(provider_stmt)
|
||||
provider = provider_result.scalar_one_or_none()
|
||||
|
||||
if not provider:
|
||||
# 2. Ha nem létezik → létrehozás + PROVIDER_DISCOVERY
|
||||
new_provider = ServiceProvider(
|
||||
name=clean_name,
|
||||
address=clean_name,
|
||||
status=ModerationStatus.pending,
|
||||
source=SourceType.api,
|
||||
validation_score=10,
|
||||
added_by_user_id=added_by_user_id,
|
||||
)
|
||||
db.add(new_provider)
|
||||
await db.flush()
|
||||
|
||||
logger.info(
|
||||
f"Új provider felfedezve: name='{clean_name}', "
|
||||
f"provider_id={new_provider.id}, user_id={added_by_user_id}"
|
||||
)
|
||||
|
||||
# Gamification pont kiosztása
|
||||
await _award_provider_points(
|
||||
db=db,
|
||||
user_id=added_by_user_id,
|
||||
action_key="PROVIDER_DISCOVERY",
|
||||
)
|
||||
|
||||
return new_provider, "PROVIDER_DISCOVERY"
|
||||
|
||||
# 3. Ha létezik, státusz alapján döntés
|
||||
# P0 CRITICAL (Card #362): USE_UNVERIFIED_PROVIDER vs PROVIDER_CONFIRMATION
|
||||
# - Ha a provider APPROVED -> PROVIDER_VERIFIED_USE (100 XP)
|
||||
# - Ha a provider PENDING es a hasznalo user a provider letrehozoja -> PROVIDER_CONFIRMATION (150 XP)
|
||||
# - Ha a provider PENDING es a hasznalo user NEM a provider letrehozoja -> USE_UNVERIFIED_PROVIDER (200 XP)
|
||||
# Ez megakadalyozza az XP farmingot (sajat provider hasznalata sajat maganak).
|
||||
if provider.status == ModerationStatus.approved:
|
||||
action_key = "PROVIDER_VERIFIED_USE"
|
||||
elif provider.added_by_user_id == added_by_user_id:
|
||||
# A provider letrehozoja hasznalja a sajat pending provideret
|
||||
action_key = "PROVIDER_CONFIRMATION"
|
||||
else:
|
||||
# Mas user hasznal egy pending providert
|
||||
action_key = "USE_UNVERIFIED_PROVIDER"
|
||||
|
||||
logger.info(
|
||||
f"Meglevo provider hasznalata: name='{clean_name}', "
|
||||
f"provider_id={provider.id}, action_key='{action_key}', "
|
||||
f"user_id={added_by_user_id}, provider_creator_id={provider.added_by_user_id}"
|
||||
)
|
||||
|
||||
# Gamification pont kiosztása
|
||||
await _award_provider_points(
|
||||
db=db,
|
||||
user_id=added_by_user_id,
|
||||
action_key=action_key,
|
||||
)
|
||||
|
||||
return provider, action_key
|
||||
|
||||
|
||||
async def search_providers(
|
||||
|
||||
@@ -10,36 +10,36 @@ from app.schemas.social import ServiceProviderCreate
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class SocialService:
|
||||
"""
|
||||
"""
|
||||
SocialService: Kezeli a közösségi interakciókat, szavazatokat és a moderációt.
|
||||
Az importok a metódusokon belül vannak a körkörös függőség elkerülése érdekében.
|
||||
"""
|
||||
|
||||
async def create_service_provider(self, db: AsyncSession, obj_in: ServiceProviderCreate, user_id: int):
|
||||
from app.services.gamification_service import gamification_service
|
||||
from app.services.provider_service import _award_provider_points
|
||||
|
||||
new_provider = ServiceProvider(**obj_in.model_dump(), added_by_user_id=user_id)
|
||||
db.add(new_provider)
|
||||
await db.flush()
|
||||
await db.flush()
|
||||
|
||||
# Alappontszám az új beküldésért
|
||||
await gamification_service.process_activity(db, user_id, 50, 10, f"New Provider: {new_provider.name}")
|
||||
# Dinamikus pontjóváírás a point_rules táblából (ADD_NEW_PROVIDER)
|
||||
await _award_provider_points(db, user_id, "ADD_NEW_PROVIDER")
|
||||
await db.commit()
|
||||
await db.refresh(new_provider)
|
||||
return new_provider
|
||||
|
||||
async def vote_for_provider(self, db: AsyncSession, voter_id: int, provider_id: int, vote_value: int):
|
||||
from app.services.gamification_service import gamification_service
|
||||
from app.services.provider_service import _award_provider_points
|
||||
|
||||
# Duplikált szavazat ellenőrzése
|
||||
exists = (await db.execute(select(Vote).where(and_(Vote.user_id == voter_id, Vote.provider_id == provider_id)))).scalar()
|
||||
if exists:
|
||||
if exists:
|
||||
return {"message": "Már szavaztál erre a szolgáltatóra!"}
|
||||
|
||||
db.add(Vote(user_id=voter_id, provider_id=provider_id, vote_value=vote_value))
|
||||
|
||||
provider = (await db.execute(select(ServiceProvider).where(ServiceProvider.id == provider_id))).scalar_one_or_none()
|
||||
if not provider:
|
||||
if not provider:
|
||||
return {"error": "Szolgáltató nem található."}
|
||||
|
||||
provider.validation_score += vote_value
|
||||
@@ -53,6 +53,9 @@ class SocialService:
|
||||
provider.status = ModerationStatus.rejected
|
||||
await self._penalize_user(db, provider.added_by_user_id, provider.name)
|
||||
|
||||
# RATE_PROVIDER pontok kiosztása a sikeres szavazatért
|
||||
await _award_provider_points(db, voter_id, "RATE_PROVIDER")
|
||||
|
||||
await db.commit()
|
||||
return {"status": "success", "score": provider.validation_score, "new_status": provider.status}
|
||||
|
||||
@@ -67,7 +70,8 @@ class SocialService:
|
||||
from app.services.gamification_service import gamification_service
|
||||
if not user_id: return
|
||||
|
||||
await gamification_service.process_activity(db, user_id, 100, 20, f"Validated: {provider_name}")
|
||||
# A pontérték a point_rules táblából jön (action_key='PROVIDER_VALIDATED')
|
||||
await gamification_service.process_activity(db, user_id, xp_amount=0, social_amount=20, reason=f"Validated: {provider_name}", action_key="PROVIDER_VALIDATED")
|
||||
|
||||
# Aktuális verseny keresése és pontozása
|
||||
now = datetime.now(timezone.utc)
|
||||
@@ -91,8 +95,8 @@ class SocialService:
|
||||
from app.services.gamification_service import gamification_service
|
||||
if not user_id: return
|
||||
|
||||
# JAVÍTVA: is_penalty=True hozzáadva a gamification híváshoz
|
||||
await gamification_service.process_activity(db, user_id, 50, 0, f"Rejected: {provider_name}", is_penalty=True)
|
||||
# A pontérték a point_rules táblából jön (action_key='PROVIDER_REJECTED')
|
||||
await gamification_service.process_activity(db, user_id, xp_amount=0, social_amount=0, reason=f"Rejected: {provider_name}", is_penalty=True, action_key="PROVIDER_REJECTED")
|
||||
|
||||
user = (await db.execute(select(User).where(User.id == user_id))).scalar_one_or_none()
|
||||
if user and hasattr(user, 'reputation_score'):
|
||||
|
||||
Reference in New Issue
Block a user