생각하며 기획하는 커머스 백엔드

강의 활용

개념도를 그리는 툴: draw.io

생각하는 방법

회사의 상황을 꼭 생각하고 비즈니스를 이해하고 소프트웨어를 작성 하도록 노력한다.

요구사항 느끼기’를 다 본 후 잠시 강의를 멈추고 내 생각을 정리해보기

’코드 느끼기’ 전에 나는 이렇게 구현할 것 같다 라고 생각해보기 OR 직접 구현해보기 (사실 이게 제일 좋다고 생각합니다ㅎㅎ.. 진짜 코드아니더라도, 상세한 구현 없이 껍데기만 있는 sudo 코드라도 작성해보는 느낌이요!)

’개념 정리’ 를 통해 ‘요구사항 느끼기’와 ‘코드 느끼기’ 를 한번더 생각해보기

읽어볼만한 커뮤니티 내용


부가 기능을 이벤트 핸들러로 분리하는 기준

비즈니스와 비즈니스 로직의 응집도를 우선적으로 고려한다. 포인트 지급 같은 부가 기능을 별도 이벤트로 발행하면 응집도가 떨어진다.

비즈니스적으로 리뷰 작성포인트 지급은 개념적으로 가까운 관계에 속한다. (논리적으로 “포인트는 글로벌하게 쓰이니 이벤트로 처리해도 되는 것 아닌가?”라는 관점도 틀리지는 않다.)

이벤트 기반 처리를 오용하면 응집이 깨진다. 그래서 일반적으로 비즈니스적 맥락이 완전히 분리될 때를 기준으로 이벤트 기반으로 처리한다. (예: 이메일 발송, 알림톡 발송, callback 전송 등 완전히 다른 비즈니스/기능적 맥락)

약간 다른 관점으로, 동시성 관점에서 후처리나 비신뢰 처리가 되어도 된다면 @Async 를 사용하기도 한다.

강의 내용 정리

상품 목록

📌

기획 내용에 대한 질문 없이 API 개발 후 협업 직군에게 스펙 전달 하는 것은 최악이다

이 요구사항을 정리 해보자면?

📝

명확히 기재 해야 할 요구사항은 무엇인가?

  • 카테고리 상품은 1대1 매핑 구조인가?
  • 상품 목록을 표시할 때 어떤 순서대로 보여주어야 하는가?
    • 상품 별 정렬 기준
      • 만약, 가장 많이 팔린 순서라고 한다면 판매 갯수를 Product 테이블에 비정규화 하여 저장 할 것인가?
    • 페이지 처리 기준

코드 느끼기

개념도

상품 상세

이 요구사항을 정리 해보자면?

📝

명확히 기재 해야 할 요구사항은 무엇인가?

  • 상품 상세는 오로지 글로만 되어있는가? -> 쿠팡처럼 이미지가 렌더링 되지는 않는가?

코드 느끼기

개념도

리뷰

이 요구사항을 정리 해보자면?

📝

명확히 기재 해야 할 요구사항은 무엇인가?

  • 상품 1개당 1개의 리뷰를 작성하는가?
  • 리뷰는 수정 또는 삭제가 가능하는가?
  • 리뷰는 글만 존재하거나, 사진 과 글이 같이 존재하는가?
  • 제품을 구매한 후 리뷰를 남긴 다음 환불한다면 리뷰는 어떻게 되는가?
  • 작성자가 회원을 탈퇴하는 경우 리뷰도 삭제 되는가?

코드 느끼기

개념도

Q&A

이 요구사항을 정리 해보자면?

📝

명확히 기재 해야 할 요구사항은 무엇인가?

  • 상품을 구매하지 않은 사용자도 질문을 남길 수 있는가?
  • 질문에 대한 답변을 여러 번 달면 어떻게 할 것인가?
  • 질문에 대한 공개 범위를 지정할 것인가?

코드 느끼기

개념도

찜하기

이 요구사항을 정리 해보자면?

📝

명확히 기재 해야 할 요구사항은 무엇인가?

  • 찜 한 제품이 판매자에 의해 삭제 되었다면 어떻게 처리할 것인가?

코드 느끼기

개념도

포인트

이 요구사항을 정리 해보자면?

📝

명확히 기재 해야 할 요구사항은 무엇인가?

  • 리뷰를 작성하고 포인트가 적립 된다면, 리뷰 작성 후 삭제하면 포인트는 어떻게 되는건지? -> 어뷰징 가능
  • 포인트 사용 가능한 유효기간이 있는건지?

코드 느끼기

쿠폰

다운로드 받을 수 있는 쿠폰은 무엇인지? 부터 요구사항을 다시 정의할 필요가 있다.

이 요구사항을 정리 해보자면?

📝

