diff --git a/lps/README.md b/lps/README.md index c314b1e..c3967c6 100644 --- a/lps/README.md +++ b/lps/README.md @@ -100,7 +100,7 @@ lps/ │ └── database/model/models.py # DB 테이블 정의 ├── crud/ # DB 접근 (job_crud, price_history, negative_cache, bot_detection) ├── services/ -│ ├── search/ # 소스 어댑터 (coupang, naver) + 프록시·필터 +│ ├── search/ # 소스 어댑터 (coupang, naver, esm=G마켓·옥션, st11=11번가) + 프록시·필터 │ ├── pipeline/ # 필터·이상치·최저가 정렬 │ └── ai/ # AI 유사도 판정·검색어 생성 (OpenAI) ├── worker/ # 워커 루프·핸들러·알림(NOTIFY) diff --git a/lps/docs/architecture.md b/lps/docs/architecture.md index a7158d6..207d065 100644 --- a/lps/docs/architecture.md +++ b/lps/docs/architecture.md @@ -10,6 +10,7 @@ | **큐(대기줄)** | `crud/job_crud.py` + `job` 테이블 | 할 일을 순서대로 안전하게 보관 (PostgreSQL 사용) | | **워커(일꾼)** | `worker_main.py`, `worker/` | 큐에서 하나씩 꺼내 **실제 검색·판정·저장** 수행 | | **소스 어댑터** | `services/search/` | 네이버·쿠팡에서 상품 수집 (소스별 방식 캡슐화) | +| **오픈마켓 폴백** | `services/search/{esm,st11}/` | G마켓·옥션·11번가 크롤 — 네이버가 그 몰을 커버 못 했을 때만 (BrowserSearchAdapter 공유) | | **파이프라인** | `services/pipeline/` | 수집 결과를 필터·이상치 제거·최저가 정렬 | | **AI** | `services/ai/` | "같은 상품" 판정 + 검색어 생성 (OpenAI) | @@ -36,12 +37,16 @@ ⑤ AI 같은 상품 판정 후보 중 "찾는 상품과 동일한 것"만 선별 (액세서리·다른 규격 제외) - → 매칭 있으면: 최저가순 정렬 → 상위 N개 반환 (found) + → 매칭 있으면: ⑤-1 오픈마켓 폴백 → 최저가순 정렬 → 상위 N개 반환 (found) → 매칭 0건 + 소스 정상: 다음 라운드로 → 매칭 0건 + 소스 차단: 작업 실패 처리(뒤에서 재시도) +⑤-1 오픈마켓 폴백 (매칭 성공 시) + 네이버가 커버 못 한 몰(G마켓·옥션·11번가)만 실사이트 크롤 → 같은 상품 판정 → 병합 + ("네이버로 그 몰 값 확보 성공 → 그 값, 실패(몰 없음) → 크롤". 크롤 실패는 격리) + ⑥ 결과 저장 - 최저가 확정 + 최저가 이력 스냅샷 기록 + 최저가 확정 + 최저가 이력 스냅샷 기록(몰별 by_mall 포함) ``` 모든 라운드에서 못 찾으면 → **not_found(정상 종료)** + 네거티브 캐시에 기록.