Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
212 changes: 212 additions & 0 deletions docs/week2/01-requirements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
# 요구사항 명세서 (Requirements Specification)

## 1. 개요

### 1.1 태스크 목표 정의

#### 해결하고자 하는 문제
- 기존 대형 이커머스는 상품 위주의 탐색 경험으로, 사용자가 좋아하는 상품을 발견하고 모으는 즐거움이 부족
- 구매 시 매번 결제 정보를 입력해야 하는 번거로움으로 인한 구매 전환 장벽 존재
- 사용자의 취향과 관심사를 반영한 개인화된 쇼핑 경험 부재

#### 태스크 목표
- 좋아요 기능을 통해 사용자가 관심 있는 상품을 손쉽게 큐레이션할 수 있는 환경 제공
- 포인트 선충전 모델로 구매 전환 장벽을 낮추고 빠른 결제 경험 제공
- 사용자 행동 데이터(좋아요, 구매 패턴)를 수집하여 향후 추천/랭킹 시스템 구축 기반 마련

#### 2주차 구현 범위
본 명세서는 다음 기능의 설계 및 구현을 다룹니다:
- **상품 탐색**: 상품 목록 조회, 상품 상세 조회, 브랜드 조회
- **좋아요 관리**: 좋아요 등록/취소, 좋아요한 상품 목록 조회 (멱등성 보장)
- **주문 처리**: 주문 생성 및 결제 (재고 차감, 포인트 차감, 외부 시스템 연동)

#### 제외 범위
다음 기능은 1주차에서 구현 완료되었으며, 본 명세서에서는 다루지 않습니다:
- 회원가입 및 내 정보 조회
- 포인트 충전 및 보유 포인트 조회
- 인증/인가 (X-USER-ID 헤더 기반 식별)

### 1.2 기대 효과

- **사용자 재방문율 증가**: 좋아요 기능을 통한 관심 상품 큐레이션으로 재방문 유도
- **전환율 향상**: 포인트 선충전 모델로 구매 시 결제 단계를 최소화하여 전환 장벽 감소
- **데이터 기반 확장 가능성**: 사용자 행동 데이터를 수집하여 향후 추천/랭킹 시스템 구축 기반 마련

---

## 2. 도메인 용어집

### Products 도메인

**핵심 개념:**
- **브랜드 (Brand)**: 상품을 생산하고 제공하는 패션 브랜드 또는 제조사
- **상품 (Product)**: 구매 가능한 개별 패션 아이템. 가격, 소속 브랜드, 재고 수량 정보를 포함

**상태:**
- **판매중 (AVAILABLE)**: 재고가 있어 구매 가능한 상태
- **품절 (OUT_OF_STOCK)**: 재고가 소진되어 구매 불가능한 상태
- **단종 (DISCONTINUED)**: 더 이상 판매하지 않는 상태

### Likes 도메인

**핵심 개념:**
- **좋아요 (ProductLike)**: 사용자가 특정 상품에 대해 표시하는 관심 표현. 사용자는 각 상품에 최대 1개의 좋아요만 등록 가능

### Orders 도메인

**핵심 개념:**
- **주문 (Order)**: 사용자가 특정 상품의 구매를 요청하고 결제를 완료한 거래 단위
- **결제 (Payment)**: 주문에 대한 포인트 차감 및 결제 처리 정보

**주문 상태:**
- **접수됨 (PLACED)**: 주문이 시스템에 접수된 상태
- **결제 완료됨 (PAID)**: 결제가 완료되어 처리 대기 중인 상태

**결제 상태:**
- **준비 (READY)**: 결제가 준비된 상태
- **완료 (PAID)**: 결제가 완료된 상태

**행위:**
- **주문하다 (place)**: 사용자가 상품을 주문하는 행위
- **결제하다 (pay)**: 주문에 대한 결제를 완료하는 행위

### 공통

**핵심 개념:**
- **사용자 (User)**: 감성 이커머스 플랫폼에 가입하여 상품을 탐색하고 구매하는 개인. "구매자"와 동일한 의미로 사용
- **포인트 (Point)**: 사용자가 사전에 충전하여 보유한 가상 화폐 잔액. 상품 구매 시 결제 수단으로 사용됨

---

## 3. 유스케이스 명세

