Skip to content

Comments

[volume-2] 요구사항 문서, 시퀀스 다이어그램, 클래스 다이어그램, ERD 작성 #58

Merged
hyejin0810 merged 11 commits intoLoopers-dev-lab:hyejin0810from
hyejin0810:main
Feb 23, 2026
Merged

[volume-2] 요구사항 문서, 시퀀스 다이어그램, 클래스 다이어그램, ERD 작성 #58
hyejin0810 merged 11 commits intoLoopers-dev-lab:hyejin0810from
hyejin0810:main

Conversation

@hyejin0810
Copy link

@hyejin0810 hyejin0810 commented Feb 12, 2026

📌 Summary

  • 배경: 1주차에 회원(가입/조회/비밀번호변경) 기능이 TDD로 구현된 상태에서, 이커머스 핵심 도메인(브랜드, 상품, 좋아요, 장바구니, 주문)의 설계가 필요했다.
  • 목표: 유저 시나리오 기반으로 요구사항을 도출하고, 시퀀스 다이어그램 / 클래스 다이어그램 / ERD를 작성하여 구현 전 설계를 확립한다.
  • 결과: 요구사항 정의서 1건(시나리오 5개 + 기능/비기능 요구사항), 시퀀스 다이어그램 3건(좋아요, 주문생성, 주문상태변경), 클래스 다이어그램(Entity 7개 + Service
    2개), ERD 7개 테이블 설계 완료.

💬 리뷰 포인트

  1. likes_count 비정규화: Product에 likes_count를 두고 좋아요 등록/취소 시 함께 갱신하는 구조에서, 동시성 이슈(동시에 좋아요 등록 시 count 정합성) 대응이
    충분한지
  2. 물리 FK 미사용 + 애플리케이션 레벨 참조 무결성: Service에서 존재 여부를 확인하는 방식으로 충분한지, 놓치는 케이스가 없는지
  3. OrderService의 의존 범위: ProductRepository + OrderRepository + CartRepository를 한 Service가 갖는 구조가 적절한지, Facade 레이어로 분리가 필요한지 궁금합니다...

🧭 Context & Decision

선택지와 결정

  1. 조회 최적화: 좋아요 수와 FK 제약
    Context: 상품 목록 조회 시 발생하는 N+1 쿼리와 DB 의존성 문제

Decision: 좋아요 수 비정규화 및 논리적 FK 채택

Why: 읽기 비중이 압도적인 커머스 특성상 COUNT 집계 비용을 줄여야 함. 또한 DB 물리 제약을 제거해 쓰기 성능을 높이고 향후 서비스 분리(MSA)나 Soft Delete 연동 시 유연함을 확보하기 위함.

  1. 동시성 및 무결성: 재고와 중복 방지
    Context: 동시 주문 폭주 및 Race Condition 발생 위험

Decision: 낙관적 락(@Version) 및 DB 복합 유니크 제약 적용

Why: 읽기 빈도가 높아 비관적 락보다 처리량이 좋은 낙관적 락을 선택하고 충돌 시 재시도함. 앱 레벨 체크만으로는 부족한 중복 데이터 방지는 DB 유니크 제약으로 최종 차단함.

  1. 데이터 기록: 주문 정보와 삭제 정책
    Context: 상품 정보 변경에 따른 이력 오염 및 데이터 복구 필요성

Decision: 주문 스냅샷(복사) 저장 및 선택적 Soft Delete

Why: 주문 후 상품명이나 가격이 바뀌어도 거래 기록은 유지되어야 함. 유저/상품 등 주요 자산은 실수에 대비해 Soft Delete를 적용하고, 장바구니 등 휘발성 데이터는 Hard Delete로 용량을 관리함.

  1. 운영 및 보안: 주문번호와 브랜드 연동
    Context: 매출 규모 노출 위험 및 브랜드 삭제 시 데이터 정합성

Decision: 별도 주문번호 체계 구축 및 브랜드 삭제 시 상품 연쇄 처리

