Skip to content

Story: 쿠폰 생성/수정/비활성화 API

메타

항목
Story IDE-02-S-02
EpicE-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변경 사항이 저장됨

수정 가능 필드:

  • description
  • endDate (연장만 가능, 단축 불가)
  • maxUsageTotal (증가만 가능)
  • maxUsagePerUser
  • activeYn

수정 불가 필드 (이미 사용된 쿠폰 보호):

  • code
  • type
  • discountAmount, discountPercent, trialDays
  • startDate
  • minAmount
  • applicablePlans
  • firstOnlyYn

AC-03: 쿠폰 비활성화

항목내용
Given활성 상태의 쿠폰
When비활성화 버튼 클릭
Then쿠폰이 즉시 비활성화되어 사용 불가

상세 스펙:

  • activeYn = false 설정
  • 이미 적용된 결제 건에는 영향 없음
  • 비활성화 후 재활성화 가능

AC-04: 중복 코드 생성 시도

항목내용
Given이미 존재하는 쿠폰 코드
When동일 코드로 생성 시도
Then400 Bad Request + "이미 존재하는 쿠폰 코드입니다"

AC-05: 유효하지 않은 날짜

항목내용
GivenstartDate > endDate 또는 startDate < 현재
When생성 시도
Then400 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 DDLCoupon 테이블
E-02-S-01./E-02-S-01.md동일 모듈

Dev Agent Record

항목
생성 AgentClaude Opus 4.5
생성일2026-01-27
마지막 수정2026-01-27
검증자-

검증 결과: 🔄 PENDING (PO 승인 대기) 검증일: -


생성일: 2026-01-27마지막 수정: 2026-01-27

장사왕 Product Team