Skip to content

89-49/product-service

Repository files navigation

Product Service

P2P 중고 거래 플랫폼 PGSG의 상품 서비스입니다.
상품의 등록, 수정, 조회 및 타임딜 기반 상태 전이를 담당합니다.


기술 스택

분류 기술
Language Java 21
Framework Spring Boot 3
Database PostgreSQL 16
Cache Redis
Message Broker Apache Kafka
Build Gradle
Container Docker
Scheduler Quartz
Search Elasticsearch 8.13

도메인 설계

상품 상태 (ProductStatus)

상태 설명
PENDING_SALE 판매 대기 중. 최초 등록 상태 또는 재등록 대기 상태
PENDING_RESERVATION 예약 대기 중. 타임딜이 시작되어 예약 접수 중인 상태
RESERVING 예약 진행 중. 선착순 예약 접수가 진행되는 상태
IN_TRADE 거래 진행 중. 결제 및 거래가 진행되는 상태
COMPLETED 판매 완료. 거래가 완료된 최종 상태
SALE_CANCELLED 판매 취소. 거래가 취소된 최종 상태

상태 전이 흐름

정상 흐름

PENDING_SALE
    └─ reserve() ──────────────────▶ PENDING_RESERVATION
         ▲                                   │
         │ (Quartz Job)              startReserve() ▼
         │ startTime 도달                 RESERVING
         │                                   │
         │                          startTrade() ▼
         │                               IN_TRADE
         │                                   │
         │                            complete() ▼
         │                              COMPLETED

예외 / 역방향 흐름

전이 메서드 트리거
RESERVING / IN_TRADERESERVING revertToReserving() 구매자 단순 취소 후 다음 예약자 대기
RESERVING / IN_TRADEPENDING_SALE pendSale() 구매자 사유 거래 취소 / 다음 예약자 없을 때
전 상태 → SALE_CANCELLED cancelSale() 판매자 직접 취소 또는 관리자 취소

전이 규칙

  • COMPLETED, SALE_CANCELLED 상태에서는 다른 상태로 전이 불가 (최종 상태)
  • PENDING_SALEIN_TRADE 직접 전이 불가 (반드시 PENDING_RESERVATIONRESERVING을 거쳐야 함)

Kafka 이벤트 연동

상품 상태 전이는 예약 서비스 및 거래 서비스에서 발행하는 Kafka 이벤트를 구독하여 처리합니다.

구독 이벤트 처리 메서드 전이
예약 서비스 - 예약 확정 startReserve() PENDING_RESERVATIONRESERVING
거래 서비스 - 거래 시작 startTrade() RESERVINGIN_TRADE
거래 서비스 - 거래 완료 complete() IN_TRADECOMPLETED
거래 서비스 - 구매자 단순 취소 revertToReserving() IN_TRADERESERVING
예약 서비스 - 예약 취소 pendSale() RESERVINGPENDING_SALE

Quartz 스케줄링

트리거 처리 메서드 전이
타임딜 startTime 도달 reserve() PENDING_SALEPENDING_RESERVATION

CQRS 설계

읽기 성능 최적화를 위해 쓰기 모델과 읽기 모델을 분리합니다.

  • 쓰기 테이블 (p_products): 도메인 상태 관리 및 상태 전이 처리
  • 읽기 모델 (products 인덱스, Elasticsearch): 조회 최적화. 상품 기본 정보 + 판매자 닉네임 등 비정규화 데이터 포함
  • 상품 생성/수정/삭제/상태전이 시 @TransactionalEventListener(AFTER_COMMIT)으로 DB 커밋 후 ES 인덱스 자동 동기화

API 목록

상품 관리

Method URI 설명 권한
POST /api/v1/products 상품 등록 USER
PATCH /api/v1/products/{productId} 상품 수정 (PENDING_SALE~PENDING_RESERVATION 상태에서만 가능) USER (본인), MANAGER
DELETE /api/v1/products/{productId} 상품 삭제 USER (본인), MANAGER
PATCH /api/v1/products/{productId}/cancel 판매 취소 USER (본인), MANAGER
PATCH /api/v1/products/{productId}/timedeal 타임딜 수정 (PENDING_SALE, PENDING_RESERVATION 상태에서만 가능) USER (본인), MANAGER

상품 조회

Method URI 설명 권한
GET /api/v1/products 상품 목록 조회 (페이징) ALL
GET /api/v1/products/{productId} 상품 단건 조회 ALL
GET /api/v1/products/my 내 상품 목록 조회 USER

환경 변수

변수명 설명 기본값
SPRING_PROFILES_ACTIVE 활성화 프로파일 dev,topics,kafka
CONFIG_SERVER Config 서버 주소 -
PRODUCT_DB_HOST DB 호스트 -
PRODUCT_DB_PORT DB 포트 5432
PRODUCT_DB_NAME DB 이름 p_product
PRODUCT_DB_USERNAME DB 사용자 -
PRODUCT_DB_PASSWORD DB 비밀번호 -
BOOTSTRAP_SERVERS Kafka 브로커 주소 -
TRUST_STORE_PASSWORD Kafka SSL truststore 비밀번호 -

실행 방법

로컬 실행

./gradlew bootRun --args='--spring.profiles.active=local'

Docker 실행

# 환경변수 파일 설정
cp .env.template .env
# .env 파일 내 값 입력

# 실행
docker compose up -d

Docker Compose 구성

product-service   : 8082 포트
product-db        : PostgreSQL 16 (5433:5432)
elasticsearch     : 9200 포트

관련 레포지토리

레포지토리 설명
common 공통 모듈 (보안, 메시징, 예외 처리 등)
infra 인프라 (DB, 모니터링)

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages