Skip to content

A1: brand_profile fuzzy 매칭 + paper brand 가드 (None*100 폭발 차단)#195

Merged
bat1120 merged 1 commit into
devfrom
IM3-brand-profile-fuzzy-paper-guard
May 5, 2026
Merged

A1: brand_profile fuzzy 매칭 + paper brand 가드 (None*100 폭발 차단)#195
bat1120 merged 1 commit into
devfrom
IM3-brand-profile-fuzzy-paper-guard

Conversation

@bat1120

@bat1120 bat1120 commented May 5, 2026

Copy link
Copy Markdown
Contributor

Summary

agents/nodes/competitor_intel.py:257bench.get('closure_rate', 0) * 100 None * int TypeError 근본 fix. 호출자 (A2/agents) 변경 없이 데이터 소스 (A1/brand_profile) 측에서 차단.

발견 케이스 (지앤푸드 커피 시뮬)

ftc_brand_franchise 의 듀먼카페·에이에스커피(AS COFFEE) frcsCnt=0 (paper brand) → closure_rate = (0) / 0 → Nonecompetitor_intel:257 의 None * 100 → TypeError 폭발.

Fix

  1. paper brand 가드: frcsCnt=0 매칭 시 benchmark_available=False 응답

    • 호출자 (competitor_intel.py:254) 의 기존 bench.get("benchmark_available") 분기로 자동 fallback
    • franchise_count_national=0 명시 (다운스트림 KeyError 방지)
  2. fuzzy prefix 매칭: 정확 매칭 실패 시 ILIKE prefix + frcsCnt > 0 우선

    • '홍콩반점' → '홍콩반점0410' 자동 매칭
    • 가드: len(brand_name) ≥ 4 (false positive 차단: 파리/피자 등 2자는 막음)
  3. silent tie-break 제거: 정확 매칭에 추가했던 ORDER BY 제거 + 동일 (brandNm, yr) 다 row 시 logger.warning

엔지니어링

  • _FUZZY_SQL module-level constant 분리 (text() 객체 매 호출 재생성 회피)
  • f-string 외부 괄호 정리

검증 (실 DB)

케이스 결과
빽다방 (정상) ✓ avail=True, frcs=1449
홍콩반점 → 홍콩반점0410 (fuzzy 4자) ✓ matched, frcs=282
듀먼카페/에이에스커피(AS COFFEE) (paper) ✓ avail=False, frcs=0 명시
파리/피자 (2자 가드) ✓ 차단
스타벅스 (미등재) ✓ avail=False
competitor_intel.py:254 bench_block 빌드 시뮬 ✓ 폭발 안 함
peer_brands 회귀 ✓ 통과

호환성

다른 팀원 코드 영향
competitor_intel.py:254 benchmark_available 분기 ✓ 자동 fallback
peer_brands 함수 ✓ 회귀 0
호출 시그니처 / 반환 타입 ✓ 동일

다른 팀원 0 수정.

Test plan

  • 정상 brand 회귀 (빽다방/도미노피자/교촌치킨)
  • paper brand 처리 (듀먼카페/에이에스커피)
  • fuzzy 매칭 (홍콩반점)
  • fuzzy 가드 (2자 brand 차단)
  • competitor_intel bench_block 빌드 시뮬 (TypeError 안 남)
  • ruff check/format 통과
  • tests/test_brand_profile.py 에 fuzzy/paper 신규 케이스 (별 PR — LOW)

DB 변경

없음. read-only fix.

🤖 Generated with Claude Code

agents/competitor_intel.py:257 의 bench.get('closure_rate', 0) * 100 None * int
TypeError 근본 fix — 호출자 측이 아닌 데이터 소스 (brand_profile) 측에서 차단.

발견 케이스 (지앤푸드 커피 시뮬):
  ftc_brand_franchise 의 듀먼카페/에이에스커피(AS COFFEE) frcsCnt=0 (paper brand)
  → closure_rate = (0) / 0 → None
  → competitor_intel.py:257 의 None * 100 → TypeError 폭발

Fix:
1. paper brand (frcsCnt=0) 매칭 시 benchmark_available=False 응답
   - 호출자 (competitor_intel.py:254) 의 기존 'FTC 미등재' 분기로 자동 fallback
   - franchise_count_national=0 명시 (다운스트림 KeyError 방지)
2. fuzzy prefix 매칭 (정확 매칭 실패 시 ILIKE prefix + frcsCnt > 0 우선)
   - 예: '홍콩반점' → '홍콩반점0410' 자동 매칭
   - 가드: brand_name 길이 ≥ 4 (false positive 방지: '파리'/'피자' 같은 2자는 차단)
3. 정확 매칭 silent tie-break 제거
   - 동일 (brandNm, yr) 다 row 시 logger.warning 으로 데이터 품질 신호 노출

엔지니어링:
- _FUZZY_SQL module-level constant 분리 (text() 객체 매 호출 재생성 회피)
- f-string 외부 괄호 정리

검증 (실 DB):
- 빽다방(정상): avail=True, frcs=1449 ✓
- 홍콩반점→홍콩반점0410 (fuzzy 4자): matched, frcs=282 ✓
- 듀먼카페/에이에스커피 (paper): avail=False, frcs=0 명시 ✓
- 파리/피자 (2자 가드): 차단 ✓
- 스타벅스 (미등재): avail=False ✓
- competitor_intel.py:254 bench_block 빌드 시뮬: 폭발 안 함 ✓
- peer_brands 회귀: 통과 ✓

다른 팀원 코드 변경 0 — competitor_intel.py 의 기존 'benchmark_available' 분기로 자동 처리.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bat1120 bat1120 merged commit 0a2f0cb into dev May 5, 2026
@bat1120 bat1120 deleted the IM3-brand-profile-fuzzy-paper-guard branch May 5, 2026 02:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant