[PetLink] Order Api [ 1 ]

DeadWhale·2023년 8월 1일


image


저는 디자이너가 아니여서 참 다행인것 같습니다.

이런 리워드 주문 화면이 있습니다.
이제 주문을 진행해야 합니다.

주문버튼을 누르는 순간 제 서비스에서는 이런식으로 동작한다고 전제 하였습니다.

1. 사용자가 주문을 누름
2. 서버로 주문 정보를 전송 , 
3. 서버에서 요청을 수락
   3-1. 주문한 리워드들의 재고를 확인 ( 동시성 제어 : Redisson )
   3-2. 락을 점유하고 성공적일 경우 재고 감소 로직 수행 
   3-3. 주문된 모드 리워드 엔티티의 재고 감소가 진행 된 후 결제 번호 생성
4. 생성된 주문 번호와 결제 정보를 반환

이 때 주의 점

1. A,B,C 리워드를 구매 했을때 , A,B는 정상적으로 구매하여도
C가 결과적으로 lock 점유에 실패 하면 A,B 리워드의 재고도 회복되어야 한다.

2. 동시에 여러 사용자가 접근 시 동시성이 관리되어야 한다.

3. 최대 구매 갯수를 초과하는지?

4. 멱등성을 보장하는가?


이러한 내용을 기반으로 Request DTO Class를 설계해보려합니다.
일단 Orders의 Entity를 보자면

@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Entity
@Table(name = "orders")
public class Orders extends BaseTimeEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id; 

    @ManyToOne
    @JoinColumn(name = "funding_id", nullable = false)
    private Funding funding;   //펀딩 정보

    @ManyToOne
    @JoinColumn(name = "member_id")
    private Member member; //주문자 정보 (비회원일 경우 null)

    @Builder.Default
    @OneToMany(mappedBy = "orders", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
    private List<FundingItemOrder> fundingItemOrders = new ArrayList<>(); //주문 리워드 내역
    private String paymentNumber;   //결제번호

    private String parcelCode;  //송장코드
    private String parcelCompany;   //택배사

    @Enumerated(EnumType.STRING)
    private PayMethod payMethod;   //결제수단
    private Boolean priceOpen;  //금액공개여부
    private Boolean nameOpen;    //이름공개여부
    private String recipient;   //수령인

    @Embedded
    private Address address;    //주소
    private String mobilePhone; //휴대폰번호_1
    private String subPhone;    //휴대폰번호_2
}

여기서 받아야 할 정보를 추려보겠습니다.

1. 어느 펀딩인가 : 펀딩 ID
2. 누가 주문하는가 : 멤버 ID (비회원 구매도 존재)
3. 어떤 리워드들을 주문하는가 
	3.1. 구매할 리워드의 ID
    3.2. 구매할 리워드의 갯수
4. 주문자의 주소 정보
	4.1. 우편번호
    4.2.  주소
    4.3.  상세주소
5. 결제수단
6. 금액 공개 여부
7. 이름 공개 여부
8. 수령인
9. 휴대전화
10. 보조 휴대전화
--------------------------------------------------------------
@Getter
@Builder
public class OrderRequest {
    @NotNull(message = "펀딩 ID는 필수 값입니다.")
    private Long fundingId;
    @NotNull(message = "결제 방법은 필수 값입니다.")
    private PayMethod payMethod;
    private boolean amountOpen;
    private boolean nameOpen;
    @NotEmpty(message = "펀딩 아이템은 최소 1개 이상이어야 합니다.")
    private List<FundingItemDto> fundingItems;
    @NotBlank(message = "우편 번호는 필수 값입니다.")
    private String zipCode;
    @NotBlank(message = "주소는 필수 값입니다.")
    private String address;
    @NotBlank(message = "상세 주소는 필수 값입니다.")
    private String detailAddress;
    @NotBlank(message = "수령인은 필수 값입니다.")
    private String recipient;
    @NotBlank(message = "전화번호는 필수 값입니다.")
    @Pattern(regexp = "^\\d{10,11}$", message = "전화번호 형식이 올바르지 않습니다.")
    private String phone;
    @Pattern(regexp = "^\\d{10,11}$", message = "전화번호 형식이 올바르지 않습니다.")
    private String subPhone;
}

이번에는 반환할만한 정보를 추려보겠습니다.

1. 주문번호
2. 주문아이디
3. 펀딩번호
4. 회원번호
5. 주문한 리워드 제목들
6. 주문상태
7. 금액공개여부
8. 이름공개여부
--------------------------------------------------------------
@Getter
@Builder
public class OrderResponseDto {
    private Long orderNumber; // 주문번호
    private Long orderId;     // 주문아이디
    private Long fundingId;   // 펀딩번호
    private Long memberId;    // 회원번호
    private List<String> orderedRewards; // 주문한 리워드 제목들
    @Builder.Default
    private OrderStatus orderStatus = OrderStatus.ORDERED;
    private Boolean isAmountOpen;  // 금액공개여부
    private Boolean isNameOpen;   // 이름공개여부
}

이제 응답 객체와 컨트롤러 레이어는 모두 완성 되었습니다.
이제 비지니스 레이어를 통해 기능을 구현해보도록 하겠습니다.

0개의 댓글