### 3.1 주요 사용자
- **구매자**: 패션 상품을 탐색하고 구매하는 일반 사용자

### 3.2 구매자의 목표

1. **관심 있는 상품 탐색 및 좋아요로 관리하기**
- 다양한 상품 둘러보기
- 마음에 드는 상품 좋아요로 저장
- 좋아요 한 상품 다시 보기

2. **상품 주문 및 결제하기**
- 원하는 상품 주문 요청
- 포인트 차감 및 재고 확보
- 주문 완료 처리

### 3.3 유스케이스 시나리오

#### 유스케이스 1: 관심 있는 상품 탐색 및 좋아요로 관리하기

**주요 시나리오:**
1. 사용자가 상품 목록 화면에 진입한다
2. 시스템은 최신 등록된 상품 목록을 조회한다 (각 상품의 좋아요 수 포함)
3. 사용자가 관심 있는 상품의 상세 정보를 조회한다 (좋아요 수 포함)
4. 사용자가 해당 상품에 좋아요를 등록한다
5. 시스템은 좋아요를 저장하고 해당 상품의 좋아요 수를 1 증가시킨다
6. 사용자가 "내가 좋아요 한 상품 목록"을 조회하여 저장한 상품들을 확인한다

**대체 시나리오 1 (브랜드별 상품 필터링):**
1. 사용자가 브랜드 정보를 조회한다
2. 사용자가 특정 브랜드를 선택하여 해당 브랜드의 상품만 필터링한다
3. 시스템은 선택된 브랜드의 상품 목록을 조회하여 반환한다
4. 해당 브랜드에 상품이 없으면 빈 목록을 표시한다

**대체 시나리오 2 (정렬 기준 변경):**
1. 사용자가 정렬 기준을 선택한다 (최신순/가격낮은순/인기순)
2. 시스템은 선택된 기준으로 상품을 정렬하여 반환한다

**대체 시나리오 3 (좋아요 중복 등록 - 멱등성):**
1. 사용자가 이미 좋아요를 등록한 상품에 다시 좋아요를 등록한다
2. 시스템은 오류 없이 성공 응답을 반환하며, 좋아요 상태는 변경되지 않는다
3. 상품의 좋아요 수는 증가하지 않는다

**대체 시나리오 4 (좋아요 취소):**
1. 사용자가 좋아요를 등록한 상품의 좋아요를 취소한다
2. 시스템은 좋아요를 제거하고 해당 상품의 좋아요 수를 1 감소시킨다
3. 사용자가 "내가 좋아요 한 상품 목록"에서 해당 상품이 제거된 것을 확인한다

**대체 시나리오 5 (좋아요 취소 중복 요청 - 멱등성):**
1. 사용자가 좋아요를 등록하지 않은 상품에 좋아요 취소를 요청한다
2. 시스템은 오류 없이 성공 응답을 반환하며, 좋아요 상태는 변경되지 않는다
3. 상품의 좋아요 수는 감소하지 않는다

**예외 시나리오 1 (존재하지 않는 상품):**
1. 사용자가 존재하지 않는 상품에 좋아요를 등록하거나 상세 조회를 시도한다
2. 시스템은 "상품을 찾을 수 없음" 오류를 반환한다

**예외 시나리오 2 (잘못된 정렬 기준):**
1. 사용자가 지원하지 않는 정렬 기준을 입력한다
2. 시스템은 "지원하지 않는 정렬 기준" 오류를 반환한다

---

#### 유스케이스 2: 상품 주문 및 결제하기

**주요 시나리오:**
1. 사용자가 원하는 상품을 선택하고 주문을 요청한다
2. 시스템은 상품 재고를 차감한다
3. 시스템은 주문을 접수 상태로 생성한다
4. 시스템은 결제를 준비 상태로 생성한다
5. 시스템은 사용자의 포인트를 차감한다
6. 시스템은 외부 PG 시스템에 결제 요청을 전송한다

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재는 포인트르 기준으로 결제를 하니 그 기준으로 유스케이스를 작성하는 것은 어떨까요?
이후 요구사항이 수정된다면 설계서도 같이 수정되어야 한다고 생각합니다!

Copy link
Collaborator Author

