테마
Story: 미사용 상품 필터 API
메타
| 항목 | 값 |
|---|---|
| Story ID | E-09-S-04 |
| Epic | E-09 미사용 상품 정리 |
| 상태 | ready-for-dev |
| 우선순위 | P1 |
| 규모 | M |
| 담당 개발자 | BE |
사용자 스토리
As a 셀러,
I want 최근에 판매가 없는 상품을 필터링하고 싶다,
So that 정리할 상품을 쉽게 찾을 수 있다.
수락 기준 (Acceptance Criteria)
AC-01: 미사용 상품 필터
| 항목 | 내용 |
|---|---|
| Given | 상품 목록 조회 시 |
| When | 미사용 필터를 적용하면 |
| Then | 최근 N일간 판매 없는 상품만 표시된다 |
AC-02: 기간 조정
| 항목 | 내용 |
|---|---|
| Given | 미사용 필터에서 |
| When | 기간을 선택하면 |
| Then | 30일/60일/90일/180일 중 선택 가능 |
AC-03: 미사용 상품 수 표시
| 항목 | 내용 |
|---|---|
| Given | 상품 목록 페이지에서 |
| When | 미사용 상품 배지를 확인하면 |
| Then | "📦 미사용 상품 15개" 형태로 수가 표시된다 |
태스크 분해
Task 1: 미사용 상품 조회 API
- [ ] 1.1: GET /products?filter=unused&days=90
- 최근 N일간 판매 없는 상품
- 신규 등록 상품 제외 (등록 후 30일 미만)
- [ ] 1.2: 페이지네이션 지원
- [ ] 1.3: 정렬 옵션 (최근 판매일 순)
Task 2: 미사용 상품 카운트 API
- [ ] 2.1: GET /products/unused/count
- 기간별 미사용 상품 수 반환
- [ ] 2.2: 캐싱 적용 (무거운 쿼리)
Task 3: 쿼리 최적화
- [ ] 3.1: Settlement 테이블 조인 최적화
- [ ] 3.2: 인덱스 활용 확인
- [ ] 3.3: 성능 테스트
API 스펙
미사용 상품 목록
GET /api/products?filter=unused&days=90&page=1&limit=20
Response 200:
{
"products": [
{
"id": "prod_001",
"name": "기본 티셔츠",
"sku": "SKU-002",
"lastSaleDate": "2025-10-01",
"daysSinceLastSale": 111,
"costPrice": null,
"createdAt": "2025-05-01"
}
],
"total": 15,
"page": 1,
"limit": 20,
"filterDays": 90
}미사용 상품 카운트
GET /api/products/unused/count
Response 200:
{
"counts": {
"30": 5,
"60": 10,
"90": 15,
"180": 25
}
}개발 노트
미사용 상품 쿼리
sql
SELECT p.id, p.name, p.sku, MAX(s.settlement_date) AS last_sale_date
FROM Product p
LEFT JOIN Settlement s ON p.id = s.product_id
AND s.settlement_date >= DATE_SUB(NOW(), INTERVAL 90 DAY)
WHERE p.seller_id = ?
AND p.deleted_at IS NULL
AND p.created_at < DATE_SUB(NOW(), INTERVAL 30 DAY) -- 신규 제외
GROUP BY p.id, p.name, p.sku
HAVING last_sale_date IS NULL
ORDER BY p.created_at DESC
LIMIT 20 OFFSET 0;주의사항
⚠️ 쿼리 성능 주의
• Settlement 테이블도 무거움
• 인덱스 활용 필수: (seller_id, product_id, settlement_date)
• 결과 캐싱 권장 (5분)필터 기간 옵션
| 옵션 | 설명 |
|---|---|
| 30일 | 최근 1개월 판매 없음 |
| 60일 | 최근 2개월 판매 없음 |
| 90일 | 최근 3개월 판매 없음 (기본값) |
| 180일 | 최근 6개월 판매 없음 |
이벤트 로깅
| 이벤트 | 파라미터 |
|---|---|
unused_filter_apply | seller_id, days, unused_count |
생성일: 2026-01-20
