[volume-2] 이커머스 설계 문서 작성#46
Conversation
개요새로운 GitHub Actions 워크플로우를 추가하고, 2주차 요구사항, 시퀀스 다이어그램, 클래스 다이어그램, ERD 등 시스템 설계 및 API 명세에 관한 상세한 문서화를 제공합니다. 브랜드, 상품, 좋아요, 주문 기능의 사용자 스토리, 시스템 흐름, 에러 처리, 검증 사항을 포함합니다. 변경사항
예상 코드 리뷰 노력🎯 2 (Simple) | ⏱️ ~12 분
시
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (7)
docs/week2/03-class-diagram.md (2)
12-19: Point 엔티티의 포인트 잔액 필드 누락Point 클래스에 포인트 잔액을 추적할 필드가 부족해 보입니다. 현재
amount필드만 있는데, 이것이 충전된 포인트인지 현재 잔액인지 명확하지 않습니다. 요구사항(01-requirements.md 라인 165-167)에서 포인트 확인 및 차감이 언급되므로, Point 엔티티는 사용자의 현재 잔액을 명확히 추적해야 합니다.제안:
amount필드를balance또는currentBalance등으로 명확히 이름 붙이거나- 포인트 변동 내역을 기록하는 별도 엔티티(예: PointTransaction) 고려
26-36: Product 클래스에 좋아요 수 속성 누락Product 클래스에
likeCount또는totalLikes같은 필드가 없습니다. 요구사항(01-requirements.md 라인 24-26, 44, 54)과 시퀀스 다이어그램(02-sequence-diagrams.md 라인 47-48, 77-78)에서 상품 목록 및 상세 조회 시 좋아요 수를 포함하여 반환한다고 명시되므로, Product에 이 정보가 필요합니다.제안:
클래스 다이어그램의 Product 클래스에likeCount필드를 추가하세요:-Long likeCountdocs/week2/01-requirements.md (3)
103-114: 좋아요 처리 방식 명확화 필요요구사항 명세에서 좋아요 처리가 다음과 같이 기술되어 있습니다:
- 라인 108: "Like 엔티티 존재 여부 조회"
- 라인 110-111: "Like 엔티티 생성"
- 라인 113: "Like 엔티티 삭제"
이는 구현 방식을 특정하지 않지만, PR 저자의 검토 포인트에서 제기된 질문과 연결됩니다: 플래그 토글 방식(UPDATE likedYn) vs 삽입/삭제 방식 중 어느 것이 더 나은가?
현재 설계의 불일치:
- 시퀀스 다이어그램(02-sequence-diagrams.md 라인 105, 123)은
update likedYn = 'Y'/'N'으로 명시 → 플래그 토글- 클래스 다이어그램(03-class-diagram.md 라인 38-42)의 Like는
likedYn필드 없음 → 삽입/삭제 방식권장 사항:
두 가지 접근 방식의 장단점:
항목 삽입/삭제 방식 플래그 토글 방식 저장 공간 Like 레코드만 생성 Like 레코드 영구 보존 조회 성능 INNER JOIN (liked만) LEFT JOIN + 조건 필터링 감시 가능성 생성/삭제 기록 필요 수정 시간 자동 추적 트랜잭션 복잡도 낮음 낮음 제안:
아키텍처 의사결정 문서(ADR)를 통해 선택 기준을 명시하고, 모든 설계 문서(클래스 다이어그램, 시퀀스, 요구사항)를 일관되게 수정하세요.
68-78: 정렬 필드 기본값 처리 명확화라인 64에서 기본 정렬(
latest: createdAt desc)이 명시되어 있지만, 라인 77의 체크리스트 항목 7에서 "잘못된 정렬 필드에 대한 기본 정렬이 적용되는가?"라고 묻고 있습니다.불명확한 부분:
- 기본값 적용 시점: 정렬 파라미터가 완전히 없는 경우 vs 잘못된 정렬 필드인 경우
- 시퀀스 다이어그램(02-sequence-diagrams.md 라인 35-40)에서도 이 로직이 "default 정렬 적용" vs "에러 반환"로 분기됨
제안:
요구사항에 다음을 명시하면 더 명확할 것 같습니다:
- 정렬 파라미터 생략 시: 기본값 적용 (latest, createdAt desc)
- 지원하지 않는 정렬 필드 요청 시: 400 Bad Request 반환 (또는 기본값 적용)
183-190: 주문 실패 시 롤백 시나리오 명시 필요라인 186-187의 체크리스트에서 "주문 실패 시, 모든 재고와 포인트는 롤백되는지?"를 확인 항목으로 제시했습니다.
현재 요구사항 명세 부족:
- 시스템 동작 부분(라인 159-171)에는 낙관적 흐름만 명시
- 재고 차감 또는 포인트 차감 실패 시 어떤 일이 발생하는지 명시되지 않음
- 트랜잭션 경계(Transaction boundary)가 명확하지 않음
제안:
예외 처리 섹션(라인 173-181)에 다음을 추가하세요:5. 주문 처리 중 예상치 못한 오류 (재고 차감 실패, 포인트 차감 실패 등) -> 500 - 모든 변경사항이 자동 롤백됨docs/week2/02-sequence-diagrams.md (2)
32-54: 상품 목록 조회 — 정렬 파라미터 실패 처리 흐름 명확화라인 35-40의 정렬 조건 검증 흐름:
alt 정렬 조건 X alt default 정렬 적용 ... else 에러 반환 ProductController-->>User: 400 Bad Request end end이 흐름이 약간 혼동스럽습니다.
불명확한 부분:
- "정렬 조건 X"는 무엇을 의미하는가? (파라미터 생략 vs 잘못된 파라미터?)
- 두 번째
alt분기의 "default 정렬 적용" vs "에러 반환" 선택 기준이 명시되지 않음개선 제안:
alt sort 파라미터 생략 ProductController->>ProductFacade: getProductList(brandId, defaultPageable) else sort 파라미터 유효 ProductController->>ProductFacade: getProductList(brandId, pageable) else sort 파라미터 유효하지 않음 ProductController-->>User: 400 Bad Request end
86-128: 좋아요 삭제 로직 — "업데이트"와 "삭제" 의미 불일치라인 115-127의 좋아요 취소(unlike) 흐름:
User->>LikeController: DELETE /api/v1/likes/products/{productId} ... LikeService->>LikeRepository: update likedYn = 'N'HTTP 메서드는
DELETE이지만, 데이터베이스 작업은UPDATE likedYn = 'N'입니다.문제:
- REST 관례상 DELETE는 리소스 삭제를 의미합니다
- 실제로는 레코드를 유지하면서 플래그만 변경합니다
- 이는 클라이언트/서버 간 계약(contract)과 구현 사이의 불일치입니다
옵션:
- 플래그 토글 유지: HTTP DELETE를 사용하되, 응답에 "좋아요 상태: 비활성화됨" 명시
- 실제 삭제로 변경: Repository에서
DELETE FROM like WHERE user_id = ? AND product_id = ?실행첫 번째 옵션을 선택한다면, 요구사항과 시퀀스 다이어그램에서 플래그 토글 방식임을 명확히 해야 합니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
docs/img/erd.pngis excluded by!**/*.png
📒 Files selected for processing (5)
.github/workflows/main.yml(1 hunks)docs/week2/01-requirements.md(1 hunks)docs/week2/02-sequence-diagrams.md(1 hunks)docs/week2/03-class-diagram.md(1 hunks)docs/week2/04-erd.md(1 hunks)
🔇 Additional comments (2)
.github/workflows/main.yml (1)
1-13: ✅ GitHub Actions 워크플로우 설정 양호PR Agent 워크플로우 설정이 적절합니다. 비밀 관리가 제대로 되어 있고 외부 의존성이 명확합니다.
참고 사항:
- 리포지토리의 Settings → Secrets에
OPENAI_KEY와G_TOKEN이 등록되어 있는지 확인하세요.G_TOKEN이라는 이름은 관례적이지 않으므로, 팀 내 비밀 관리 가이드라인과 일치하는지 확인하세요.docs/week2/04-erd.md (1)
3-3: 이미지 경로 유효함 - 검증 완료
/docs/img/erd.png파일이 저장소에 존재하며 경로가 올바르게 설정되어 있습니다. 마크다운에서 사용된 절대 경로 형식(/docs/img/erd.png)은 GitHub 저장소 기준으로 정상적으로 렌더링됩니다.
| LikeController->>LikeFacade: like(userId, productId) | ||
| LikeFacade->>LikeService: like(userId, productId) | ||
| LikeService->>LikeRepository: update likedYn = 'Y' | ||
| alt updatedRow == 0 | ||
| LikeService->>LikeRepository: save(userId, productId, likedYn='Y') | ||
| end | ||
| LikeFacade->>ProductService: incrementLikes(productId) | ||
| ProductService->>LikeFacade: totalLikes | ||
| LikeFacade-->LikeController: { likedYn: Y, totalLikes } | ||
| LikeController-->>User: 200 OK + { likedYn: Y, totalLikes } | ||
|
|
||
| %% 좋아요 삭제 |
There was a problem hiding this comment.
🧩 Analysis chain
좋아요 업서트(Upsert) 로직 설계 — 클래스 다이어그램과 불일치
라인 105-108의 좋아요 업서트 로직이 다음을 보여줍니다:
LikeService->>LikeRepository: update likedYn = 'Y'
alt updatedRow == 0
LikeService->>LikeRepository: save(userId, productId, likedYn='Y')
end
이는 플래그 토글 방식(Like 레코드 유지, likedYn 플래그 수정)을 명시합니다. 하지만 클래스 다이어그램(03-class-diagram.md 라인 38-42)의 Like 엔티티에는 likedYn 필드가 없습니다.
문제:
- 시퀀스와 클래스 다이어그램 사이의 설계 불일치
- 삭제 로직(라인 121-123)도 마찬가지로
update likedYn = 'N'으로 표현되어 있는데, 이는 "삭제"가 아니라 "비활성화"를 의미합니다
필요한 조정:
이 PR의 검토 포인트를 명확히 해야 합니다:
- 옵션 A: 플래그 토글 방식 → 클래스 다이어그램에
likedYn필드 추가 - 옵션 B: 삽입/삭제 방식 → 시퀀스 다이어그램의 UPDATE 로직을 DELETE/INSERT로 변경
``
🏁 Script executed:
#!/bin/bash
# Check sequence diagram file around lines 103-114
echo "=== Sequence Diagram (lines 103-114) ==="
sed -n '103,114p' docs/week2/02-sequence-diagrams.md
echo ""
echo "=== Class Diagram (lines 38-42) ==="
# Check class diagram file around lines 38-42
sed -n '38,42p' docs/week2/03-class-diagram.md
echo ""
echo "=== Full Like entity in class diagram (search context) ==="
# Search for Like entity definition in class diagram
grep -n -A 10 "class Like" docs/week2/03-class-diagram.md || grep -n -A 10 "Like {" docs/week2/03-class-diagram.mdLength of output: 974
``
🏁 Script executed:
#!/bin/bash
# Check the deletion flow mentioned in the comment (lines 121-128)
echo "=== Sequence Diagram - Like Deletion Flow (lines 121-128) ==="
sed -n '121,128p' docs/week2/02-sequence-diagrams.mdLength of output: 463
시퀀스 다이어그램과 클래스 다이어그램 간의 설계 불일치 — 좋아요 엔티티 필드 정의
검증 결과, 설계 불일치가 확인되었습니다.
문제:
- 시퀀스 다이어그램(라인 103-114, 121-128)은 좋아요/삭제 로직에서
likedYn플래그를 명시적으로 사용합니다:update likedYn = 'Y'/update likedYn = 'N' - 클래스 다이어그램(라인 38-42)의 Like 엔티티는
likedYn필드가 없고, id, user, product만 정의합니다. - 두 다이어그램이 서로 다른 Like 엔티티 설계를 가정합니다.
필요한 조정:
다음 중 하나를 선택하여 일관성을 맞추세요:
- 클래스 다이어그램 수정: Like 엔티티에
-String likedYn필드 추가 - 시퀀스 다이어그램 수정: Like 업서트 로직을 INSERT/DELETE 패턴으로 변경 (UPDATE 대신)
🤖 Prompt for AI Agents
docs/week2/02-sequence-diagrams.md lines 103-114 and related class diagram lines
~38-42: the sequence diagram uses a likedYn flag (update likedYn = 'Y'/'N') but
the Like entity in the class diagram lacks that field, so pick one consistency
approach and apply it: either add a String likedYn field to the Like entity in
the class diagram (update the class diagram lines to include "- likedYn: String"
and keep the sequence diagram as-is), or change the sequence diagram to use
INSERT/DELETE semantics instead of UPDATE (replace the update likedYn lines with
an attempt to insert and, on conflict, delete or insert logic as appropriate) so
both diagrams reflect the same model.
| PointService-->>OrderFacade: 409 Conflict | ||
| else 포인트 보유 O | ||
| OrderFacade->>OrderService: createOrder(userId, orderRequest, point, stocks) | ||
|
|
||
| OrderService->>Order: orderProcess() | ||
|
|
||
| activate Order | ||
| Order->>Stock: stockDecrease() | ||
| Stock-->>Order: ok | ||
| Order->>Point: pointUse() | ||
| _ Point-->>Order: ok | ||
| Order-->>OrderService: orderResult | ||
| deactivate Order | ||
|
|
||
| OrderFacade->>OMS(주문 정보 외부 시스템): sendOrderInfo(order) | ||
| alt OMS(주문 정보 외부 시스템) X | ||
| OMS(주문 정보 외부 시스템)-->>OrderService: 500 | ||
| else OMS(주문 정보 외부 시스템) O | ||
| OMS(주문 정보 외부 시스템)-->>OrderService: 200 OK | ||
| end |
There was a problem hiding this comment.
주문 생성 시 외부 시스템(OMS) 통지 실패 처리 — 트랜잭션 무결성 우려
라인 173-178에서 OMS 통지 결과를 처리합니다:
OrderFacade->>OMS(주문 정보 외부 시스템): sendOrderInfo(order)
alt OMS(주문 정보 외부 시스템) X
OMS(주문 정보 외부 시스템)-->>OrderService: 500
else OMS(주문 정보 외부 시스템) O
OMS(주문 정보 외부 시스템)-->>OrderService: 200 OK
end
문제:
- OMS 통지가 동기 방식으로 주문 생성과 같은 트랜잭션 내에 있어 보입니다 (라인 161-178 전체가 OrderService 호출 범위)
- OMS 실패(500) 시 전체 주문이 롤백될 수 있으므로, 재고 및 포인트가 해제됩니다
- 이는 고객이 결제를 했지만 주문이 확인되지 않는 상황을 초래할 수 있습니다
권장 개선:
- 비동기 처리: OMS 통지를 별도 태스크(메시지 큐, 이벤트 등)로 분리
- 재시도 로직: OMS 실패 시 재시도 메커니즘 추가
- 명확한 상태 관리: 주문 상태를 "생성됨" → "OMS 통지 중" → "완료됨"으로 구분
🤖 Prompt for AI Agents
docs/week2/02-sequence-diagrams.md lines 159-178: 현재 OMS 통지가 주문 생성 트랜잭션 안에 동기
호출로 그려져 있어 실패 시 전체 주문이 롤백될 우려가 있으니 다이어그램을 수정해 OMS 통시을 비동기화하고 재시도/상태 관리를 명시하십시오;
구체적으로 sendOrderInfo 호출을 OrderService 트랜잭션 바깥으로 이동하고 메시지 큐나 이벤트(예: OrderService
->> MQ: publishOrderEvent / MQ ->> OMS: deliverOrderInfo)로 대체해 비동기 흐름을 표현하고, OMS
전송 실패 시 재시도 또는 DLQ(또는 재시도 상태)를 표시하며 주문 상태 전이를 "CREATED" -> "NOTIFYING" ->
"NOTIFIED/FAILED" 같은 상태로 추가해 트랜잭션 무결성을 보장하는 흐름으로 바꾸십시오.
| class Like { | ||
| -Long id | ||
| -User user | ||
| -Product product | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
Like 엔티티 설계 불일치 — 요구사항과 시퀀스 다이어그램 간 모순
클래스 다이어그램의 Like 엔티티가 likedYn 필드를 포함하지 않지만, 시퀀스 다이어그램(라인 105, 123)에서는 update likedYn = 'Y' / update likedYn = 'N' 작업을 명시합니다. 이는 설계 의도가 명확하지 않음을 의미합니다.
질문:
- Like 처리 전략이 플래그 토글 방식(UPDATE likedYn)인지, 아니면 레코드 삽입/삭제 방식인지 확인이 필요합니다.
- 플래그 방식이면: Like 클래스에
likedYn필드를 추가하고, 시퀀스 다이어그램도 명확히 동기화해야 합니다. - 삽입/삭제 방식이면: 시퀀스 다이어그램의 "update likedYn" 표현을 "delete" 또는 "insert"로 수정해야 합니다.
또한 Product 클래스에 좋아요 총 수를 나타내는 필드(예: likeCount)가 명시되어야 합니다.
[/run_scripts]
🏁 Script executed:
#!/bin/bash
# Read the full class diagram documentation file
cat docs/week2/03-class-diagram.mdLength of output: 1217
🏁 Script executed:
#!/bin/bash
# Search for likedYn references in the documentation
rg -n 'likedYn|likeCount|Like|Product' docs/week2/03-class-diagram.md -C 2Length of output: 722
🏁 Script executed:
#!/bin/bash
# Search for sequence diagram sections around mentioned lines
sed -n '90,130p' docs/week2/03-class-diagram.mdLength of output: 0
[/run_scripts]
🏁 Script executed:
#!/bin/bash
# List all files in week2 directory
fd . docs/week2/ -type fLength of output: 170
🏁 Script executed:
#!/bin/bash
# Search for likedYn in all week2 documentation files
rg 'likedYn' docs/week2/Length of output: 1035
🏁 Script executed:
#!/bin/bash
# Search for sequence diagram or update operations in all week2 files
rg -n 'update.*likedYn|sequenceDiagram' docs/week2/ -C 2Length of output: 2821
Like 엔티티 설계 불일치 — 클래스 다이어그램 불완전
Like 엔티티가 클래스 다이어그램(라인 38-42)에서 id, user, product 필드만 정의되어 있으나, 시퀀스 다이어그램(docs/week2/02-sequence-diagrams.md 라인 105, 123)에서는 update likedYn = 'Y' / update likedYn = 'N' 작업을 명시합니다. 이는 실제 설계에 포함된 필드가 다이어그램에 누락된 상태입니다.
필수 수정:
- Like 클래스에
likedYn필드(String또는Boolean타입)를 추가해야 합니다. - Product 클래스에
likeCount또는totalLikes필드를 명시적으로 추가하여increaseLikes()/decreaseLikes()메서드와의 연계를 명확히 해야 합니다.
docs/week2/03-class-diagram.md의 Like 및 Product 클래스 정의를 업데이트하세요.
🤖 Prompt for AI Agents
In docs/week2/03-class-diagram.md around lines 38 to 42, the Like class is
missing the likedYn field referenced by the sequence diagrams and the Product
class lacks an explicit like count field; update the Like class to include a
likedYn attribute (Boolean or String) and update the Product class to include a
likeCount or totalLikes attribute so the increaseLikes()/decreaseLikes() methods
clearly map to that field; ensure the attribute names and types match the usage
in docs/week2/02-sequence-diagrams.md (lines ~105,123) for consistency.
refactor(cache): 캐시 키 형식 및 오류 메시지 개선
📌 Summary
💬 Review Points
사용자가 좋아요를 누를 경우 Like 테이블에 새로운 레코드를 삽입하고 취소 시 해당 레코드를 삭제하는 방식으로 설계했습니다. 이 방식이 아닌 차라리 새로운 레코드 삽입 시 liked_yn 플래그 필드를 하나 두고 업데이트하는 방식이 더 나은 방식일까요?
서비스 요구사항에 맞춰 최대한 단순하게 요구사항 명세 및 시나리오, ERD 등을 작성해보았는데, 멘토님들께서 의도한 요구사항에 제 설계가 충족하고 있는지 궁금합니다.
✅ Checklist
Summary by CodeRabbit