RUNNING

SellerSync

해외구매대행 셀러가 네이버 스마트스토어 주문과 빅딜 배대지 배송·정산을 단일 화면에서 자동 수집·매칭하는 운영 대시보드. LLM이 오픈마켓 금지·규제어 사전 4,200건을 피해 상품명 후보를 생성한다.

Python 3.12 FastAPI React 18 TypeScript PostgreSQL OpenAI Anthropic SQLAlchemy Docker
PROBLEM

해결한 문제

세 시스템을 수기로 대조하는 비효율

네이버 커머스 솔루션, 빅딜 배대지, 자체 엑셀을 따로 열어 수기로 주문과 배송을 맞춰야 했다.

BEFORE 탭 3개를 오가며 수기 복사·붙여넣기. 실수와 누락 빈발.
AFTER 네이버 주문·빅딜 배송을 자동 동기화 후 그리드 한 화면에 정렬.

주문↔배대지 신청서 매칭 오탐

주문번호와 배대지 신청서가 별개 식별자라 수취인 이름·주소 기준 수동 매칭 시 오탐이 잦았다.

BEFORE 이름·주소 유사도 점수만으로 매칭 → 오탐·누락 반복.
AFTER 운송장 완전 일치 우선 + 금액·이름·주소·날짜 보수적 결정 규칙. 50건 fixture precision 1.0000.

상품명 금지어 사고

4,200건 이상의 오픈마켓 금지·규제어를 매번 사람이 확인하기 어려워 등록 실패·노출 차단이 반복됐다.

BEFORE 상품명 등록 후 반려 통보. 수동 수정 반복.
AFTER LLM이 후보를 생성하고 금지어 사전이 결정적으로 후처리. 안전한 상품명만 출력.
ARCHITECTURE

데이터 흐름

네이버 스마트스토어와 빅딜 배대지를 동기화한 뒤 자동으로 매칭 엔진이 발동한다. LLM 상품명 생성은 별도 APScheduler 잡으로 처리된다.

FLOW 1 — 주문 동기화 & 자동 매칭

네이버 스마트스토어
빅딜 배대지
API 폴링

Sync Job

cron 일 2회

UPSERT

PostgreSQL

SAVEPOINT 패턴

trigger

매칭 엔진

결정적 규칙

UNIQUE

운영자 그리드

React SPA

네이버 주문 동기화 완료 직후 _trigger_auto_match가 발동해 빅딜 신청서와 1:1 매칭을 시도한다. 매칭 규칙은 운송장 완전 일치 → 금액 ±1원 + 이름 유사도 ≥ 0.80 + 주소·전화 부분일치 + 날짜 윈도우 10일의 결정적 순서를 따른다. 미해결 건은 수동 매칭 다이얼로그로 라우팅된다.

FLOW 2 — LLM 상품명 생성

엑셀 업로드

최대 2,000행

APScheduler

LLM 호출

OpenAI / Anthropic

후처리

금지어 필터

4,200+ 사전

다운로드

결과 엑셀

안전한 상품명

ENGINEERING

기술적으로 내세울 점

개발자 관점에서 이 시스템이 어떻게 설계됐는지를 코드 수준에서 설명한다.

01

결정적 매칭 — 점수 기반 NLP를 의도적으로 배제

운송장 완전 일치 우선, 그 다음 금액 ±1원 + 이름 유사도 ≥ 0.80 + 주소(시도명 축약·도로명/지번 추출) + 전화(비숫자 제거) 부분일치 + 날짜 윈도우 10일의 결정적 규칙을 조합한다. 외부 NLP 의존성을 제거해 오탐 위험을 줄이는 설계 결정이다.

precision 1.0000 (50건 fixture) recall 0.7778
02

민감정보: Fernet 암호화 + 메모리 zeroize

스마트스토어 client_secret과 빅딜 API 키는 Fernet으로 암호화 후 DB에 저장한다. 메모리에서는 bytearray로 보관하다 __del__에서 zeroize한다. 키 회전은 FERNET_KEYS=key1,key2,... MultiFernet으로 무중단으로 처리한다.

fernets = [Fernet(k.encode() if isinstance(k, str) else k) for k in keys] return MultiFernet(fernets)
MultiFernet 무중단 키 회전 메모리 zeroize
03

SAVEPOINT 부분 성공 — 한 건 실패가 전체를 롤백하지 않는다

동기화와 매칭 모두 db.begin_nested()(SAVEPOINT)으로 항목 단위 트랜잭션을 분리한다. 실패한 한 건은 해당 항목만 롤백·tb_sync_failure_log에 적재하고 나머지는 계속 진행한다. 운영자는 실패 항목만 골라 재처리할 수 있다.

SAVEPOINT 부분 성공 패턴
04

Prometheus 실패율 알림 + 커버리지 게이트

prometheus-client로 동기화 실패율 지표(sellersync_sync_failures_total)를 노출하고, "5분 실패율 > 20%" 알림 규칙을 문서화했다. 테스트 커버리지는 65% 게이트(pytest --cov-fail-under=65)로 강제하며, 스마트스토어 클라이언트 98%, 빅딜 클라이언트 100% 커버리지를 달성했다.

Prometheus 실패율 알림 커버리지 게이트 65%
05

LLM 비용·재시도 제어 — 잡 단위 token 추적

OpenAI(gpt-4.1)와 Anthropic(claude-sonnet-4-6) 둘 다 지원한다. provider별 단가표로 token 사용량을 잡 단위로 합산해 tb_pname_api_usage에 기록한다. 청크당 지수 백오프 재시도와 사용자당 동시 활성 잡 3개 제한으로 429를 방어한다. 금지·규제어 사전 4,200건 이상이 LLM 결과를 결정적으로 후처리한다.

금지·규제어 사전 4,200+ 잡당 최대 2,000행