Files
service-finder/backend/app/workers/service/service_robot_3_enricher.py
2026-03-22 11:02:05 +00:00

91 lines
4.2 KiB
Python
Executable File

import asyncio
import logging
from sqlalchemy import select, text
from app.database import AsyncSessionLocal
from app.models.marketplace.service import ExpertiseTag
logging.basicConfig(level=logging.INFO, format='%(asctime)s [%(levelname)s] %(name)s: %(message)s')
logger = logging.getLogger("Service-Robot-3-Enricher")
class ServiceEnricher:
""" Service Robot 3: Professional Classifier (Bíró-Kompatibilis Verzió) """
@staticmethod
async def match_expertise_and_score(db, scraped_text: str, current_trust_score: int) -> int:
""" Keresi a szakmákat és bónusz pontokat ad értük a Staging adatnak. """
if not scraped_text: return current_trust_score
tags_query = await db.execute(select(ExpertiseTag).where(ExpertiseTag.is_official == True))
all_tags = tags_query.scalars().all()
match_count = 0
for tag in all_tags:
for kw in (tag.search_keywords or []):
if kw.lower() in scraped_text.lower():
match_count += 1
break # Egy tag elég, ha egyszer megvan
# +5 pont minden megtalált szakmáért, max 30 bónusz pont
bonus = min(match_count * 5, 30)
new_score = min(current_trust_score + bonus, 100)
if bonus > 0:
logger.info(f"{match_count} szakma azonosítva. Bónusz: +{bonus} pont.")
return new_score
@classmethod
async def run_worker(cls):
logger.info("🧠 Service Enricher ONLINE - Adatdúsítás (Nem publikál, csak pontoz!)")
while True:
try:
async with AsyncSessionLocal() as db:
query = text("""
UPDATE marketplace.service_staging
SET status = 'enriching'
WHERE id = (
SELECT id FROM marketplace.service_staging
WHERE status = 'enrich_ready'
FOR UPDATE SKIP LOCKED
LIMIT 1
)
RETURNING id, name, trust_score, raw_data;
""")
result = await db.execute(query)
task = result.fetchone()
await db.commit()
if task:
s_id, name, t_score, raw_data = task
web_context = raw_data.get('web_context', '') if isinstance(raw_data, dict) else ''
async with AsyncSessionLocal() as process_db:
try:
# 1. Kiszámoljuk az új pontszámot a webes adatok (kulcsszavak) alapján
new_score = await cls.match_expertise_and_score(process_db, web_context, t_score)
# 2. Visszaírjuk a Staging táblába, és átadjuk az Auditor-nak (Gamification 2.0: auditor_ready státusz)
upd_query = text("""
UPDATE marketplace.service_staging
SET status = 'auditor_ready', trust_score = :ns
WHERE id = :id
""")
await process_db.execute(upd_query, {"ns": new_score, "id": s_id})
await process_db.commit()
logger.info(f"✅ Dúsítás kész: {name} (Pont: {t_score} -> {new_score}). Átadva az Auditor-nak (auditor_ready).")
except Exception as e:
await process_db.rollback()
logger.error(f"❌ Hiba a dúsítás során ({s_id}): {e}")
await process_db.execute(text("UPDATE marketplace.service_staging SET status = 'error' WHERE id = :id"), {"id": s_id})
await process_db.commit()
else:
await asyncio.sleep(15)
except Exception as e:
logger.error(f"💀 Kritikus hiba a főciklusban: {e}")
await asyncio.sleep(10)
if __name__ == "__main__":
asyncio.run(ServiceEnricher.run_worker())