[BE-10] LimitedDropApiController + 피처 플래그 config (통합)

작업 내용 (설계 의도)

변경 사항

한정판 REST 진입점과 상태코드 매핑, 피처 플래그 설정을 와이어업한다(근거 TDD: “API 계약”, “Release Scenario”). 공통 파일(application.yml) 단독 수정 통합 티켓 — 마지막 wave 단독 배치(Single Writer). 롤백: limited-drop.enabled=false로 엔드포인트 즉시 비활성.

  • LimitedDropApiController(presentation): POST /limited-drops(개설)·GET /limited-drops/{id}·POST /limited-drops/{id}/orders(구매)·GET /limited-drops/{id}/stats.
  • Request/Response DTO: CreateLimitedDropRequest·PurchaseLimitedDropRequest(quantity)·LimitedDropResponse(dropId·productId·status·openAt·closeAt·remaining·perUserLimit — FE QuantityStepper 상한용)·LimitedDropStatsResponse. header X-User-Id·Idempotency-Key (기존 GoodsOrderApiController 관례).
  • 예외→상태코드 매핑(@ExceptionHandler 또는 ControllerAdvice): TooEarly→425(openAt 포함)·SoldOut/Closed→409·Throttled→429·PerUserLimit→403. 정상 실패는 5xx 아님.
  • 구매 성공 응답 202 Accepted(주문 PENDING=선점).
  • 피처 플래그 config: limited-drop.enabled·limited-drop.redis-gate.enabled·세마포어 permit 수·acquire timeout(application.yml + ConfigurationProperties). 플래그 OFF 시 엔드포인트 404/비활성.

의존

  • BE-07 (Purchase), BE-08 (Create), BE-09 (Get·Stats)

다이어그램

클래스 의존

flowchart LR
    LimitedDropApiController --> PurchaseLimitedDropUseCase
    LimitedDropApiController --> CreateLimitedDropUseCase
    LimitedDropApiController --> GetLimitedDropUseCase
    LimitedDropApiController --> GetLimitedDropStatsUseCase

테스트 케이스

  • 구매 성공 시 202와 orderId를 반환한다 (MockMvc)
  • now<openAt이면 425와 openAt을 응답한다
  • 소진 후 구매는 409 SoldOut을 반환한다
  • 완충 초과는 429를 반환한다
  • 1인 한도 초과는 403을 반환한다
  • limited-drop.enabled=false면 구매 엔드포인트가 비활성(404/503)이다