Skip to content

Story: 상품 삭제 API (개별/일괄)

메타

항목
Story IDE-09-S-02
EpicE-09 미사용 상품 정리
상태ready-for-dev
우선순위P0
규모M
담당 개발자BE

사용자 스토리

As a 셀러,
I want 더 이상 판매하지 않는 상품을 삭제하고 싶다,
So that 원가입력 화면이 깔끔해진다.


수락 기준 (Acceptance Criteria)

AC-01: 개별 삭제

항목내용
Given셀러가 특정 상품에 대해
When삭제 API를 호출하면
Then해당 상품이 Soft Delete 처리된다

AC-02: 일괄 삭제

항목내용
Given셀러가 여러 상품을 선택하고
When일괄 삭제 API를 호출하면
Then선택한 모든 상품이 Soft Delete 처리된다

AC-03: 삭제 후 조회 제외

항목내용
Given상품이 삭제된 후
When상품 목록을 조회하면
Then삭제된 상품은 기본적으로 제외된다

태스크 분해

Task 1: 개별 삭제 API

  • [ ] 1.1: DELETE /products/
    • Soft Delete: deleted_at = NOW()
    • deleted_by = 'seller'
  • [ ] 1.2: 권한 검증 (본인 상품만 삭제 가능)
  • [ ] 1.3: 이미 삭제된 상품 처리 (멱등성)

Task 2: 일괄 삭제 API

  • [ ] 2.1: DELETE /products/batch
    • Request:
    • 최대 100개 제한
  • [ ] 2.2: 비동기 처리 (대량 삭제 시)
  • [ ] 2.3: 부분 실패 처리

Task 3: 응답 처리

  • [ ] 3.1: 삭제 결과 응답
    • 성공 건수, 실패 건수, 실패 사유
  • [ ] 3.2: 복구 가능 안내 포함

API 스펙

개별 삭제

DELETE /api/products/{productId}

Response 200:
{
  "success": true,
  "message": "상품이 삭제되었습니다. 7일 내 복구 가능합니다.",
  "deletedAt": "2026-01-20T10:00:00Z",
  "recoveryDeadline": "2026-01-27T10:00:00Z"
}

일괄 삭제

DELETE /api/products/batch

Request:
{
  "productIds": ["prod_001", "prod_002", "prod_003"]
}

Response 200:
{
  "success": true,
  "totalRequested": 3,
  "deletedCount": 3,
  "failedCount": 0,
  "failures": [],
  "message": "3개 상품이 삭제되었습니다.",
  "recoveryDeadline": "2026-01-27T10:00:00Z"
}

개발 노트

Soft Delete 처리

typescript
async deleteProduct(productId: string, sellerId: string) {
  // 1. 권한 검증
  const product = await this.productRepo.findOne({ id: productId, sellerId });
  if (!product) throw new NotFoundException('상품을 찾을 수 없습니다');

  // 2. 이미 삭제된 경우
  if (product.deletedAt) {
    return { success: true, message: '이미 삭제된 상품입니다' };
  }

  // 3. Soft Delete
  await this.productRepo.update(productId, {
    deletedAt: new Date(),
    deletedBy: 'seller'
  });

  return { success: true, recoveryDeadline: addDays(new Date(), 7) };
}

일괄 삭제 제한

  • 최대 100개/요청
  • 초과 시 400 Bad Request
  • 대량 삭제는 비동기 처리 권장

이벤트 로깅

이벤트파라미터
product_delete_confirmseller_id, product_count
product_batch_deleteseller_id, product_count, success_count

생성일: 2026-01-20

장사왕 Product Team