테마
Story: 패턴 발견 로직 + SellerPatterns 테이블
메타
| 항목 | 값 |
|---|---|
| Story ID | E-10-S-09 |
| Epic | E-10 업무노트 |
| 상태 | draft |
| 우선순위 | P1-a (v2.0) |
| 규모 | L |
| 담당 개발자 | 하록 (BE) |
사용자 스토리
As a 여러 조언을 적용해본 셀러,
I want 어떤 방법이 나에게 잘 맞는지 자동으로 분석해주길 원한다,
So that "이 방법이 내 방법이다"라는 확신을 얻을 수 있다.
배경
왜 필요한가?
- 한 번의 성공 → "운인가?"
- 두 번의 성공 → "우연인가?"
- 세 번의 성공 → "나에게 맞는 방법이구나!"
- 반복이 확신을 만들고, 확신이 성장을 만든다
- **핵심 가치 "성장 확신"**의 핵심 메커니즘
S53 E-04 연계
- SellerPatterns 데이터 → S53 E-04 SellerAIContext로 활용
- 개인화된 Surface Layer 진단의 기반 데이터
비즈니스 임팩트
| 지표 | 예상 영향 |
|---|---|
| 조언 적용률 | +25% (패턴 발견 → 추가 적용 동기) |
| 셀러 리텐션 | +10% (개인화 가치 인식) |
| S53 E-04 준비 | 완료 (데이터 인프라) |
수락 기준 (Acceptance Criteria)
AC-01: 패턴 발견 조건
| 항목 | 내용 |
|---|---|
| Given | 효과 추적이 완료된 노트가 있을 때 |
| When | 동일 adviceType으로 3회 이상 적용 AND 70% 이상 동일 결과 |
| Then | 해당 adviceType이 패턴으로 등록된다 |
패턴 발견 예시:
"비검색 입찰가 낮추기" 5회 적용
- positive: 4회 (80%)
- negative: 1회 (20%)
→ preferredActions에 등록AC-02: SellerPatterns 테이블 생성
| 항목 | 내용 |
|---|---|
| Given | 패턴 발견 시스템 구축 시 |
| When | 최초 배포 시 |
| Then | SellerPatterns 테이블이 생성된다 |
sql
CREATE TABLE seller_patterns (
id UUID PRIMARY KEY,
user_id UUID NOT NULL REFERENCES users(id),
-- 선호 방법
preferred_actions JSONB DEFAULT '[]',
-- 비선호 방법
avoided_actions JSONB DEFAULT '[]',
-- S53 E-04 연계용
apply_rate DECIMAL(5,4) DEFAULT 0,
positive_outcome_rate DECIMAL(5,4) DEFAULT 0,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_seller_patterns_user_id ON seller_patterns(user_id);AC-03: preferredActions 데이터 구조
| 항목 | 내용 |
|---|---|
| Given | 패턴이 발견되면 |
| When | preferredActions에 저장할 때 |
| Then | 다음 구조로 저장된다 |
json
preferredActions: [
{
"adviceType": "bidding_down",
"displayName": "비검색 입찰가 낮추기",
"trialCount": 5,
"positiveRate": 0.8,
"avgRoasChange": 16.3,
"lastApplied": "2026-01-28",
"discoveredAt": "2026-01-28"
}
]AC-04: avoidedActions 데이터 구조
| 항목 | 내용 |
|---|---|
| Given | 부정적 패턴이 발견되면 (3회+, 70%+ negative) |
| When | avoidedActions에 저장할 때 |
| Then | 다음 구조로 저장된다 |
json
avoidedActions: [
{
"adviceType": "keyword_add",
"displayName": "키워드 추가",
"trialCount": 4,
"negativeRate": 0.75,
"avgRoasChange": -8.5,
"lastApplied": "2026-01-25",
"discoveredAt": "2026-01-28"
}
]AC-05: 패턴 갱신 로직
| 항목 | 내용 |
|---|---|
| Given | 이미 패턴이 있는 adviceType에 새 결과가 추가되면 |
| When | 효과 추적 완료 시 |
| Then | trialCount, positiveRate/negativeRate, avgRoasChange가 갱신된다 |
AC-06: S53 E-04 연계 필드 계산
| 항목 | 내용 |
|---|---|
| Given | 패턴 계산 시 |
| When | SellerPatterns 갱신 시 |
| Then | apply_rate, positive_outcome_rate도 함께 계산된다 |
apply_rate = 조언 적용 횟수 / 조언 노출 횟수
positive_outcome_rate = positive 결과 / 전체 효과 추적 완료 건AC-07: API 제공
| 항목 | 내용 |
|---|---|
| Given | 패턴 조회가 필요할 때 |
| When | GET /api/seller-patterns 호출 시 |
| Then | 현재 사용자의 패턴 데이터가 반환된다 |
태스크 분해
Task 1: DB 스키마 AC-02
- [ ] 1.1: seller_patterns 테이블 마이그레이션 작성
- [ ] 1.2: 인덱스 생성 (user_id)
- [ ] 1.3: SellerPatterns 엔티티 생성
Task 2: 패턴 발견 로직 AC-01, AC-05
- [ ] 2.1: 효과 추적 완료 시 패턴 체크 트리거
- [ ] 2.2: adviceType별 결과 집계 쿼리
- [ ] 2.3: 패턴 조건 판정 (3회+, 70%+)
- [ ] 2.4: preferredActions / avoidedActions 분류
Task 3: 패턴 저장/갱신 AC-03, AC-04
- [ ] 3.1: 신규 패턴 등록 로직
- [ ] 3.2: 기존 패턴 갱신 로직
- [ ] 3.3: avgRoasChange 계산 (가중 평균)
Task 4: S53 E-04 연계 AC-06
- [ ] 4.1: apply_rate 계산 로직
- [ ] 4.2: positive_outcome_rate 계산 로직
- [ ] 4.3: SellerAIContext 호환 포맷 확인
Task 5: API AC-07
- [ ] 5.1: GET /api/seller-patterns 엔드포인트
- [ ] 5.2: 인증 및 권한 체크
- [ ] 5.3: 응답 DTO 정의
Dev Notes
아키텍처 패턴
| 항목 | 내용 |
|---|---|
| 사용할 패턴 | Event-driven (효과 추적 완료 시 트리거) |
| 참고 구현 | S53 E-04 SellerAIContext 스펙 |
| 피해야 할 것 | 실시간 집계 (배치 또는 이벤트 기반) |
의존성
| 항목 | 상태 | 설명 |
|---|---|---|
| 선행 작업 | E-10-S-05 | 효과 추적 완료 이벤트 필요 |
| 후행 작업 | E-10-S-10 | 패턴 표시 UI |
| 연계 | S53 E-04 | SellerAIContext 데이터 제공 |
영향 받는 소스 트리
src/
├── entities/
│ └── SellerPatterns.ts # 🆕 신규 생성
├── repositories/
│ └── SellerPatternsRepository.ts # 🆕 신규 생성
├── services/
│ ├── EffectTrackingService.ts # 수정: 패턴 체크 트리거
│ └── PatternDiscoveryService.ts # 🆕 신규 생성
├── controllers/
│ └── SellerPatternsController.ts # 🆕 신규 생성
└── migrations/
└── YYYYMMDD_create_seller_patterns.ts # 🆕 신규 생성S53 E-04 연계 데이터 포맷
typescript
// S53 E-04 SellerAIContext 호환
interface SellerPatternsForAI {
applyRate: number; // 0.0 ~ 1.0
positiveOutcomeRate: number; // 0.0 ~ 1.0
preferredActions: string[]; // ['bidding_down', 'roas_up']
avoidedActions: string[]; // ['keyword_add']
}이벤트 로깅
| 이벤트명 | 트리거 | 파라미터 | GA4 여부 |
|---|---|---|---|
pattern_discovered | 새 패턴 발견 | `{adviceType, patternType: 'preferred' | 'avoided', trialCount, rate}` |
pattern_updated | 기존 패턴 갱신 | {adviceType, newTrialCount, newRate} | ❌ (내부용) |
테스트 시나리오
| # | 시나리오 | 예상 결과 |
|---|---|---|
| 1 | bidding_down 3회 중 3회 positive | preferredActions에 등록 (100%) |
| 2 | keyword_add 4회 중 3회 negative | avoidedActions에 등록 (75%) |
| 3 | roas_up 3회 중 2회 positive (66%) | 패턴 미등록 (70% 미달) |
| 4 | bidding_down 2회 positive | 패턴 미등록 (3회 미달) |
| 5 | 기존 패턴 adviceType에 4번째 결과 추가 | 기존 패턴 갱신 |
| 6 | apply_rate, positive_outcome_rate 계산 | S53 E-04 연계 필드 정상 |
생성일: 2026-01-29
📋 Penny