명확히 기재 해야 할 요구사항은 무엇인가?

  • 다운로드 받은 쿠폰의 유효기간을 표기 해줘야 하는가?
  • 기 만료된 쿠폰도 노출 해야 하는가?

코드 느끼기

개념도

장바구니

주문

사용자가 결제하기 버튼을 누르면 결제를 하기 위한 페이지를 보여준다. 페이지에서 결제 하고자 하는 상품을 결제 시 쿠폰과 포인트를 사용할 수 있고

이 요구사항을 정리 해보자면?

📝

명확히 기재 해야 할 요구사항은 무엇인가?

  • 포인트 사용 제한이 있는지?
  • 쿠폰은 여러개를 한 번에 사용할 수 있는지?
📝

기술적 고민은 무엇인가?

  • 주문에 대한 데이터는 언제 생성할 것인가? 결제 전 / 결제 시
  • 재고 변경 후 유효성 검증은 결제 후 검증할 것인가? 재고 변경 시 할 것인가?

코드 느끼기

개념도

개념도를 그릴 때는 코드와 1대1로 매칭 될 필요 없이, 우리 현실 세계에서 고민할 법한 내용들을 기준으로 연관관계를 그려내어 단순함을 만들어내도록 유도하는 것이다.

📝

내가 생각하는 개념도 카트는 상품을 담기 위한 보관함일 뿐, 결제는 상품에 의해 이뤄진다. 그렇다면 카트는 도구일 뿐 더 중요하게 여겨질 것은 “상품” 이고 “상품”의 바코드를 찍어 총 결제 금액을 계산하기 때문에, 현재 개념도에 나와있듯 카트보다 상품을 의존하는 것이 올바르다.

결제

코드 느끼기

서비스 로직에서 비즈니스 코드를 작성하는 것 보다 컴포터는화 하여 호출하는 것을 더 선호한다.

PG 사 승인 외부 API 를 거치고 난 이후는 사용자가 실제 잔고에서 돈이 빠져 나갔기 때문에 예외가 던져지는 일이 없어야한다.

개념도

취소

코드 느끼기

PaymentEntity 에서 status 를 관리할 때, READY, SUCCESS 단 두가지의 상태만 갖고 있는다. 취소는 PaymentEntity 의 상태를 업데이트 하지 않고 CancelEntity 에서 관리한다.

이 구조의 장점은 결제와 취소가 분리 되어 있어, DB 테이블에서 각 책임에 맞게 데이터를 “삽입” 만 하게 된다.

데이터를 수정하게 되면, 과거 데이터를 불러 왔을 때도 수정일시를 확인해야 하는 번거로움이 있지만, 삽입된 데이터만 있다면 삽입일시 기준으로 데이터를 조회할 수 있다.

또한, 이미 결제한 건이 30일이 지나서 취소가 되었다고 한다면 이 데이터는 30일 전 데이터를 조회해서 취소 건으로 바꿔야한다. 그럴 경우, Payment 테이블에 updated_at 을 지속적으로 모니터링 해야 하는 단점이 존재한다.

만약 Cacnel 테이블에서 관리 했더라면 30일 후에 취소한 건이 가장 최근에 쌓이게 되고, 이 취소 데이터를 기준으로 정산을 하거나 유저에게 노출을 시키거나 할 수 있게 되는 것이다.

그리고, 정산을 하기 위해서 이 테이블 분리에 장점이 있고, 그 장점이 무엇인지는 정산을 하면서 다룬다.

정산

요구사항 느끼기

이 요구사항을 정리 해보자면?

📝

명확히 기재 해야 할 요구사항은 무엇인가?

  • 어떤 데이터를 기준으로 정산을 할 것인가?
  • 정산 금액에 대한 지급 대행은 언제 할 것인가?
📝

기술적 고민은 무엇인가?

  • 주문에 대한 데이터는 언제 생성할 것인가? 결제 전 / 결제 시
  • 재고 변경 후 유효성 검증은 결제 후 검증할 것인가? 재고 변경 시 할 것인가?

코드 느끼기

정산 원천 데이터를 다룰 때, 정산 가공 데이터를 만들기 위한 중간 과정을 한 번 더 두면 추후에 부분 취소를 하거나 다른 요구사항이 생겼을 때 정산 데이터는 깔끔하게 유지하며 요구사항을 반영할 수 있다.

정산 배치를 다룰 때 크론 주기의 시간 기준으로 배치를 수행 시키게 되면, 추후에 데이터가 많아졌을 때 의존하고 있는 크론 잡이 다음 크론잡을 실행 하는 시간이 될 때 까지도 완료되지 않을 경우 정상적으로 동작하지 않을 수 있다.

전체 개념도

1안: 중요한 개념 위주의 개념도를 그리는데 유리

2안: 참조 관계를 가독성 있게 표현하기 위한 개념도

3안: 복잡한 시스템의 개념도를 그리는 방법