Skip to content

kt-cloud-basic-project/shopping

Repository files navigation

Java Spring Boot JPA MySQL Swagger Docker IntelliJ GitHub Gradle Discord Notion Jira GitHub Issues Postman Swagger UI

πŸ“‘ Table of Contents

ShoppingFourU

ShoppingFourU λŠ” 온라인 μ‡Όν•‘λͺ° μš΄μ˜μ— ν•„μš”ν•œ κΈ°λŠ₯듀을 μ™„μ „ν•˜κ²Œ κ΅¬ν˜„ν•œ E-commerce ν”Œλž«νΌμž…λ‹ˆλ‹€.
νšŒμ› 관리뢀터 μƒν’ˆ 등둝, μž₯λ°”κ΅¬λ‹ˆ, μ£Όλ¬Έ/κ²°μ œκΉŒμ§€ μ‹€μ œ μ„œλΉ„μŠ€μ™€ λ™μΌν•œ 흐름을 μ œκ³΅ν•˜λ©°
μ‚¬μš©μž κ²½ν—˜κ³Ό κ΄€λ¦¬μž 운영 κ²½ν—˜μ„ λͺ¨λ‘ λ‹΄μ•„λ‚Έ μ‡Όν•‘ μ„œλΉ„μŠ€μž…λ‹ˆλ‹€.

πŸ‘₯ Team Member

이름 GITHUB μ—­ν• 
πŸ¦” μ–‘μ •μš” https://github.com/jungyoyang νŒ€μ›
🀭 이동석 https://github.com/DaveLee-b νŒ€μ›
πŸ€“ μ „μ§€λ―Ό https://github.com/jeemin65-pixel νŒ€μ›
🐨 μ •λ¬Έμ˜ https://github.com/munyeong0103 νŒ€μž₯
🫠 μ •μ’…ν•œ https://github.com/jong15325/ νŒ€μ›

πŸ› Architecture

πŸ“œ ERD 섀계도 basic-project-shopping_last_last_copy

πŸ“Œ Convention

μžμ„Έν•œ μ»¨λ²€μ…˜μ‚¬ν•­μ€ λ…Έμ…˜μ„ 톡해 확인 ν•΄μ£Όμ„Έμš”! https://vivid-thyme-ac6.notion.site/Commit-Convention-2e19e3e335cc80d7bf16c7377e4ddeac?source=copy_link

πŸ“‘ API Documentation

전체 API λͺ…μ„Έ 및 상세 μŠ€νŽ™μ€ μ•„λž˜ λ§ν¬μ—μ„œ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

πŸ“„ Full API Documentation (Notion)
πŸ“„ Swagger Documentation


πŸ”₯ Troubleshooting

λΆˆν•„μš”ν•œ 쿼리 생성 문제

문제 상황

  • 할인 정보 쑰회 μ‹œ 멀버십 정보도 ν•„μš”ν•¨
  • Lazy Loading으둜 인해 2번의 쿼리 λ°œμƒ (할인 쑰회 β†’ 멀버십 쑰회)
  • λͺ©λ‘ μ‘°νšŒμ—μ„œλŠ” N+1 문제둜 μ΄μ–΄μ§ˆ 수 μžˆλŠ” ꡬ쑰

ν•΄κ²° 방법

  • @EntityGraph 둜 Fetch Join 적용
  • 1번의 쿼리둜 ν†΅ν•©ν•˜μ—¬ μ„±λŠ₯ κ°œμ„ 
  • 쿼리 횟수 50% κ°μ†Œ (2회 β†’ 1회)

JWT ν•„ν„° μ˜ˆμ™Έ 처리 문제

문제 상황

  • 토큰이 ν•„μš” μ—†λŠ” μš”μ²­μ—μ„œλ„ 토큰 검증 μ˜ˆμ™Έ λ°œμƒ
  • Authorization 헀더가 μ—†λŠ” κ²½μš°μ—λ„ μ˜ˆμ™Έλ₯Ό 던져 Controller λ‘œμ§κΉŒμ§€ μ „λ‹¬λ˜μ§€ λͺ»ν•¨

κΈ°μ‘΄ 문제 μ½”λ“œ

private String resolveToken(HttpServletRequest request) {
    String header = request.getHeader(AUTH_HEADER);

    if (!StringUtils.hasText(header) || !header.startsWith(BEARER_PREFIX)) {
        throw new CustomException(ErrorCode.INVALID_JWT_TOKEN);
    }
    return header.substring(BEARER_PREFIX.length());
}

해결방법

if (!StringUtils.hasText(header) || !header.startsWith(BEARER_PREFIX)) {
    return null;
}
return header.substring(BEARER_PREFIX.length());

- Authorization 헀더가 μ—†κ±°λ‚˜ Bearer 둜 μ‹œμž‘ν•˜μ§€ μ•ŠμœΌλ©΄ μ˜ˆμ™Έλ₯Ό λ˜μ§€μ§€ μ•Šκ³  null λ°˜ν™˜
- μ΄λ ‡κ²Œ ν•˜λ©΄ Securityμ—μ„œ 인증없이 ν†΅κ³Όμ‹œν‚€κ³  Controller λ‘œμ§κΉŒμ§€ μ •μƒμ μœΌλ‘œ 전달됨

