Initial commit: Robot ökoszisztéma v2.0 - Stabilizált jármű és szerviz robotok
This commit is contained in:
115
backend/app/workers/service/service_robot_3_enricher.py
Executable file
115
backend/app/workers/service/service_robot_3_enricher.py
Executable file
@@ -0,0 +1,115 @@
|
||||
import asyncio
|
||||
import logging
|
||||
import json
|
||||
from sqlalchemy import select, text, update, func
|
||||
from app.database import AsyncSessionLocal # JAVÍTVA
|
||||
from app.models.service import ServiceProfile, ExpertiseTag, ServiceExpertise, ServiceStaging
|
||||
|
||||
# Logolás MB 2.0 szabvány
|
||||
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 (Atomi Zárolással)
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
async def match_expertise_to_service(db, service_profile_id: int, scraped_text: str):
|
||||
""" Kulcsszó-alapú elemző motor az ExpertiseTag tábla alapján. """
|
||||
if not scraped_text: return
|
||||
|
||||
tags_query = await db.execute(select(ExpertiseTag).where(ExpertiseTag.is_official == True))
|
||||
all_tags = tags_query.scalars().all()
|
||||
|
||||
found_any = False
|
||||
for tag in all_tags:
|
||||
match_count = 0
|
||||
for kw in (tag.search_keywords or []):
|
||||
if kw.lower() in scraped_text.lower():
|
||||
match_count += 1
|
||||
|
||||
if match_count > 0:
|
||||
existing_check = await db.execute(
|
||||
select(ServiceExpertise).where(
|
||||
ServiceExpertise.service_id == service_profile_id,
|
||||
ServiceExpertise.expertise_id == tag.id
|
||||
)
|
||||
)
|
||||
|
||||
if not existing_check.scalar():
|
||||
new_link = ServiceExpertise(
|
||||
service_id=service_profile_id,
|
||||
expertise_id=tag.id,
|
||||
confidence_level=min(match_count, 2)
|
||||
)
|
||||
db.add(new_link)
|
||||
found_any = True
|
||||
logger.info(f"✅ {tag.key} szakma azonosítva a szerviznél.")
|
||||
|
||||
if found_any:
|
||||
await db.commit()
|
||||
|
||||
@classmethod
|
||||
async def run_worker(cls):
|
||||
logger.info("🧠 Service Enricher ONLINE - Szakmai elemzés indítása (Atomi Zárolás)")
|
||||
|
||||
while True:
|
||||
try:
|
||||
async with AsyncSessionLocal() as db:
|
||||
# 1. Zárolunk egy "enrich_ready" szervizt a Staging táblából
|
||||
query = text("""
|
||||
UPDATE data.service_staging
|
||||
SET status = 'enriching'
|
||||
WHERE id = (
|
||||
SELECT id FROM data.service_staging
|
||||
WHERE status = 'enrich_ready'
|
||||
FOR UPDATE SKIP LOCKED
|
||||
LIMIT 1
|
||||
)
|
||||
RETURNING id, name, city, full_address, fingerprint, raw_data;
|
||||
""")
|
||||
result = await db.execute(query)
|
||||
task = result.fetchone()
|
||||
await db.commit()
|
||||
|
||||
if task:
|
||||
s_id, name, city, address, fprint, raw_data = task
|
||||
web_context = raw_data.get('web_context', '') if isinstance(raw_data, dict) else ''
|
||||
|
||||
async with AsyncSessionLocal() as process_db:
|
||||
try:
|
||||
# 2. Áttesszük a végleges ServiceProfile táblába (mert már van elég adatunk a webről)
|
||||
profile_stmt = text("""
|
||||
INSERT INTO data.service_profiles
|
||||
(fingerprint, status, trust_score, location, is_verified, bio)
|
||||
VALUES (:fp, 'active', 40, ST_SetSRID(ST_MakePoint(19.04, 47.49), 4326), false, :bio)
|
||||
ON CONFLICT (fingerprint) DO UPDATE SET bio = EXCLUDED.bio
|
||||
RETURNING id;
|
||||
""") # Megjegyzés: A GPS koordinátát (19.04, 47.49) majd a Validator (Robot-4) pontosítja!
|
||||
|
||||
p_result = await process_db.execute(profile_stmt, {"fp": fprint, "bio": name + " - " + city})
|
||||
profile_id = p_result.scalar()
|
||||
await process_db.commit()
|
||||
|
||||
# 3. Futtatjuk a kulcsszó-elemzést
|
||||
await cls.match_expertise_to_service(process_db, profile_id, web_context)
|
||||
|
||||
# 4. Lezárjuk a Staging feladatot
|
||||
await process_db.execute(text("UPDATE data.service_staging SET status = 'processed' WHERE id = :id"), {"id": s_id})
|
||||
await process_db.commit()
|
||||
|
||||
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 data.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())
|
||||
Reference in New Issue
Block a user