fix(realestate): compose INTERNAL_API_KEY(배포 401 방지) + 매칭·알림 공유락(중복 텔레그램 방지)

- docker-compose.yml realestate-lab environment에 INTERNAL_API_KEY/NAVER_PAGE_LIMIT 누락 추가
  (verify_internal_key 항상 401 → 워커 계약 전체 마비 방지, sibling image/video/music/insta-lab과 동형)
- pipeline_lock.py 신설: cron _run_listing_pipeline과 워커 listings_ingest가
  run_listing_matching()+notify_new_listings() 임계구역을 공유 threading.Lock으로 직렬화
  (동시 실행 시 동일 매물 중복 텔레그램 발송 방지). 느린 collect는 락 밖 유지.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EqCYBhvTcdeCTUDX3RhWx9
This commit is contained in:
2026-07-10 00:50:55 +09:00
parent 04081bef6a
commit 1fff511752
5 changed files with 30 additions and 4 deletions

View File

@@ -44,3 +44,16 @@ def test_ingest_idempotent(monkeypatch):
c.post("/api/internal/realestate/listings-ingest", headers={"X-Internal-Key": "SECRET"}, json=payload)
r2 = c.post("/api/internal/realestate/listings-ingest", headers={"X-Internal-Key": "SECRET"}, json=payload)
assert r2.json()["new"] == 0 # 재push → 신규 0
def test_ingest_holds_match_notify_lock(monkeypatch):
from app import internal_router as ir
from app.pipeline_lock import match_notify_lock
c = _client(monkeypatch)
holds = {}
def fake_notify():
holds["locked"] = match_notify_lock.locked()
return {"sent": 0}
monkeypatch.setattr(ir, "notify_new_listings", fake_notify)
c.post("/api/internal/realestate/listings-ingest", headers={"X-Internal-Key": "SECRET"},
json={"batches": [{"dong": "신대방동", "articles": [_ARTICLE]}]})
assert holds["locked"] is True # 알림 시점에 락 보유(임계구역 직렬화 증명)