Skip to content

Story: 효과 추적 로직 (Before/After 계산)

메타

항목
Story IDE-10-S-05
EpicE-10 업무노트
상태draft
우선순위P0
규모L
담당 개발자하록 (BE)

사용자 스토리

As a 조언을 적용한 셀러,
I want 적용 전/후 지표 변화를 자동으로 비교해서 보고 싶다,
So that 내가 한 조정이 효과 있었는지 알 수 있다.


수락 기준 (Acceptance Criteria)

AC-01: 효과 추적 시작 시 Before 스냅샷

항목내용
GiveneffectTrackingEnabled = true로 노트가 저장될 때
When노트 생성 시
Then해당 캠페인의 최근 7일 평균 지표가 beforeMetrics에 저장된다
json
beforeMetrics: {
  "roas": 280,
  "profitPer100": 5,
  "adCost": 150000,
  "conversionAmount": 420000,
  "impressions": 50000,
  "clicks": 500,
  "orders": 25,
  "measurePeriod": {
    "start": "2026-01-14",
    "end": "2026-01-20"
  }
}

AC-02: 추적 종료일 자동 설정

항목내용
Given효과 추적이 활성화되면
When노트가 저장될 때
ThentrackingEndDate = 생성일 + 7일로 설정된다

AC-03: 추적 완료 시 After 지표 계산

항목내용
GiventrackingEndDate가 지난 노트가 있을 때
When배치 작업 또는 조회 시
Then적용 후 7일 평균 지표가 afterMetrics에 저장된다
json
afterMetrics: {
  "roas": 385,
  "profitPer100": 18,
  "adCost": 120000,
  "conversionAmount": 462000,
  "impressions": 40000,
  "clicks": 400,
  "orders": 28,
  "measurePeriod": {
    "start": "2026-01-21",
    "end": "2026-01-27"
  }
}

AC-04: 효과 요약 자동 생성

항목내용
GivenafterMetrics가 계산되면
When효과 판정 로직이 실행될 때
TheneffectSummary가 자동 생성된다
판정 기준:
- ROAS +10% 이상 OR 순이익 +10% 이상 → "효과 있음"
- -10% ~ +10% → "변화 없음"
- ROAS -10% 이상 OR 순이익 -10% 이상 → "효과 없음"

effectSummary 예시:
- "ROAS +37% 개선, 100원당 순이익 +13원"
- "광고비 20% 절감하면서 효율 유지"
- "큰 변화 없음. 조금 더 지켜보세요"

AC-05: 데이터 부족 시 처리

항목내용
Given추적 기간 중 데이터가 부족할 때 (클릭 < 30)
WhenAfter 계산 시
TheneffectSummary = "데이터 부족으로 효과 측정 불가"로 설정

AC-06: 삭제된 캠페인 처리

항목내용
Given추적 중인 캠페인이 삭제되면
WhenAfter 계산 시
TheneffectSummary = "캠페인 삭제로 추적 불가"로 설정

태스크 분해

Task 1: Before 스냅샷 AC-01, AC-02

  • [ ] 1.1: 노트 생성 시 캠페인 7일 평균 지표 조회 쿼리
  • [ ] 1.2: beforeMetrics JSON 저장
  • [ ] 1.3: trackingEndDate 자동 계산 (+7일)

Task 2: After 계산 배치 AC-03

  • [ ] 2.1: trackingEndDate 지난 노트 조회 (스케줄러)
  • [ ] 2.2: 적용 후 7일 평균 지표 계산
  • [ ] 2.3: afterMetrics 업데이트

Task 3: 효과 판정 로직 AC-04

  • [ ] 3.1: Before/After 비교 알고리즘
  • [ ] 3.2: 효과 판정 (positive/neutral/negative)
  • [ ] 3.3: effectSummary 문구 생성

Task 4: 예외 처리 AC-05, AC-06

  • [ ] 4.1: 데이터 부족 판정 (클릭 < 30)
  • [ ] 4.2: 삭제된 캠페인 체크
  • [ ] 4.3: 예외 상황 effectSummary 설정

Task 5: API 확장

  • [ ] 5.1: GET /api/work-notes/:id 에 효과 결과 포함
  • [ ] 5.2: 수동 효과 재계산 API (선택)

Dev Notes

아키텍처 패턴

항목내용
사용할 패턴배치 처리 (Scheduler) + On-demand 계산
참고 구현기존 캠페인 지표 집계 로직 참고
피해야 할 것무거운 테이블 Full scan, 실시간 계산 부하

영향 받는 소스 트리

src/
├── services/
│   └── EffectTrackingService.ts    # 🆕 신규 생성
├── jobs/
│   └── EffectTrackingJob.ts        # 🆕 신규 생성 (스케줄러)
├── repositories/
│   └── CampaignMetricsRepository.ts # 수정: 7일 평균 쿼리 추가
└── utils/
    └── effectSummaryGenerator.ts   # 🆕 신규 생성

지표 계산 SQL (참고)

sql
-- 7일 평균 지표 조회
SELECT
  AVG(roas) as roas,
  AVG(profitPer100) as profitPer100,
  SUM(adCost) as adCost,
  SUM(conversionAmount) as conversionAmount,
  SUM(impressions) as impressions,
  SUM(clicks) as clicks,
  SUM(orders) as orders
FROM campaign_daily_metrics
WHERE campaign_id = :campaignId
  AND date BETWEEN :startDate AND :endDate

충돌 감지

항목상태설명
기존 코드 충돌⚠️ 주의캠페인 지표 조회 로직 공유
API 계약 변경✅ 없음-
DB 스키마 변경✅ 없음WorkNote 테이블 내 JSON 컬럼
환경 변수 변경✅ 없음-

이벤트 로깅

이벤트명트리거파라미터GA4 여부
start_effect_tracking추적 시작{campaignId}
complete_effect_tracking추적 완료`{effectResult: 'positive''neutral'

생성일: 2026-01-21

장사왕 Product Team