Spring 2기 과제

포인트 기반 커피 주문 결제 시스템 (도메인 설계)

sudaruuu 2026. 3. 27. 15:40

https://github.com/Banhklo2/coffee-order-system.git

 

GitHub - Banhklo2/coffee-order-system: Spring Boot 기반 포인트 기반 커피 주문 결제 시스템

Spring Boot 기반 포인트 기반 커피 주문 결제 시스템. Contribute to Banhklo2/coffee-order-system development by creating an account on GitHub.

github.com

 

☕ Coffee Order System


📋 기확 관련 메모

포인트 기반으로 커피 메뉴를 조회하고, 충전한 포인트로 주문 및 결제를 진행할 수 있는 커피 주문 서비스입니다.

사용자는 메뉴 정보를 조회한 뒤 원하는 메뉴를 선택하여 주문을 생성하고, 보유 포인트를 사용해 결제를 진행할 수 있습니다.

결제가 완료되면 주문 내역이 저장되며, 주문 정보는 외부 데이터 수집 플랫폼으로 실시간 전송됩니다.

또한 최근 7일간의 주문 데이터를 기준으로 인기 메뉴 3개를 조회할 수 있습니다.


👤 사용자 역할

일반 사용자 (Customer)

  • 메뉴 조회
  • 포인트 충전
  • 주문 생성
  • 포인트 결제 진행
  • 인기 메뉴 조회

📌 프로젝트 소개

요구사항을 기반으로 도메인 규칙을 정의하고,
주문/결제/포인트 흐름을 중심으로 시스템을 설계하였다.


🧩 플로우차트 설계


🧩 요구사항 → 도메인 규칙

1. 메뉴 조회

  • 사용자는 커피 메뉴 목록을 조회할 수 있다.
  • 메뉴 조회 시 메뉴 ID, 메뉴명, 가격 정보를 확인할 수 있다.
  • 메뉴 가격은 원화 기준으로 관리한다.

2. 포인트 충전

  • 결제는 포인트로만 가능하다.
  • 사용자는 충전 금액을 입력하여 포인트를 충전할 수 있다.
  • 포인트는 1원 = 1포인트로 충전되며, 사용자는 원하는 금액만큼 자유롭게 충전할 수 있도록 설계하였다.
  • 단, 잘못된 입력을 방지하기 위해 충전 금액은 0보다 커야 한다.
  • 충전이 완료되면 사용자의 현재 포인트가 증가해야 한다.
  • 충전 이력은 PointHistory에 저장한다.
  • 포인트 이력의 변화량은 amount로 관리한다.
  • 포인트 이력 상태는 CHARGE, USE로 구분한다.

⭐ 포인트를 자유롭게 충전하도록 한 이유

  • 결제 로직 단순화 + 상태 변화 집중

3. 주문 생성 및 결제

  • 사용자는 메뉴를 선택하여 주문을 생성할 수 있다.
  • 주문 시 사용자 식별값과 메뉴 ID를 입력받는다.
  • 주문 생성 시 주문 총금액(total_price)을 계산한다.
  • 주문한 메뉴 정보는 OrderItem에 저장한다.
  • 주문 시점의 메뉴명, 메뉴가격은 이후 메뉴 정보가 변경되어도 유지되어야 한다.
  • 결제는 사용자의 현재 포인드(User.point)에서 차감한다.
  • 보유 포인트가 부족하면 결제를 진행할 수 없다.
  • 결제가 성공하면 Payment 이력을 저장한다.
  • 결제 상태는 SUCCESS, FAILED로 구분한다.
  • 주문 정보는 외부 데이터 수집 플랫폼으로 실시간 전송한다.
  • 전송 데이터는 사용자 ID, 메뉴 ID, 결제 금액을 포함한다.

4. 인기 메뉴 조회

  • 최근 7일간 주문 데이터를 기준으로 인기 메뉴를 조회한다.
  • 인기 메뉴는 주문 횟수 기준 상위 3개를 조회한다.
  • 주문 횟수 집계는 정확해야 한다.
  • 인기 메뉴 조회 시 메뉴 ID, 메뉴명, 주문 횟수를 반환할 수 있다.

⭐ 7일 기준으로 설정한 이유

  • 너무 짧으면 변동성이 큼
  • 너무 길면 최신 트렌드 반영 어려움
  • 최근성과 안정성을 모두 고려한 기준

🧩 도메인 설계

  • User: 사용자 정보 및 현재 포인트 관리
  • Menu: 커피 메뉴 정보 관리
  • Order: 주문 정보 및 상태 관리
  • OrderItem: 주문 시점의 메뉴 정보를 스냅샷으로 저장
  • Payment: 결제 이력 관리
  • PointHistory: 포인트 충전/사용 이력 관리

🔗 연관관계

  • User(1) : Order(N)
  • User(1) : PointHistory(N)
  • User(1) : Payment(N)
  • Order(1) : OrderItem(N)
  • Menu(1) : OrderItem(N)
  • Order(1) : Payment(N) → 확장 가능한 구조

🗂️ ERD

https://www.erdcloud.com/d/XbDjagmXhWaoiM7tL


⚠️ 예외 처리 / 비즈니스 규칙

포인트 충전

  • 충전 금액은 0 이하일 수 없다.

주문 / 결제

  • 존재하지 않는 사용자는 주문할 수 없다.
  • 존재하지 않는 메뉴는 주문할 수 없다.
  • 보유 포인트가 부족하면 결제할 수 없다.
  • 결제 실패 시 포인트가 차감되면 안 된다.
  • 주문 생성, 포인트 차감, 결제 저장은 하나의 트랜잭션으로 처리해야 한다.
  • 외부 플랫폼 전송은 결제 성공 이후 수행한다.

인기 메뉴 조회

  • 집계 대상은 최근 7일 이내 완료된 주문 기준으로 제한한다.

⚙️ 기술적 고려사항

1. 트랜잭션

  • 주문 생성
  • 포인트 차감
  • 결제 이력 저장

⭐ 주문 생성, 포인트 차감, 결제 이력 저장은 하나의 트랜잭션으로 처리하여

데이터 정합성을 보장하는 구조로 설계한다.


2. 동시성

  • 여러 결제 요청이 동시에 들어올 경우 포인트 차감 정합성이 깨질 수 있다.
  • 사용자 포인트 차감 시 동시성 제어가 필요하다.

3. 인기 메뉴 집계

  • order_items 테이블 기준으로 메뉴별 주문 횟수 집계
  • 상위 3개 조회

초기 구현

  • 별도의 집계 테이블 없이 집계 쿼리로 처리한다.

확장 고려

  • 트래픽 증가 시 Redis 캐시 도입 또는 집계 테이블 분리를 고려한다.

4. 외부 플랫폼 실시간 전송

  • 결제 성공 이후 수행
  • Mock API 또는 테스트 코드로 구현 가능
  • 전송 데이터 : 사용자 ID, 메뉴 ID, 결제 금액

⭐ 핵심 주문/결제 로직과 외부 연동 로직을 분리하는 구조로 설계한다.