πŸš€ κΈ°λ³Έ ν”„λ‘œμ νŠΈ 이후 보완점

κΈ°λ³Έ ν”„λ‘œμ νŠΈ κ΅¬ν˜„ 이후,
μ‹€μ œ 운영 ν™˜κ²½μ—μ„œ λ°œμƒν•  수 μžˆλŠ” λ¬Έμ œλ“€μ„ κ°€μ •ν•˜κ³  μ•ˆμ •μ„±κ³Ό ν™•μž₯성을 μ€‘μ‹¬μœΌλ‘œ ꡬ쑰λ₯Ό λ³΄μ™„ν–ˆμŠ΅λ‹ˆλ‹€.
λ‹¨μˆœ κΈ°λŠ₯ κ΅¬ν˜„μ„ λ„˜μ–΄μ„œ 운영 κ΄€μ μ˜ ν’ˆμ§ˆ κ°œμ„ μ— μ΄ˆμ μ„ λ§žμ·„μŠ΅λ‹ˆλ‹€.

1. Git Β· Slack μ•Œλ¦Ό & Bot μ—λŸ¬ 연동

2. API μ ‘κ·Ό μ œν•œ (Rate Limiting)

섀계 λͺ©ν‘œ

1μ°¨ λ°©μ–΄

  • Global Filter 기반 IP λ‹¨μœ„ μ œν•œ
  • μ΄ˆλ‹Ή 100회 / μ΅œλŒ€ 10,000 IP κΈ°μ€€

2μ°¨ λ°©μ–΄

  • AOP 기반 Controller λ‹¨μœ„ μ ‘κ·Ό μ œμ–΄
  • API νŠΉμ„±μ— 따라 IP / μ‚¬μš©μžλ³„ μ œν•œ μ •μ±… 뢄리 적용

Bucket4j 선택 이유

  • λ©”μ„œλ“œλ³„λ‘œ μ„œλ‘œ λ‹€λ₯Έ μ œν•œ μ •μ±… 적용 κ°€λŠ₯
  • Redis μ‚¬μš©μ΄ μ œν•œμ μΈ ν™˜κ²½ κ³ λ €
  • Caffeine 기반 μΊμ‹œλ‘œ κ²½λŸ‰ Β· κ³ μ„±λŠ₯ Β· λ™μ‹œμ„± μ•ˆμ •μ„± 확보

3. Domain Refactoring

1️⃣ 할인 Β· 멀버십 μ •μ±… λͺ¨λ“ˆν™”

2️⃣ μ£Όλ¬Έ μ‹œ 배솑지 검증 κ°•ν™”

4. μ£Όλ¬Έβ€“κ²°μ œ ν”„λ‘œμ„ΈμŠ€ λ¦¬νŒ©ν† λ§ & λ™μ‹œμ„± μ œμ–΄

κ°œμ„ λœ ν”„λ‘œμ„ΈμŠ€

μ£Όλ¬Έ 생성 API

  • μƒν’ˆ ꡬ맀 κ°€λŠ₯ μ—¬λΆ€ 확인
  • μ£Όλ¬Έ 정보 μ €μž₯
    πŸ‘‰ μƒνƒœ: PENDING_PAYMENT

결제 생성 API

  • μ™ΈλΆ€ 결제 λͺ¨λ“ˆ 호좜
  • (Transaction)
    • 결제 정보 μ €μž₯
    • μƒν’ˆ 재고 차감
    • μ£Όλ¬Έ μƒνƒœ λ³€κ²½ β†’ PAID

πŸ’‘
μ™ΈλΆ€ 결제 API ν˜ΈμΆœμ€ νŠΈλžœμž­μ…˜μ— ν¬ν•¨ν•˜μ§€ μ•Šκ³ ,
DB λ³€κ²½ 둜직만 μ›μžμ μœΌλ‘œ λ¬Άμ–΄ 락 점유 및 μ„±λŠ₯ μ €ν•˜λ₯Ό λ°©μ§€

5. 낙관적 락 (Optimistic Lock) λ„μž…

  • μƒν’ˆ 엔티티에 @Version ν•„λ“œ μΆ”κ°€
  • λ™μ‹œ 재고 차감 μ‹œ 컀밋 μ‹œμ μ— 좩돌 감지
  • 좩돌 λ°œμƒ μ‹œ μ˜ˆμ™Έ 처리 ν›„ μž¬μ‹œλ„ μ „λž΅ 적용

6. 재고 μ˜ˆμ•½ μ‹œμŠ€ν…œ λ„μž…

λ„μž… 이유

  • λ™μ‹œ μ£Όλ¬Έ ν™˜κ²½μ—μ„œ 초과 판맀 λ°©μ§€
  • 결제 μ™„λ£Œ μ „ ꡬ맀 κΆŒν•œ 선점 ν•„μš”

