"""잡 핸들러 — job_type 별 처리. 현재는 SEARCH(검색)만. 검색 핸들러는 소스 어댑터로 검색해 정규화 결과를 반환한다. 필터/이상치/AI 유사도(코어 파이프라인)는 다음 단계에서 이 핸들러 안에 결합한다. """ from common.enums import JobType from services.search.contract import SearchAdapter def build_search_handler(adapters: dict[str, SearchAdapter], default_source: str = "coupang", limit: int = 40): """검색 핸들러 생성. adapters = {source: SearchAdapter}.""" async def handler(job: dict) -> dict: if job["job_type"] != JobType.SEARCH.value: raise ValueError(f"unsupported job_type: {job['job_type']}") payload = job.get("payload") or {} query = (payload.get("product_name") or "").strip() if not query: raise ValueError("empty product_name") adapter = adapters.get(default_source) if adapter is None: raise ValueError(f"no adapter for source: {default_source}") products = await adapter.search(query, limit=limit) return { "source": adapter.source, "query": query, "count": len(products), "products": [p.model_dump() for p in products], } return handler