Skip to content

imbbeck/lessonReservation

Repository files navigation

Lesson Reservation System

수업 예약/대기/체크인 시스템


실행 방법

1. 환경 설정

# Docker 환경 시작
chmod +x docker-commands.sh
./docker-commands.sh up

# 또는 수동으로
docker-compose up -d

2. 애플리케이션 실행

./gradlew bootRun

3. API 요청 테스트

4. 계정 정보

테스트 회원 계정

모든 계정 비밀번호: 12341234

이메일 이름 상태
member1@example.com 회원1 ACTIVE
member2@example.com 회원2 ACTIVE
member3@example.com 회원3 ACTIVE
member4@example.com 회원4 ACTIVE
member5@example.com 회원5 ACTIVE
member6@example.com 회원6 INACTIVE

관리자 계정 - application.yml에 설정.

  • 이메일: admin@lessonrsvn.com
  • 비밀번호: admin123!@#
  • 권한: ADMIN (관리자 전용 API 접근 가능)
  • 전용 엔드포인트: /api/admin/**

프로젝트 개요

수업 예약, 대기열 관리, 체크인 기능을 제공하는 백엔드 시스템입니다.

핵심 기능

  • 수업 관리: 수업 생성, 조회, 수정, 삭제, 정원 증가
  • 예약 시스템: 수업 예약 생성 및 취소, 중복 예약 방지
  • 대기열 관리: 정원 초과 시 자동 대기열 등록 및 승격 처리
  • 체크인: 예약자 출석 처리, 중복 체크인 방지
  • 동시성 제어: Redis 분산락을 활용한 원자적 처리
  • 캐시 최적화: Redis 기반 성능 최적화 및 Self-healing
  • 이벤트 드리븐: 수업 취소/정원 증가/회원 상태 변경 시 연관 데이터 자동 처리
  • 멱등성 보장: API 레벨 멱등성 및 중복 요청 처리

아키텍처

기술 스택

  • Language: Java 21
  • Framework: Spring Boot 3.2.10, Spring Security, Spring Data JPA
  • Authentication: JWT (JSON Web Token)
  • Database: MySQL 8.0 (Flyway 마이그레이션)
  • Cache & Lock: Redis 7.0, Redisson (분산락)
  • Build Tool: Gradle
  • Testing: JUnit 5, AssertJ, Mockito, Testcontainers
  • Documentation: OpenAPI 3.0 (Swagger)
  • Containerization: Docker, Docker Compose

DDD + CQRS 구조

com.lessonRsvn
├── applicationInfra/          # 공통 인프라
│   ├── config/               # 설정 (Security, Redis, Async)
│   ├── exception/            # 전역 예외 처리
│   ├── idempotency/          # 멱등성 필터
│   └── redis/                # Redis 서비스 (캐시, 분산락)
├── lesson/                   # 수업 도메인
│   ├── application/          # 애플리케이션 서비스
│   ├── domain/               # 도메인 모델, 이벤트, 레포지토리
│   ├── dto/                  # 데이터 전송 객체
│   └── interfaces/           # REST 컨트롤러
├── reservation/              # 예약 도메인 (CQRS 적용)
│   ├── application/          # 애플리케이션 서비스
│   │   ├── command/          # 명령 서비스 (상태 변경)
│   │   └── query/            # 조회 서비스 (읽기 전용)
│   ├── checkin/              # 체크인 서브도메인
│   ├── domain/               # 도메인 모델, 서비스, 이벤트
│   ├── dto/                  # 데이터 전송 객체
│   └── interfaces/           # REST 컨트롤러 (Command/Query 분리)
└── member/                   # 회원 도메인
    ├── application/          # 인증/회원 서비스
    ├── domain/               # 도메인 모델, 이벤트
    └── systemNotice/         # 시스템알림 서브도메인 (TODO)

CQRS (Command Query Responsibility Segregation) 적용

예약 도메인에 CQRS 패턴 적용으로 확장성과 성능 최적화:

Command 서비스 (상태 변경)

  • 역할: 예약 생성, 취소, 대기열 승격 등 상태 변경 작업
  • 트랜잭션: 쓰기 트랜잭션 (@Transactional)
  • 동시성 제어: Redis 분산락으로 데이터 일관성 보장
  • 이벤트 발행: 도메인 이벤트를 통한 부가 작업 처리

Query 서비스 (조회 전용)

  • 역할: 예약 목록, 대기열, 통계 등 다양한 조회 작업
  • 트랜잭션: 읽기 전용 (@Transactional(readOnly = true))
  • 성능 최적화: Redis 캐시 우선 조회, N+1 문제 해결
  • 확장성: 조회 전용 최적화 및 독립적 스케일링 가능

개발 환경

데이터베이스 접속 정보

  • MySQL: localhost:3307/lesson_rsvn (lesson_rsvn/lesson_rsvn)
  • Redis: localhost:6380 (password: redispw)

Docker 명령어

./docker-commands.sh up      # 환경 시작
./docker-commands.sh down    # 환경 종료  
./docker-commands.sh restart # 환경 재시작
./docker-commands.sh logs    # 로그 확인
./docker-commands.sh status  # 상태 확인
./docker-commands.sh clean   # 데이터 삭제

주요 비즈니스 로직

1. 예약 생성 프로세스

  • 중복 예약 방지: 동일 회원의 동일 수업 중복 예약 차단
  • 정원 관리: Redis 캐시 기반 실시간 정원 확인
  • 상태 결정: 정원 여유 시 즉시 확정, 초과 시 대기열 등록
  • 재예약 지원: 취소된 예약의 상태 변경을 통한 효율적 재예약

2. 예약 취소 및 자동 승격

  • 동시성 제어: Redis 분산락으로 안전한 취소/승격 처리
  • 자동 승격: 확정 예약 취소 시 대기열 첫 번째 회원 자동 승급
  • 순서 보장: Redis Sorted Set 기반 대기 순서 관리
  • 상태 동기화: 캐시-DB 일관성 유지

3. 체크인 처리

  • 자격 검증: 확정 예약 회원만 체크인 가능
  • 시간 제한: 수업 시작 10분 전부터 종료까지만 허용
  • 중복 방지: 동일 예약에 대한 중복 체크인 차단

4. 이벤트 드리븐 처리

  • 수업 취소: 해당 수업의 모든 예약 자동 취소
  • 정원 증가: 대기열에서 증가량만큼 자동 승급
  • 회원 비활성화: 해당 회원의 모든 예약 자동 취소

동시성 제어 및 성능 최적화

Redis 분산락

  • Redisson 활용: 안전한 분산 환경 동시성 제어
  • 락 범위: 수업별 예약 생성/취소/승급 처리
  • 설정 가능: 대기 시간 및 임대 시간 환경별 설정

캐시 전략

  • 대상: 수업별 확정 예약 수, 대기열 정보
  • Self-healing: 캐시 미스 시 DB 기반 자동 복구
  • TTL 관리: 수업 시작 시간에 자동 만료
  • 정기 동기화: 스케줄러 기반 캐시-DB 일관성 유지

데이터베이스 최적화

  • 인덱스 전략: 쿼리 패턴 기반 복합 인덱스 설계
  • N+1 해결: @EntityGraph 활용한 페치 조인
  • 읽기 최적화: CQRS 패턴의 Query 서비스 분리

테스트

단위 테스트

./gradlew test -Dspring.profiles.active=test

통합 테스트 (Testcontainers)

./gradlew test --tests "*Integration*" -Dspring.profiles.active=testcontainers

전체 테스트 실행

./gradlew test

테스트 커버리지 확인

./gradlew jacocoTestReport
# build/reports/jacoco/test/html/index.html에서 확인

주요 테스트 클래스

  • 단위 테스트: 도메인 엔티티, 서비스별 단위 테스트
  • 통합 테스트: Redis, MySQL 포함한 실제 환경 테스트
  • 동시성 테스트: 분산락 및 대기열 처리 검증
  • 시스템 테스트: End-to-End 전체 플로우 검증

API 엔드포인트

인증 API

POST /api/auth/login           # 로그인
POST /api/auth/refresh         # 토큰 갱신
POST /api/auth/refresh-from-cookie # 쿠키 기반 토큰 갱신
POST /api/auth/logout          # 로그아웃

회원 관리 API

=== 일반 회원용 ===
POST /api/members/signup       # 회원 가입
GET  /api/members/me           # 내 정보 조회
PUT  /api/members/me           # 내 정보 수정
PATCH /api/members/me/password # 비밀번호 변경
DELETE /api/members/me         # 회원 탈퇴

=== 관리자용 ===
GET  /api/admin/members              # 회원 목록 조회
GET  /api/admin/members/{id}         # 회원 상세 조회
PATCH /api/admin/members/{id}/status # 회원 상태 변경

수업 관리 API

=== 공통 ===
GET  /api/lessons              # 수업 목록 조회
GET  /api/lessons/{id}         # 수업 상세 조회
GET  /api/lessons/reservable   # 예약 가능한 수업 조회
GET  /api/lessons/date         # 특정 날짜 수업 조회

=== 관리자용 ===
POST /api/admin/lessons                # 수업 생성
PUT  /api/admin/lessons/{id}           # 수업 정보 수정
DELETE /api/admin/lessons/{id}         # 수업 삭제(취소)
PATCH /api/admin/lessons/{id}/capacity # 수업 정원 증가

예약 관리 API (CQRS 적용)

Command API (상태 변경)

POST /api/reservations                 # 예약 생성
DELETE /api/reservations/{id}          # 예약 취소

Query API (조회)

=== 개인 예약 조회 ===
GET /api/reservations/my                 # 내 예약 목록
GET /api/reservations/my/status          # 상태별 내 예약
GET /api/reservations/my/active          # 취소 가능한 내 예약
GET /api/reservations/my/date-range      # 기간별 내 예약
GET /api/reservations/my/today           # 오늘 확정된 내 예약
GET /api/reservations/my/checkin-eligible # 체크인 가능한 예약
GET /api/reservations/my/waiting-position/{lessonId} # 내 대기 순번

=== 수업별 예약 조회 (관리자) ===
GET /api/admin/reservations/{id}               # 예약 상세
GET /api/admin/reservations/lessons/{id}       # 수업별 예약 목록
GET /api/admin/reservations/lessons/{id}/waiting # 수업별 대기열
GET /api/admin/reservations/lessons/{id}/confirmed # 수업별 확정 예약
GET /api/admin/reservations/date               # 특정 날짜 모든 예약

체크인 API

POST /api/checkins                       # 체크인 처리
GET  /api/checkins/my                    # 내 체크인 현황
GET  /api/admin/checkins/lessons/{id}          # 수업별 체크인 현황 (관리자)
GET  /api/admin/checkins/reservations/{id}     # 예약별 체크인 조회 (관리자)

고급 기능

멱등성 보장

  • HTTP 헤더: X-Idempotency-Key 기반 중복 요청 처리
  • 캐시 저장: Redis 30초 TTL로 응답 캐싱
  • 자동 반환: 동일 키 요청 시 이전 응답 반환

에러 처리

  • 구조화된 응답: 일관된 에러 포맷 제공
  • 비즈니스 예외: 도메인별 명확한 에러 메시지
  • Fallback 처리: Redis 장애 시 DB 기반 서비스 유지

보안

  • JWT 인증: 액세스/리프레시 토큰 기반
  • 역할 기반 접근 제어: 일반 회원/관리자 권한 분리
  • 환경별 보안 설정: 개발/운영 환경 차별화

문서

상세한 설계 및 구현 내용은 다음 문서를 참고하세요:


확장 계획

관리자 도메인

  • 관리자 별 권한제어

배치 처리

  • 수업 상태 자동 변경 (시작/종료 시간 기준)
  • 체크인 리마인더 알림
  • 캐시 정합성 정기 점검

알림 시스템

  • 실시간 알림 (Server-Sent Events)
  • 예약 확정/취소/승격 알림
  • 수업 리마인더 알림

모니터링

  • 비즈니스 메트릭 수집
  • 성능 지표 모니터링
  • 알림 및 대시보드 구축

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors