diff --git a/docs/20260929_크리에이터_선물하기/client-api-summary.md b/docs/20260929_크리에이터_선물하기/client-api-summary.md index 2e22f448..be779547 100644 --- a/docs/20260929_크리에이터_선물하기/client-api-summary.md +++ b/docs/20260929_크리에이터_선물하기/client-api-summary.md @@ -26,16 +26,16 @@ PRD에는 상세 API 계약, request/response 예시, 요구사항을 유지한 | 사용자 | Method | URI | 역할 | Request | Response | |---|---:|---|---|---|---| | 팬 | POST | `/api/v2/gifts` | 크리에이터에게 선물을 신청하고 최종 결제 금액만큼 캔을 차감한다. | body: `recipientMemberId`, `senderName`, `senderPhoneNumber`, `senderZipCode`, `senderAddress`, `senderAddressDetail`, `sizeCode`, `categoryId`, `senderTermsAgreed`, `senderPrivacyAgreed`, `damageWaiverAgreed` | `applicationNo`, `status`, `statusName`, `priceCan`, `trackingDeadlineAt` | -| 팬 | POST | `/api/v2/gifts/{applicationNo}/cancel` | 운송장 등록 전 선물 신청을 취소하고 전액 환불한다. | path: `applicationNo` | `applicationNo`, `status`, `refundedCan` | -| 팬 | POST | `/api/v2/gifts/{applicationNo}/tracking` | 발송 후 택배사와 운송장 번호를 등록한다. | path: `applicationNo`, body: `courierCompanyName`, `trackingNumber` | `applicationNo`, `status`, `recipientAddressDeadlineAt` | +| 팬 | POST | `/api/v2/gifts/{applicationNo}/cancel` | 운송장 등록 전 선물 신청을 취소하고 전액 환불한다. | path: `applicationNo` | `applicationNo`, `status`, `statusName`, `priceCan`, `canceledAt` | +| 팬 | POST | `/api/v2/gifts/{applicationNo}/tracking` | 발송 후 택배사와 운송장 번호를 등록한다. | path: `applicationNo`, body: `courierCompanyName`, `trackingNumber` | `applicationNo`, `status`, `statusName`, `courierCompanyName`, `trackingNumber`, `trackingRegisteredAt`, `recipientAddressDeadlineAt` | | 팬 | POST | `/api/v2/gifts/{applicationNo}/review` | 전달 완료된 선물에 리뷰를 작성한다. | path: `applicationNo`, body: `rating`, `keywords`, `comment` | `reviewId`, `applicationNo`, `rating`, `keywords`, `comment`, `createdAt` | ## 크리에이터 API | 사용자 | Method | URI | 역할 | Request | Response | |---|---:|---|---|---|---| -| 크리에이터 | POST | `/api/v2/gifts/{applicationNo}/recipient-address` | 운송장 등록 이후 배송지와 수령 약관 동의를 등록한다. | path: `applicationNo`, body: `recipientName`, `recipientPhoneNumber`, `recipientZipCode`, `recipientAddress`, `recipientAddressDetail`, `recipientTermsAgreed`, `recipientPrivacyAgreed` | `applicationNo`, `recipientAddressRegisteredAt` | -| 크리에이터 | POST | `/api/v2/gifts/{applicationNo}/delivery-complete` | 검수 완료된 선물을 직접 수령 완료 처리한다. | path: `applicationNo` | `applicationNo`, `status`, `deliveredAt` | +| 크리에이터 | POST | `/api/v2/gifts/{applicationNo}/recipient-address` | 운송장 등록 이후 배송지와 수령 약관 동의를 등록한다. | path: `applicationNo`, body: `recipientName`, `recipientPhoneNumber`, `recipientZipCode`, `recipientAddress`, `recipientAddressDetail`, `recipientTermsAgreed`, `recipientPrivacyAgreed` | `applicationNo`, `status`, `statusName`, `recipientAddressRegisteredAt` | +| 크리에이터 | POST | `/api/v2/gifts/{applicationNo}/delivery-complete` | 검수 완료된 선물을 직접 수령 완료 처리한다. | path: `applicationNo` | `applicationNo`, `status`, `statusName`, `deliveredAt` | ## 관리자 API @@ -58,6 +58,238 @@ PRD에는 상세 API 계약, request/response 예시, 요구사항을 유지한 - `AdminGiftSizePriceResponse`: `sizeCode`, `name`, `basePriceCan`, `salePriceCan`, `isActive` - `AdminGiftOperationStatusResponse`: `applicationNo`, `status`, `statusName`, `occurredAt` +## Kotlin DTO 형태 + +아래는 JSON으로 변환되기 직전의 API request/response `data class` 형태다. `companion object` 변환 함수는 클라이언트 입력/출력 형태와 직접 관련이 없어 생략했다. + +### 사용자 Request DTO + +```kotlin +data class GiftApplicationRequest( + val recipientMemberId: Long, + val senderName: String, + val senderPhoneNumber: String, + val senderZipCode: String, + val senderAddress: String, + val senderAddressDetail: String?, + val sizeCode: GiftSize, + val categoryId: Long, + val senderTermsAgreed: Boolean, + val senderPrivacyAgreed: Boolean, + val damageWaiverAgreed: Boolean +) + +data class GiftTrackingRegistrationRequest( + val courierCompanyName: String, + val trackingNumber: String +) + +data class GiftRecipientAddressRegistrationRequest( + val recipientName: String, + val recipientPhoneNumber: String, + val recipientZipCode: String, + val recipientAddress: String, + val recipientAddressDetail: String?, + val recipientTermsAgreed: Boolean, + val recipientPrivacyAgreed: Boolean +) + +data class GiftReviewRequest( + val rating: Int, + val keywords: List, + val comment: String? +) +``` + +### 사용자 Response DTO + +```kotlin +data class GiftFormOptionsResponse( + val sizes: List, + val categories: List +) + +data class GiftSizeOptionResponse( + val sizeCode: String, + val name: String, + val basePriceCan: Int, + val salePriceCan: Int +) + +data class GiftCategoryOptionResponse( + val categoryId: Long, + val name: String, + val requiresDamageWaiver: Boolean +) + +data class GiftListResponse( + val totalCount: Long, + val items: List, + val page: Int, + val size: Int, + val hasNext: Boolean +) + +data class GiftListItemResponse( + val applicationNo: String, + val direction: String, + val status: String, + val statusName: String, + val priceCan: Int, + val categoryName: String, + val sizeName: String, + val createdAt: LocalDateTime? +) + +data class GiftDetailResponse( + val applicationNo: String, + val direction: String, + val status: String, + val statusName: String, + val giftInfo: GiftDetailInfoResponse, + val senderInfo: GiftAddressResponse?, + val recipientAddress: GiftAddressResponse?, + val mailbox: GiftMailboxResponse?, + val trackingRequired: Boolean, + val recipientAddressRequired: Boolean, + val recipientAddressDeadlineAt: LocalDateTime?, + val delivery: GiftDeliveryInfoResponse, + val statusTimeline: List +) + +data class GiftDetailInfoResponse( + val recipientCreatorNickname: String?, + val senderNickname: String?, + val sizeName: String, + val categoryName: String, + val applicationNo: String?, + val paidCan: Int?, + val tracking: String?, + val shippingRequestedAt: LocalDateTime? +) + +data class GiftAddressResponse( + val name: String, + val phoneNumber: String, + val address: String +) + +data class GiftMailboxResponse( + val name: String, + val address: String, + val phoneNumber: String +) + +data class GiftDeliveryInfoResponse( + val canceledAt: LocalDateTime?, + val undeliverableAt: LocalDateTime?, + val undeliverableReason: String? +) + +data class GiftStatusTimelineResponse( + val status: String, + val statusName: String, + val occurredAt: LocalDateTime? +) + +data class GiftApplicationResponse( + val applicationNo: String, + val status: String, + val statusName: String, + val priceCan: Int, + val trackingDeadlineAt: LocalDateTime +) + +data class GiftCancellationResponse( + val applicationNo: String, + val status: String, + val statusName: String, + val priceCan: Int, + val canceledAt: LocalDateTime +) + +data class GiftTrackingRegistrationResponse( + val applicationNo: String, + val status: String, + val statusName: String, + val courierCompanyName: String, + val trackingNumber: String, + val trackingRegisteredAt: LocalDateTime, + val recipientAddressDeadlineAt: LocalDateTime +) + +data class GiftRecipientAddressRegistrationResponse( + val applicationNo: String, + val status: String, + val statusName: String, + val recipientAddressRegisteredAt: LocalDateTime +) + +data class GiftDeliveryConfirmationResponse( + val applicationNo: String, + val status: String, + val statusName: String, + val deliveredAt: LocalDateTime +) + +data class GiftReviewResponse( + val reviewId: Long, + val applicationNo: String, + val rating: Int, + val keywords: List, + val comment: String?, + val createdAt: LocalDateTime? +) +``` + +### 관리자 Request DTO + +```kotlin +data class AdminGiftCategoryRequest( + val categoryCode: String, + val name: String, + val requiresDamageWaiver: Boolean, + val isActive: Boolean +) + +data class AdminGiftSizePriceRequest( + val basePriceCan: Int, + val salePriceCan: Int, + val isActive: Boolean +) + +data class AdminGiftMarkUndeliverableRequest( + val reason: String +) +``` + +### 관리자 Response DTO + +```kotlin +data class AdminGiftCategoryResponse( + val categoryId: Long, + val categoryCode: String, + val name: String, + val requiresDamageWaiver: Boolean, + val isActive: Boolean +) + +data class AdminGiftSizePriceResponse( + val sizeCode: String, + val name: String, + val basePriceCan: Int, + val salePriceCan: Int, + val isActive: Boolean +) + +data class AdminGiftOperationStatusResponse( + val applicationNo: String, + val status: GiftStatus, + val statusName: String, + val occurredAt: LocalDateTime +) +``` + ## 클라이언트 구현 참고 - 선물 푸시 딥링크는 `deepLinkValue=GIFT_DETAIL`, `deepLinkId=applicationNo`를 사용한다.