Why: PK 노출로 인한 보안 취약점을 막고 운영 편의를 위해 별도 번호를 생성함. 브랜드가 삭제되었는데 상품만 노출되는 논리적 오류를 막기 위해 소속 상품도 함께 처리함.

  1. 아키텍처 및 UX: 로직 위치와 장바구니
    Context: 서비스 로직 비대화 및 중복 상품 담기 시나리오

Decision: 엔티티 내 비즈니스 로직 캡슐화 및 장바구니 수량 합산

Why: decreaseStock() 등을 엔티티가 직접 수행하게 하여 도메인 규칙을 강제함. 중복 상품 추가 시 에러를 뱉기보다 수량을 합쳐주는 것이 사용자 입장에서 자연스러운 흐름

🏗️ Design Overview

변경 범위

  • 영향 받는 모듈: commerce-api (브랜드, 상품, 좋아요, 장바구니, 주문)
  • 신규 추가:
    • docs/design/01-requirements.md — 요구사항 정의서
    • docs/design/02-sequence-diagrams.md — 시퀀스 다이어그램 3건
    • docs/design/03-class-diagram.md — 클래스 다이어그램
    • docs/design/04-erd.md — ERD (7개 테이블)
  • 제거/대체: 없음 (설계 문서만 추가)

주요 컴포넌트 책임

컴포넌트 책임
LikeService 좋아요 등록/취소 + Product.likesCount 증감
OrderService 주문 생성(재고 확인→차감→저장→장바구니 삭제), 승인/취소 상태 변경
Product Entity decreaseStock/increaseStock 재고 관리, increaseLikes/decreaseLikes 좋아요 수 관리
Order Entity approve()/cancel()/isPending() 상태 전이 규칙 캡슐화
OrderItem 주문 시점 상품 정보 스냅샷 보관 (productName, productPrice, brandName)

변경 요약

변경 목적: 기존 설계 문서(요구사항서, 시퀀스 다이어그램, 클래스 다이어그램, ERD)의 마크다운 형식을 개선하고 Mermaid 다이어그램의 참여자 별칭(actor, participant)을 정리하여 가독성 및 일관성 향상

핵심 변경점:

  • docs/design/01-requirements.md ~ 04-erd.md 마크다운 표기 정규화 및 Mermaid 시퀀스 다이어그램의 참여자명 정리(예: "좋아요 처리"에서 Auth Filter, Like API, Like Service, Product Repository 등으로 명확화)
  • build.gradle.kts와 gradle.properties의 testcontainers 의존성 추가는 이전 커밋(3310a3d)에서 이루어짐

리스크/주의사항: 없음 (문서 포맷 정리만 해당)

테스트/검증 방법: 마크다운 린터로 문법 검증, Mermaid 다이어그램이 정상 렌더링되는지 GitHub/Wiki에서 확인, 설계 문서 검토자의 사전 승인 여부 확인 필요

madirony and others added 11 commits February 7, 2026 22:07
fix : 예제 테스트 코드 오류 해결을 위한 testcontainers 버전 업
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link

coderabbitai bot commented Feb 12, 2026

📝 Walkthrough

Walkthrough

의존성 관리에 TestContainers BOM을 추가한다. gradle.properties에 testcontainersVersion=2.0.2를 정의하고, build.gradle.kts의 dependencyManagement에 해당 BOM을 포함시킨다.

Changes

Cohort / File(s) Summary
의존성 버전 정의
gradle.properties
testcontainersVersion=2.0.2 버전 속성 추가
의존성 관리 구성
build.gradle.kts
org.testcontainers:testcontainers-bom BOM을 dependencyManagement에 임포트

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~5 minutes

Possibly related PRs

Suggested reviewers

  • hubtwork