@toongri toongri Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@simbokyung98 과제에 외부 시스템 연동에 대한 언급이 있는데 그럼에도 제외해야할까요?ㅠ mock으로라도 적어놓으라고 하시긴했거든요. 실제 구현할건 아니지만

7. 사용자에게 주문 생성 완료 응답을 반환한다 (결제 준비 상태)

**대체 시나리오 1 (전액 포인트 결제):**
1. 사용자가 상품 주문을 요청한다
2. 시스템은 재고를 차감한다
3. 시스템은 주문을 접수 상태로 생성한다
4. 시스템은 결제를 준비 상태로 생성한다
5. 시스템은 포인트를 차감한다 (전액 결제 가능)
6. 외부 PG 호출을 스킵하고 결제를 완료 처리한다
7. 사용자에게 주문 완료 응답을 반환한다

**예외 시나리오 1 (재고 부족):**
1. 사용자가 상품 주문을 요청한다
2. 시스템이 재고 차감을 시도하지만 재고가 부족하여 실패한다
3. 시스템은 "재고 부족" 오류를 반환한다
4. 주문이 생성되지 않으며, 포인트도 차감되지 않는다

**예외 시나리오 2 (포인트 부족):**
1. 사용자가 상품 주문을 요청한다
2. 시스템이 재고를 차감한다
3. 시스템이 포인트 차감을 시도하지만 잔액이 부족하여 실패한다
4. 시스템은 트랜잭션을 롤백한다
5. 시스템은 "포인트 부족" 오류를 반환한다
6. 주문 및 결제가 생성되지 않는다

**예외 시나리오 3 (외부 PG 시스템 실패):**
1. 사용자가 상품 주문을 요청한다
2. 시스템이 재고, 포인트 차감 및 주문/결제 생성을 시도한다
3. 외부 PG 시스템에 결제 요청 전송 시 오류가 발생한다
4. 시스템은 트랜잭션을 롤백한다
5. 시스템은 "결제 요청 실패" 오류를 반환한다
6. 주문 및 결제가 생성되지 않으며, 재고와 포인트도 차감되지 않는다

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

서버개발자들과 소통하기 위한 설계서라면 예외시나리오에 대한 HTTP 상태코드도 함께 들어가며 좋을 것 같아요!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@simbokyung98 음 API 스펙은 아직 단계가 아니라서 안적긴했는데, 같이 적어놓으면 좋을까요?


---

## 4. 기술 요구사항

### 4.1 데이터 정합성

**주문 처리 (재고/포인트 차감)**
- 강한 일관성 (Strong Consistency) 필요
- 재고 차감, 포인트 차감, 주문 생성, 결제 생성이 모두 성공하거나 모두 실패해야 함
- 트랜잭션 롤백을 통한 원자성 보장

**좋아요 카운트**
- 최종 일관성 (Eventual Consistency) 허용
- 좋아요 수는 대략적인 인기도 지표로, 실시간 정확성 불필요
- 사용자의 좋아요 등록/취소 상태는 즉시 반영되어야 함

### 4.2 에러 처리

**주문 생성 실패**
- 재고 부족: 재고 부족 정보 제공
- 포인트 부족: 포인트 잔액 부족 정보 제공
- 외부 PG 시스템 실패: 결제 요청 실패 정보 전달 (전체 롤백)

**좋아요 처리**
- 존재하지 않는 상품: "상품을 찾을 수 없음" 명확히 구분
- 멱등성 보장: 중복 요청에도 사용자에게 성공 응답 전달
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

멱등성이 보장된 API 는 어떤걸 만족해야 한다고 생각하시나요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@djawnstj 아 저는 멱등성을 보장하는 API는 같은 요청에 대해 동일한 결과를 낳아야한다고 생각했습니다. 그래서 좋아요 요청을 함에 있어서 언제 어디서 요청을 하든 항상 성공 응답과 좋아요가 db에 기록되는 결과를 낳아야한다고 생각했던 것 같습니다.

71 changes: 71 additions & 0 deletions docs/week2/02-sequence-diagrams.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# 시퀀스 다이어그램 (Sequence Diagrams)

본 문서는 감성 이커머스의 핵심 유스케이스에 대한 객체 간 상호작용을 시각화합니다.

---

## 1. 상품 목록 조회