ν”„λ‘œμ„ΈμŠ€

μ£Όλ¬Έ 생성 μ‹œ

  • 재고 차감
  • 재고 μ˜ˆμ•½ 정보 μ €μž₯
  • μ£Όλ¬Έ μƒνƒœ: PENDING_PAYMENT

결제 성곡 μ‹œ

  • 재고 μ˜ˆμ•½ ν•΄μ œ
  • μ£Όλ¬Έ μƒνƒœ λ³€κ²½: PAID

결제 μ‹€νŒ¨ / μ˜ˆμ•½ 만료 μ‹œ

  • μ˜ˆμ•½ 정보 μ‚­μ œ
  • 재고 볡ꡬ

7. 찜 (Wishlist) 도메인 μΆ”κ°€


πŸš€ μƒˆλ‘œμš΄ 기술 λ„μž… 사항 및 μ„ μ • 이유

1. μƒν’ˆ 할인 μ‹œ 이메일 μ•Œλ¦Ό μ‹œμŠ€ν…œ λ„μž…

이메일 μ„ μ • 이유

  • λŒ€λΆ€λΆ„μ˜ μ‚¬μš©μžκ°€ 이메일을 λ³΄μœ ν•˜κ³  μžˆμ–΄ 접근성이 λ†’μŒ
  • νšŒμ›κ°€μž… μ‹œ 이미 이메일 정보λ₯Ό μˆ˜μ§‘ν•˜λ―€λ‘œ
    μΆ”κ°€ 정보 μž…λ ₯μ΄λ‚˜ μ™ΈλΆ€ μ„œλΉ„μŠ€ μ°Έμ—¬λ₯Ό μš”κ΅¬ν•˜μ§€ μ•Šμ•„λ„ 됨
  • Slack, Discord 등은 λ³„λ„μ˜ ν”„λ‘œκ·Έλž¨ μ‚¬μš© 및 곡간 μ°Έμ—¬κ°€ ν•„μš”ν•˜μ—¬
    μ‚¬μš©μž μ•Œλ¦Ό λͺ©μ κ³Ό λ§žμ§€ μ•Šμ•„ μ œμ™Έ
  • μΉ΄μΉ΄μ˜€ν†‘ μ±„λ„μ˜ 경우
    • μ‚¬μ—…μž 등둝 ν•„μˆ˜
    • 유료 λ©”μ‹œμ§€ λ°œμ†‘
    • 카카였 계정 κ΄€λ ¨ 정보 μΆ”κ°€ 관리 ν•„μš”
      β†’ 운영 λΉ„μš© 및 λ³΅μž‘μ„± μ¦κ°€λ‘œ 인해 μ œμ™Έ

2. OpenAI 기반 FAQ 챗봇 λ„μž…

데이터 ꡬ성

  • 도메인별 자주 λ¬»λŠ” 질문과 닡변을 JSON 파일둜 정리
  • ν•΄λ‹Ή 데이터λ₯Ό 기반으둜 벑터 μŠ€ν† μ–΄(Vector Store) 연동

κΈ°λŠ₯ λ²”μœ„

  • FAQ JSON 데이터 기반 μ§ˆμ˜μ‘λ‹΅ 제곡
  • μ„œλΉ„μŠ€ λ‹΄λ‹Ή 도메인 μ™Έ μ§ˆλ¬Έμ— λŒ€ν•΄μ„œλŠ”
    응닡을 μ œν•œν•˜μ—¬ λΉ„μ˜λ„μ  λ‹΅λ³€ λ°©μ§€

3. ELK + λͺ¨λ‹ˆν„°λ§ μ‹œμŠ€ν…œ λ„μž…

μ—­ν•  뢄리 및 ν™œμš©

ELK Stack

  • μ—λŸ¬ 둜그 μˆ˜μ§‘
  • μš”μ²­ 흐름 및 μž₯μ•  원인 좔적

Prometheus + Grafana

  • EC2 및 Docker μ»¨ν…Œμ΄λ„ˆ λ¦¬μ†ŒμŠ€ λͺ¨λ‹ˆν„°λ§
  • CPU / λ©”λͺ¨λ¦¬ / μ„œλΉ„μŠ€ λΆ€ν•˜ μƒνƒœ μ‹€μ‹œκ°„ μ‹œκ°ν™”

λ„μž… 효과

  • λ‘œκ·Έμ™€ λ©”νŠΈλ¦­μ„ λΆ„λ¦¬ν•˜μ—¬ 뢄석 κ°€λŠ₯
  • μ„œλΉ„μŠ€ μž₯μ•  λ°œμƒ μ‹œ 원인 νŒŒμ•… 속도 ν–₯상
  • 운영 κ΄€μ μ—μ„œ μ‹œμŠ€ν…œ μƒνƒœλ₯Ό ν•œλˆˆμ— νŒŒμ•… κ°€λŠ₯

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 5