🚥 Pre-merge checks | ✅ 3 | ❌ 3
❌ Failed checks (2 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning gradle 파일 변경은 PR 제목의 '설계 문서 작성' 범위를 벗어난다. testcontainers-bom 추가는 테스트 인프라와 관련된 별개의 개선사항이므로 명시적 설명이 필요하다. testcontainers 의존성 추가가 이 PR의 범위에 포함되는 이유를 설명하거나, 별도의 인프라 개선 PR로 분리하기 바란다.
Merge Conflict Detection ⚠️ Warning ❌ Merge conflicts detected (2 files):

⚔️ build.gradle.kts (content)
⚔️ gradle.properties (content)

These conflicts must be resolved before merging into hyejin0810.
Resolve conflicts locally and push changes to this branch.
Linked Issues check ❓ Inconclusive linked issues 정보가 제공되지 않아 PR과 이슈 간 추적 가능성을 확인할 수 없다. 해당 PR이 연관된 issue가 있다면 명시하여 요구사항 추적(traceability)을 개선하기 바란다.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목은 요구사항 문서, 시퀀스 다이어그램, 클래스 다이어그램, ERD 작성이라는 설계 문서 추가의 핵심 내용을 정확하게 반영하고 있다.
Description check ✅ Passed PR 설명은 template의 Summary, Context & Decision, Design Overview 섹션을 충분히 작성했으며, 배경/목표/결과, 의사결정 근거, 변경 범위를 명확히 제시했다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
⚔️ Resolve merge conflicts (beta)
  • Auto-commit resolved conflicts to branch main
  • Post resolved changes as copyable diffs in a comment

No actionable comments were generated in the recent review. 🎉


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@looper88888
Copy link
Contributor

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Feb 13, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@looper88888
Copy link
Contributor

@coderabbitai review

상품/브랜드/좋아요/주문 도메인이 모두 포함되어 있는가?
기능 요구사항이 유저 중심으로 정리되어 있는가?
시퀀스 다이어그램에서 책임 객체가 드러나는가?
클래스 구조가 도메인 설계를 잘 표현하고 있는가?
ERD 설계 시 데이터 정합성을 고려하여 구성하였는가?

위 체크리스트에 맞게 구현되어있는지 확인해.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
build.gradle.kts (1)

67-70: ⚠️ Potential issue | 🟠 Major

Testcontainers 2.0 마이그레이션 시 JUnit 5 통합 모듈의 아티팩트 ID 갱신이 필요하다.

Testcontainers 2.0에서 모든 모듈의 아티팩트 ID가 testcontainers- 접두사를 갖도록 변경되었다. 라인 70의 org.testcontainers:junit-jupiterorg.testcontainers:testcontainers-junit-jupiter로 수정되어야 한다. 올바른 아티팩트 좌표를 사용하지 않으면 BOM 해석 오류 또는 호환성 문제가 발생하여 런타임 ClassNotFoundException으로 이어질 수 있다.

🔧 2.0 호환 좌표로의 변경
         // Testcontainers
         testImplementation("org.springframework.boot:spring-boot-testcontainers")
         testImplementation("org.testcontainers:testcontainers")
-        testImplementation("org.testcontainers:junit-jupiter")
+        testImplementation("org.testcontainers:testcontainers-junit-jupiter")
🤖 Fix all issues with AI agents
In `@build.gradle.kts`:
- Around line 44-46: Replace the incorrect Testcontainers artifact coordinate
"org.testcontainers:junit-jupiter" with the new Testcontainers 2.0 artifact id
"org.testcontainers:testcontainers-junit-jupiter" where the dependency is
declared (the dependency string "org.testcontainers:junit-jupiter"); update the
build.gradle.kts dependency block to use
"org.testcontainers:testcontainers-junit-jupiter" and then run the full
build+test pipeline (CI) to confirm the dependency resolution and tests pass.

Comment on lines 44 to 46
mavenBom("org.springframework.cloud:spring-cloud-dependencies:${project.properties["springCloudDependenciesVersion"]}")
mavenBom("org.testcontainers:testcontainers-bom:${project.properties["testcontainersVersion"]}")
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# 빌드 파일에서 testcontainers 관련 의존성 확인
echo "=== build.gradle.kts에서 testcontainers 의존성 확인 ==="
if [ -f "build.gradle.kts" ]; then
  cat -n build.gradle.kts | grep -A2 -B2 "testcontainers"
fi

Repository: Loopers-dev-lab/loop-pack-be-l2-vol3-java

Length of output: 1146


🏁 Script executed:

#!/bin/bash
# Maven Central에 아티팩트 존재 여부 확인
echo "=== Maven Central 아티팩트 확인 ==="

echo "1. testcontainers-bom:2.0.2"
curl -s -o /dev/null -w "HTTP %{http_code}\n" "https://repo1.maven.org/maven2/org/testcontainers/testcontainers-bom/2.0.2/testcontainers-bom-2.0.2.pom"

echo "2. junit-jupiter:2.0.2 (구형 좌표)"
curl -s -o /dev/null -w "HTTP %{http_code}\n" "https://repo1.maven.org/maven2/org/testcontainers/junit-jupiter/2.0.2/junit-jupiter-2.0.2.pom"

echo "3. testcontainers-junit-jupiter:2.0.2 (신형 좌표)"
curl -s -o /dev/null -w "HTTP %{http_code}\n" "https://repo1.maven.org/maven2/org/testcontainers/testcontainers-junit-jupiter/2.0.2/testcontainers-junit-jupiter-2.0.2.pom"

echo "4. testcontainers (core):2.0.2"
curl -s -o /dev/null -w "HTTP %{http_code}\n" "https://repo1.maven.org/maven2/org/testcontainers/testcontainers/2.0.2/testcontainers-2.0.2.pom"

Repository: Loopers-dev-lab/loop-pack-be-l2-vol3-java

Length of output: 286


🌐 Web query:

Testcontainers 2.0 artifact coordinates module naming changes

💡 Result:

In Testcontainers for Java 2.0.0, the groupId stays the same (org.testcontainers), but all non-core modules changed artifactIds to be prefixed with testcontainers-. (github.com)

Rule

  • Before 2.0: org.testcontainers:<module>
  • Since 2.0: org.testcontainers:testcontainers-<module> (github.com)

Common examples

  • org.testcontainers:mysqlorg.testcontainers:testcontainers-mysql (github.com)
  • org.testcontainers:cratedborg.testcontainers:testcontainers-cratedb (java.testcontainers.org)
  • org.testcontainers:openfgaorg.testcontainers:testcontainers-openfga (java.testcontainers.org)
  • JUnit Jupiter module is now published as org.testcontainers:testcontainers-junit-jupiter (tessl.io)

Unchanged / notable

Citations:


Line 70 아티팩트 좌표를 Testcontainers 2.0에 맞게 변경해야 한다.

Testcontainers 2.0에서 모든 비핵심 모듈의 아티팩트ID에 testcontainers- 접두사가 추가되었다. Line 70의 org.testcontainers:junit-jupiter는 Maven Central에 존재하지 않아(HTTP 404) 의존성 해석 실패로 인한 빌드 실패를 야기한다.

이는 테스트 단계에서 즉시 발견되는 문제로, 모든 CI 파이프라인이 중단된다. 운영 배포 전에 반드시 수정해야 한다.

변경 사항:

org.testcontainers:junit-jupiter → org.testcontainers:testcontainers-junit-jupiter

CI 파이프라인에서 전체 빌드 및 테스트 실행이 정상 통과하는지 반드시 확인해야 한다.

🤖 Prompt for AI Agents
In `@build.gradle.kts` around lines 44 - 46, Replace the incorrect Testcontainers
artifact coordinate "org.testcontainers:junit-jupiter" with the new
Testcontainers 2.0 artifact id "org.testcontainers:testcontainers-junit-jupiter"
where the dependency is declared (the dependency string
"org.testcontainers:junit-jupiter"); update the build.gradle.kts dependency
block to use "org.testcontainers:testcontainers-junit-jupiter" and then run the
full build+test pipeline (CI) to confirm the dependency resolution and tests
pass.

@coderabbitai
Copy link

coderabbitai bot commented Feb 13, 2026

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Read all design documents to review against the checklist

echo "=== 01-requirements.md ==="
cat docs/design/01-requirements.md

echo -e "\n\n=== 02-sequence-diagrams.md ==="
cat docs/design/02-sequence-diagrams.md

echo -e "\n\n=== 03-class-diagram.md ==="
cat docs/design/03-class-diagram.md

echo -e "\n\n=== 04-erd.md ==="
cat docs/design/04-erd.md

Length of output: 359


🏁 Script executed:

#!/bin/bash
# Find design documents in the repository

echo "=== Finding design documents ==="
fd -t f "requirements.md|sequence-diagrams.md|class-diagram.md|erd.md"

echo -e "\n=== Listing all markdown files in docs directory ==="
fd -t f ".md" docs/

Length of output: 179


🏁 Script executed:

#!/bin/bash
# Check what files are actually changed in this PR

echo "=== Repository structure ==="
tree -L 3 -I 'node_modules|build|.gradle|.git'

echo -e "\n\n=== Git log (recent commits) ==="
git log --oneline -10

echo -e "\n\n=== Changed files in recent commit ==="
git diff --name-only HEAD~1 HEAD

echo -e "\n\n=== All markdown files in repository ==="
fd -e md

Length of output: 1698


🏁 Script executed:

#!/bin/bash
# Read all design documents

echo "=== Checking what design files exist ==="
ls -la docs/design/ 2>/dev/null || echo "docs/design directory check..."

echo -e "\n=== Finding all files in docs ==="
find . -path "./docs/*" -type f 2>/dev/null

echo -e "\n\n=== Reading 01-requirements.md ==="
cat ./docs/design/01-requirements.md 2>/dev/null || echo "File not found"

echo -e "\n\n=== Reading 02-sequence-diagrams.md ==="
cat ./docs/design/02-sequence-diagrams.md 2>/dev/null || echo "File not found"

echo -e "\n\n=== Reading 03-class-diagram.md ==="
cat ./docs/design/03-class-diagram.md 2>/dev/null || echo "File not found"

echo -e "\n\n=== Reading 04-erd.md ==="
cat ./docs/design/04-erd.md 2>/dev/null || echo "File not found"

Length of output: 311


🏁 Script executed:

#!/bin/bash
# Read files from the latest commit

echo "=== Files in the latest commit ==="
git show --name-status HEAD

echo -e "\n\n=== Reading 01-requirements.md from HEAD ==="
git show HEAD:docs/design/01-requirements.md

echo -e "\n\n=== Reading 02-sequence-diagrams.md from HEAD ==="
git show HEAD:docs/design/02-sequence-diagrams.md

echo -e "\n\n=== Checking for 03-class-diagram.md ==="
git show HEAD:docs/design/03-class-diagram.md 2>&1 || echo "Not in HEAD commit"

echo -e "\n\n=== Checking for 04-erd.md ==="
git show HEAD:docs/design/04-erd.md 2>&1 || echo "Not in HEAD commit"

echo -e "\n\n=== All docs/design files in git history ==="
git log --all --pretty=format: --name-only --diff-filter=A | grep "docs/design" | sort -u

Length of output: 12313


@looper88888: 체크리스트 기준으로 설계 문서를 검토하였다.

✅ 체크리스트 검증 결과

1. 상품/브랜드/좋아요/주문 도메인 포함 여부

통과. Brand, Product, Like, Order, OrderItem 5개 핵심 도메인과 Cart(장바구니), User 도메인까지 총 7개 엔티티가 정의되어 있다.

2. 기능 요구사항의 유저 중심 정리

통과. 01-requirements.md에 5개 유저 시나리오(회원 가입 후 상품 탐색, 관심 상품 저장, 장바구니 담기 및 관리, 상품 주문, 관리자 상품 및 주문 관리)가 흐름 기반으로 작성되었고, 기능 요구사항이 "사용자는...", "관리자는..." 형태로 명확히 정리되어 있다.

3. 시퀀스 다이어그램의 책임 객체 표현

통과. 3개 시퀀스 다이어그램(좋아요 처리, 주문 생성, 주문 상태 변경) 모두 Auth Filter → API → Service → Repository 계층 구조가 명확히 드러나며, 각 객체의 책임(인증, API 처리, 비즈니스 로직, 영속성)이 분리되어 있다.

4. 클래스 구조의 도메인 설계 표현

통과. 03-class-diagram.md에서 Entity 7개와 Service 2개가 정의되었고, Product.decreaseStock(), Order.approve() 등 비즈니스 로직이 엔티티 내부에 캡슐화되어 있어 도메인 주도 설계 원칙을 따르고 있다.

5. ERD의 데이터 정합성 고려

부분 통과. 복합 유니크 제약(user_id+product_id), version 컬럼(낙관적 락), 스냅샷 저장(ORDER_ITEMS), soft delete 등 기본적인 정합성 메커니즘이 포함되어 있으나, 아래 운영 관점 개선이 필요하다.


⚠️ 운영/장애/보안 관점 개선 사항

1. likes_count 동시성 정합성 보장 미흡

문제: Product 테이블의 likes_count는 비정규화되어 있으나, 동시에 여러 사용자가 좋아요를 누를 경우 UPDATE 쿼리 경합으로 인한 count 불일치가 발생할 수 있다. ERD에 version 컬럼이 정의되어 있으나, 클래스 다이어그램의 increaseLikes()/decreaseLikes() 메서드가 낙관적 락을 활용하는지 명시되지 않았다.

수정안:

  • LikeService에서 좋아요 등록/취소 시 Product 엔티티의 @Version을 함께 검증하도록 시퀀스 다이어그램에 명시한다.
  • 또는 likes_count 갱신을 배치 작업으로 분리하고, 실시간 정합성 대신 최종 일관성(Eventual Consistency)을 채택하는 전략을 문서화한다.

추가 테스트: 동시에 100명이 동일 상품에 좋아요를 누르는 부하 테스트를 수행하고, likes_count와 LIKES 테이블 COUNT(*) 결과를 비교하는 검증 로직을 추가한다.


2. 물리적 FK 제약 부재로 인한 참조 무결성 검증 누락

문제: ERD 하단에 "논리적 관계 정의 (물리적 FK 제약조건 없음)"이라고 명시되어 있다. 애플리케이션 레벨에서 존재 여부를 확인하는 방식은 장애 상황(DB 직접 조작, 배치 작업 오류 등)에서 무결성을 보장할 수 없다. 예를 들어, PRODUCTS 테이블의 레코드가 soft delete되었는데 LIKES 테이블에 해당 product_id가 남아 있는 경우 고아 데이터가 생성된다.

수정안:

  • 최소한 ORDERS → USERS, ORDER_ITEMS → ORDERS 등 트랜잭션 정합성이 필수적인 관계는 물리적 FK를 추가한다.
  • FK를 추가할 수 없다면, 주기적으로 참조 무결성을 검증하는 배치 작업을 설계하고 모니터링 알람을 연동한다.

추가 테스트: 참조 무결성 검증 쿼리를 작성하고(예: LIKES 테이블에서 존재하지 않는 product_id 조회), CI 파이프라인에 통합 테스트로 포함시킨다.


3. OrderService의 의존 범위 과다 및 관심사 분리 미흡

문제: 클래스 다이어그램에서 OrderService가 ProductRepository, OrderRepository, CartRepository 3개 저장소를 직접 의존하고 있다. 주문 생성 시퀀스 다이어그램을 보면 "재고 차감 → 주문 저장 → 장바구니 삭제" 3개 책임을 한 Service가 처리하고 있어 단일 책임 원칙(SRP)에 위배되며, 향후 재고 관리 로직이 복잡해질 경우(예: 예약 재고, 배송지별 재고 분리) OrderService가 비대해진다.

수정안:

  • OrderFacade 레이어를 추가하여 OrderService, StockService, CartService를 조율하는 구조로 변경한다.
  • 또는 현재 구조를 유지하되, ProductRepository 의존성을 제거하고 StockService를 주입받아 재고 차감을 위임하도록 리팩토링한다.

추가 테스트: OrderService의 단위 테스트에서 3개 Repository를 모두 Mock 처리해야 하는 복잡도를 확인하고, Facade 패턴 도입 후 테스트 복잡도 감소를 비교한다.


4. 장바구니 최대 개수 제한 검증 로직 누락

문제: 01-requirements.md의 비기능 요구사항에 "장바구니 최대 상품 개수: 100개"가 명시되어 있으나, ERD의 CART 테이블이나 클래스 다이어그램의 Cart 엔티티에 해당 제약 조건이 반영되지 않았다. 런타임에 애플리케이션 레벨에서만 검증할 경우, DB 직접 삽입 시 제한이 우회된다.

수정안:

  • Cart 엔티티에 validateMaxItems() 메서드를 추가하고, CartService에서 상품 추가 전 호출하도록 클래스 다이어그램에 명시한다.
  • 또는 DB 레벨에서 트리거 또는 CHECK 제약 조건으로 사용자당 장바구니 항목 수를 제한하는 방안을 검토한다.

추가 테스트: 장바구니에 100개 상품을 담은 후 101번째 추가 시도 시 예외가 발생하는지 확인하는 통합 테스트를 작성한다.


5. 주문번호 생성 전략의 동시성 충돌 대응 미흡

문제: ORDERS 테이블의 order_number가 "ORD-yyyyMMdd-xxxxx" 형태로 정의되어 있으나, xxxxx 부분의 생성 전략(시퀀스, UUID, 타임스탬프 등)이 명시되지 않았다. 동시에 여러 주문이 생성될 때 중복 방지 메커니즘이 없으면 UK 제약 위반으로 주문 생성이 실패한다.

수정안:

  • 주문번호 생성 전략을 문서화한다. 예: Redis INCR을 사용한 일별 시퀀스, 또는 UUID 기반 랜덤 생성 후 중복 재시도 로직 추가.
  • OrderService에 generateOrderNumber() 메서드를 추가하고, 클래스 다이어그램과 시퀀스 다이어그램에 명시한다.

추가 테스트: 동시에 1000건의 주문을 생성하는 부하 테스트를 수행하고, order_number의 중복 여부를 검증한다.


6. 주문 취소 시 재고 복구 트랜잭션 실패 시나리오 미정의

문제: 주문 상태 변경 시퀀스 다이어그램에서 "주문 취소 → 재고 복구 → 상태 업데이트" 흐름이 정의되어 있으나, 재고 복구는 성공했지만 상태 업데이트가 실패하는 경우(예: DB 연결 끊김) 보상 트랜잭션(Compensating Transaction) 처리 방안이 없다.

수정안:

  • 주문 취소를 Saga 패턴으로 설계하거나, 최소한 @Transactional 범위에 재고 복구와 상태 업데이트를 모두 포함시키고 롤백 전략을 문서화한다.
  • 또는 주문 취소 이벤트를 메시지 큐에 발행하고, 재고 복구를 비동기로 처리하는 방안을 검토한다.

추가 테스트: 주문 취소 트랜잭션 중간에 강제로 예외를 발생시키고, 재고가 원복되는지 확인하는 통합 테스트를 작성한다.


📋 요약

전반적으로 설계 문서는 요구사항 정의부터 시퀀스, 클래스, ERD까지 체계적으로 작성되어 있으며, 체크리스트 5개 항목을 모두 충족한다. 다만 운영 환경에서 발생 가능한 동시성 이슈(likes_count, order_number), 참조 무결성 검증, 트랜잭션 실패 시나리오 등이 설계 단계에서 명시적으로 다뤄지지 않아, 구현 단계에서 위 6개 항목을 보완하고 각 항목에 대한 테스트를 추가할 것을 권장한다.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@hyejin0810 hyejin0810 merged commit bfd730c into Loopers-dev-lab:hyejin0810 Feb 23, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants