테마
Story: 쿠폰 생성/수정/비활성화 API
메타
| 항목 | 값 |
|---|---|
| Story ID | E-02-S-02 |
| Epic | E-02 어드민 강화 |
| 상태 | draft |
| 우선순위 | P0 |
| 규모 | M |
| 담당 개발자 | BE (하록님) |
사용자 스토리
As a 운영팀 관리자, I want 쿠폰을 직접 생성하고 수정하고 비활성화, So that 개발팀 요청 없이 프로모션을 즉시 실행할 수 있다.
수락 기준 (Acceptance Criteria)
AC-01: 쿠폰 생성
| 항목 | 내용 |
|---|---|
| Given | 관리자가 쿠폰 생성 폼을 작성한 상태 |
| When | 생성 버튼 클릭 |
| Then | 쿠폰이 생성되고 목록에 표시됨 |
요청 필드:
{
code: string, // 필수, 유니크
type: "FIXED" | "PERCENT" | "TRIAL_EXT", // 필수
description: string, // 선택
// type별 필수 필드
discountAmount?: number, // FIXED일 때 필수
discountPercent?: number, // PERCENT일 때 필수
maxDiscount?: number, // PERCENT일 때 선택 (최대 할인 금액)
trialDays?: number, // TRIAL_EXT일 때 필수
minAmount?: number, // 최소 결제 금액 (선택)
startDate: string, // 필수 (ISO8601)
endDate: string, // 필수 (ISO8601)
maxUsageTotal?: number, // 총 사용 가능 횟수 (선택, null=무제한)
maxUsagePerUser?: number, // 사용자당 사용 횟수 (선택, 기본 1)
applicablePlans?: string[], // 적용 가능 플랜 (선택, null=전체)
firstOnlyYn?: boolean // 첫 결제만 (선택, 기본 false)
}검증 규칙:
code: 중복 불가 (DB UK)startDate: 현재 이후endDate: startDate 이후type=FIXED: discountAmount 필수type=PERCENT: discountPercent 필수 (1~100)type=TRIAL_EXT: trialDays 필수
AC-02: 쿠폰 수정
| 항목 | 내용 |
|---|---|
| Given | 기존 쿠폰 상세 화면 |
| When | 수정 후 저장 |
| Then | 변경 사항이 저장됨 |
수정 가능 필드:
descriptionendDate(연장만 가능, 단축 불가)maxUsageTotal(증가만 가능)maxUsagePerUseractiveYn
수정 불가 필드 (이미 사용된 쿠폰 보호):
codetypediscountAmount,discountPercent,trialDaysstartDateminAmountapplicablePlansfirstOnlyYn
AC-03: 쿠폰 비활성화
| 항목 | 내용 |
|---|---|
| Given | 활성 상태의 쿠폰 |
| When | 비활성화 버튼 클릭 |
| Then | 쿠폰이 즉시 비활성화되어 사용 불가 |
상세 스펙:
activeYn = false설정- 이미 적용된 결제 건에는 영향 없음
- 비활성화 후 재활성화 가능
AC-04: 중복 코드 생성 시도
| 항목 | 내용 |
|---|---|
| Given | 이미 존재하는 쿠폰 코드 |
| When | 동일 코드로 생성 시도 |
| Then | 400 Bad Request + "이미 존재하는 쿠폰 코드입니다" |
AC-05: 유효하지 않은 날짜
| 항목 | 내용 |
|---|---|
| Given | startDate > endDate 또는 startDate < 현재 |
| When | 생성 시도 |
| Then | 400 Bad Request + 상세 에러 메시지 |
태스크 분해
Task 1: 쿠폰 생성 API AC-01, AC-04, AC-05
- [ ] 1.1:
POST /admin/coupons엔드포인트 생성 - [ ] 1.2: 요청 DTO 정의 + class-validator 데코레이터
- [ ] 1.3: type별 필수 필드 검증 로직
- [ ] 1.4: 날짜 검증 로직 (startDate, endDate)
- [ ] 1.5: 중복 코드 검증 (try-catch DB UK)
- [ ] 1.6: 쿠폰 생성 후 응답 반환
Task 2: 쿠폰 수정 API AC-02
- [ ] 2.1:
PATCH /admin/coupons/:id엔드포인트 생성 - [ ] 2.2: 수정 가능 필드 제한 로직
- [ ] 2.3: endDate 연장만 허용 검증
- [ ] 2.4: maxUsageTotal 증가만 허용 검증
- [ ] 2.5: 404 처리
Task 3: 쿠폰 비활성화 API AC-03
- [ ] 3.1:
POST /admin/coupons/:id/deactivate엔드포인트 생성 - [ ] 3.2: activeYn = false 업데이트
- [ ] 3.3: 이미 비활성화된 경우 처리 (멱등성)
- [ ] 3.4: 404 처리
Task 4: 테스트 작성
- [ ] 4.1: 생성 API 테스트 (type별 검증)
- [ ] 4.2: 중복 코드 테스트
- [ ] 4.3: 날짜 검증 테스트
- [ ] 4.4: 수정 API 테스트 (제한 필드)
- [ ] 4.5: 비활성화 API 테스트
Task 5: 마무리
- [ ] 5.1: API 문서화 (Swagger/OpenAPI)
- [ ] 5.2: 에러 메시지 한글화
- [ ] 5.3: PR 생성
Dev Notes (AI Agent 최적화)
아키텍처 패턴
| 항목 | 내용 |
|---|---|
| 사용할 패턴 | Repository Pattern + Service Layer |
| 참고 구현 | E-02-S-01과 동일 모듈 |
| 피해야 할 것 | 수정 불가 필드 변경 허용 |
영향 받는 소스 트리
src/
├── admin/
│ └── coupon/
│ ├── coupon.admin.controller.ts # 수정 (CUD 엔드포인트 추가)
│ ├── coupon.admin.service.ts # 수정 (CUD 메서드 추가)
│ └── dto/
│ ├── create-coupon.dto.ts # 🆕 신규 생성
│ └── update-coupon.dto.ts # 🆕 신규 생성
└── tests/
└── admin/
└── coupon.admin.spec.ts # 수정 (CUD 테스트 추가)비즈니스 로직 상세
Type별 필수 필드 검증
typescript
// 유사 코드
if (type === 'FIXED' && !discountAmount) {
throw new BadRequestException('정액 할인 쿠폰은 할인 금액이 필수입니다');
}
if (type === 'PERCENT' && !discountPercent) {
throw new BadRequestException('정률 할인 쿠폰은 할인율이 필수입니다');
}
if (type === 'TRIAL_EXT' && !trialDays) {
throw new BadRequestException('무료체험 연장 쿠폰은 연장 일수가 필수입니다');
}수정 제한 로직
typescript
// 유사 코드
const immutableFields = ['code', 'type', 'discountAmount', ...];
for (const field of immutableFields) {
if (dto[field] !== undefined && dto[field] !== existing[field]) {
throw new BadRequestException(`${field}는 수정할 수 없습니다`);
}
}충돌 감지
| 항목 | 상태 | 설명 |
|---|---|---|
| 기존 코드 충돌 | ✅ 없음 | E-02-S-01 모듈 확장 |
| API 계약 변경 | ✅ 없음 | 신규 엔드포인트 |
| DB 스키마 변경 | ✅ 없음 | 기존 테이블 사용 |
| 환경 변수 변경 | ✅ 없음 | - |
References
| 출처 | 경로/링크 | 참조 섹션 |
|---|---|---|
| Epic Spec | .context/sprints/s53/epic-specs/E-02.md | 쿠폰 API 설계, EDGE |
| 테이블 스키마 | S52 E-07 DDL | Coupon 테이블 |
| E-02-S-01 | ./E-02-S-01.md | 동일 모듈 |
Dev Agent Record
| 항목 | 값 |
|---|---|
| 생성 Agent | Claude Opus 4.5 |
| 생성일 | 2026-01-27 |
| 마지막 수정 | 2026-01-27 |
| 검증자 | - |
검증 결과: 🔄 PENDING (PO 승인 대기) 검증일: -
생성일: 2026-01-27마지막 수정: 2026-01-27