사용자가 상품 목록을 조회하는 시나리오입니다. 각 상품의 좋아요 수를 함께 조회하여 인기도를 표시합니다.

![img](https://i.imgur.com/Og1yTzK.png)

**주요 흐름:**

1. 사용자가 페이징, 정렬 기준과 함께 상품 목록 조회를 요청
2. Facade가 정렬 기준에 따라 상품 목록을 조회 (Slice 반환)
3. 조회된 상품 ID 목록으로 좋아요 수를 일괄 조회
4. Facade에서 상품 정보와 좋아요 수를 조합하여 ProductInfo 리스트 생성

**고려사항:**

- ProductLikeCount를 일괄 조회하여 N+1 문제 방지
- 정렬 기준: latest(최신순), price_asc(가격낮은순), likes_desc(인기순)
Comment on lines +22 to +23
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

지금 다이어그램에서는 ProductRepository 조회 후 ProductLikeRepository 를 조회하는데, 인기순 상품 목록을 조회하고자 할때도 문제 없을까요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@djawnstj 아 인기순 흐름에 대해선 다른 flow을 작성해둬야할 것 같습니다. 그리고 인덱스도 추가해놔야겠네요 감사합니다. 놓쳤습니다


---

## 2. 상품 좋아요 등록

사용자가 상품에 좋아요를 등록하는 시나리오입니다. 멱등성을 보장하여 중복 등록 시에도 오류 없이 처리됩니다.

![img_1.png](https://i.imgur.com/ttJAMA7.png)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상품과 좋아요 테이블 두곳에서 좋아요를 관리하면 어떤 점이 좋을까요?

Copy link
Collaborator Author

@toongri toongri Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@simbokyung98 아 두 곳은 서로 다른 역할을 갖고 있습니다.

  1. ProductLike은 실제로 유저와 상품 사이의 좋아요를 기록하는 테이블입니다. 이 테이블을 기준으로 각 상품당 유저의 좋아요 여부를 확인하고, 추후에 등장할 내가 좋아요 한 상품 목록 조회에 사용됩니다.
  2. ProductLikeCount은 상품당 좋아요 갯수를 비정규화한 테이블입니다. 상품 리스트 조회 시에 count 집계에 대한 리소스 소모가 있을 것으로 예상되는데, 이커머스 특성상 조회의 비중이 높기 때문에 조회 시의 부하를 좀 줄이고 미리 집계하는 방향으로 갔습니다.


**주요 흐름:**

1. 사용자가 특정 상품에 좋아요 등록 요청
2. Facade가 기존 좋아요 존재 여부 확인
3. 이미 존재하면 아무 작업 없이 성공 응답 (멱등성 보장)
4. 존재하지 않으면 ProductLike 생성 및 저장
5. ProductLikeCountRepository의 increment()로 좋아요 수 증가
6. 성공 응답

**고려사항:**

- 멱등성 보장: 중복 등록 시도에도 오류 없이 성공 응답
- 좋아요 수 증가는 Repository 레벨에서 원자적으로 처리

---

## 3. 주문 생성 및 결제

사용자가 상품을 주문하고 결제하는 시나리오입니다. 전액 포인트 결제 여부에 따라 외부 PG 호출 여부가 결정됩니다.

![img_2.png](https://i.imgur.com/EM0MjPP.png)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

다이어그램에서 주요 흐름의 순차에 따라 lifeline 을 위치해주신 것 같은데, 저는 개인적으로 비슷한 계층끼리 모여있는게 보기 좋은 것 같더라고요.
그리고 너무 많은 정보를 한번에 담으려고 하지 않았나 생각도 들어요. 시퀀스 다이어그램에는 모든 구현이 다 담길 필요는 없다고 생각합니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@djawnstj 아 이 부분 조금 주의하겠습니다. 과제 내용에 controller, service 등등의 layer 흐름을 표현하라는 문구에 매몰되어서 모든 상세 스펙을 적어야 리뷰가 쉽다고 판단했던 것 같습니다. 같은 백엔드 개발자들과 구현 리뷰를 한다고 했을 때 어떤 수준으로 문서화해주는게 좋았을까요?ㅠ


**주요 흐름:**

1. 재고를 비관적 락으로 조회하여 차감 (StockManager)
2. 주문을 접수 상태(PLACED)로 생성 (Order.place)
3. 포인트를 차감하고 이력 기록 (PointAccountManager)
4. **결제 처리 (PaymentManager.pay)**

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기서 PG결제를 사용한다고 되어있네요!

이커머스 요구사항에 보면 "💡 이 시스템은 실제 결제(PG) 대신, 사전 충전된 포인트로 상품을 결제합니다. " 라는 조건이 있습니다.

개인적으로 함께 일하는 입장에서 보았을때 같이 정한 요구사항과 설계문서가 다를경우 한번 더 커뮤니케이션을 해야하기 때문에 비용이 더 추가된다고 생각합니다. 확장성에 대한 고려는 기본 설계 작성 후에 이루이지는게 더 좋지 않을까요?

Copy link
Collaborator Author

@toongri toongri Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@simbokyung98 아 근데 이부분은 실제 수업은 또 내용이 다릅니다.

과제 설계범위도 이렇게 적혀있기도 해서 설계 범위에 외부 시스템 연동을 빼놓을 수가 없었습니다ㅠ

  • 설계 범위
    • 상품 목록 / 상품 상세 / 브랜드 조회
    • 상품 좋아요 등록/취소 (멱등 동작)
    • 주문 생성 및 결제 흐름 (재고 차감, 포인트 차감, 외부 시스템 연동)

- Payment 생성 (READY 상태)
- 결제 처리 필요 여부 판단 (Payment.needsExternalPayment())
- 외부 결제 필요: PG 시스템에 결제 요청 전송
- 전액 포인트: 즉시 결제 완료 처리 (PAID 상태)
5. 성공 시 트랜잭션 커밋, 실패 시 자동 롤백

**고려사항:**

- 재고 차감은 비관적 락을 통한 동시성 제어
- 전액 포인트 결제 여부는 Payment 도메인 객체가 판단 (actualPaymentAmount == 0)
- 재고 부족, 포인트 부족, PG 실패 시 트랜잭션 롤백으로 일관성 보장
58 changes: 58 additions & 0 deletions docs/week2/03-class-diagram.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# 클래스 다이어그램 (Class Diagram)

본 문서는 감성 이커머스의 도메인 모델 구조를 시각화합니다.

---

## 1. Products 도메인

![img_3.png](https://i.imgur.com/Xv2rXLF.png)

**주요 구조:**

- **Brand**: 브랜드 정보 엔티티
- **Product**: 상품 엔티티. 상태 관리 행위(품절/재판매/단종) 포함
- **Stock**: 재고 엔티티. 차감/증가/소진 확인 행위 포함
- **StockManager**: 재고 차감 시 Stock과 Product를 함께 조율하는 도메인 서비스
- **Money**: 금액 값 객체. 금액 계산 로직 캡슐화
- **ProductStatus**: 상품 상태 열거형

**설계 의도:**

- Product와 Stock은 각각 독립적인 애그리게이트 루트
- StockManager가 두 애그리게이트를 조율하여 비즈니스 로직 수행

---

## 2. Likes 도메인

![img_6.png](https://i.imgur.com/5h67fSJ.png)

**주요 구조:**

- **ProductLike**: 사용자의 상품 좋아요 기록 엔티티

**설계 의도:**

- 단순한 관계 엔티티로 별도의 비즈니스 로직 없음

---

## 3. Orders 도메인

![img_5.png](https://i.imgur.com/0ENqus2.png)

**주요 구조:**

- **Order**: 주문 엔티티. 주문 생성(place) 및 결제 완료(pay) 행위 포함
- **OrderItem**: 주문 항목 엔티티. 주문 시점의 상품 정보 스냅샷
- **Payment**: 결제 엔티티. 결제 생성, 외부 결제 필요 여부 판단, 완료 처리 행위 포함
- **PaymentManager**: 결제 생성 및 PG 호출 조율을 담당하는 도메인 서비스
- **OrderStatus**: 주문 상태 열거형
- **PaymentStatus**: 결제 상태 열거형

**설계 의도:**

- Order와 OrderItem은 하나의 애그리게이트 (강한 일관성)
- Payment는 독립적인 애그리게이트
- PaymentManager가 결제 프로세스 전체를 조율
Loading