수업 예약/대기/체크인 시스템
# Docker 환경 시작
chmod +x docker-commands.sh
./docker-commands.sh up
# 또는 수동으로
docker-compose up -d./gradlew bootRun- API Documentation: http://localhost:8080/swagger-ui.html
모든 계정 비밀번호: 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 |
- 이메일: 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
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 패턴 적용으로 확장성과 성능 최적화:
- 역할: 예약 생성, 취소, 대기열 승격 등 상태 변경 작업
- 트랜잭션: 쓰기 트랜잭션 (
@Transactional) - 동시성 제어: Redis 분산락으로 데이터 일관성 보장
- 이벤트 발행: 도메인 이벤트를 통한 부가 작업 처리
- 역할: 예약 목록, 대기열, 통계 등 다양한 조회 작업
- 트랜잭션: 읽기 전용 (
@Transactional(readOnly = true)) - 성능 최적화: Redis 캐시 우선 조회, N+1 문제 해결
- 확장성: 조회 전용 최적화 및 독립적 스케일링 가능
- MySQL: localhost:3307/lesson_rsvn (lesson_rsvn/lesson_rsvn)
- Redis: localhost:6380 (password: redispw)
./docker-commands.sh up # 환경 시작
./docker-commands.sh down # 환경 종료
./docker-commands.sh restart # 환경 재시작
./docker-commands.sh logs # 로그 확인
./docker-commands.sh status # 상태 확인
./docker-commands.sh clean # 데이터 삭제- 중복 예약 방지: 동일 회원의 동일 수업 중복 예약 차단
- 정원 관리: Redis 캐시 기반 실시간 정원 확인
- 상태 결정: 정원 여유 시 즉시 확정, 초과 시 대기열 등록
- 재예약 지원: 취소된 예약의 상태 변경을 통한 효율적 재예약
- 동시성 제어: Redis 분산락으로 안전한 취소/승격 처리
- 자동 승격: 확정 예약 취소 시 대기열 첫 번째 회원 자동 승급
- 순서 보장: Redis Sorted Set 기반 대기 순서 관리
- 상태 동기화: 캐시-DB 일관성 유지
- 자격 검증: 확정 예약 회원만 체크인 가능
- 시간 제한: 수업 시작 10분 전부터 종료까지만 허용
- 중복 방지: 동일 예약에 대한 중복 체크인 차단
- 수업 취소: 해당 수업의 모든 예약 자동 취소
- 정원 증가: 대기열에서 증가량만큼 자동 승급
- 회원 비활성화: 해당 회원의 모든 예약 자동 취소
- Redisson 활용: 안전한 분산 환경 동시성 제어
- 락 범위: 수업별 예약 생성/취소/승급 처리
- 설정 가능: 대기 시간 및 임대 시간 환경별 설정
- 대상: 수업별 확정 예약 수, 대기열 정보
- Self-healing: 캐시 미스 시 DB 기반 자동 복구
- TTL 관리: 수업 시작 시간에 자동 만료
- 정기 동기화: 스케줄러 기반 캐시-DB 일관성 유지
- 인덱스 전략: 쿼리 패턴 기반 복합 인덱스 설계
- N+1 해결: @EntityGraph 활용한 페치 조인
- 읽기 최적화: CQRS 패턴의 Query 서비스 분리
./gradlew test -Dspring.profiles.active=test./gradlew test --tests "*Integration*" -Dspring.profiles.active=testcontainers./gradlew test./gradlew jacocoTestReport
# build/reports/jacoco/test/html/index.html에서 확인- 단위 테스트: 도메인 엔티티, 서비스별 단위 테스트
- 통합 테스트: Redis, MySQL 포함한 실제 환경 테스트
- 동시성 테스트: 분산락 및 대기열 처리 검증
- 시스템 테스트: End-to-End 전체 플로우 검증
POST /api/auth/login # 로그인
POST /api/auth/refresh # 토큰 갱신
POST /api/auth/refresh-from-cookie # 쿠키 기반 토큰 갱신
POST /api/auth/logout # 로그아웃
=== 일반 회원용 ===
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 # 회원 상태 변경
=== 공통 ===
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 # 수업 정원 증가
POST /api/reservations # 예약 생성
DELETE /api/reservations/{id} # 예약 취소
=== 개인 예약 조회 ===
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 # 특정 날짜 모든 예약
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 인증: 액세스/리프레시 토큰 기반
- 역할 기반 접근 제어: 일반 회원/관리자 권한 분리
- 환경별 보안 설정: 개발/운영 환경 차별화
상세한 설계 및 구현 내용은 다음 문서를 참고하세요:
- 설계 결정 기록: 트랜잭션 경계, 동시성 제어, 일관성 모델, 에러 처리 등 핵심 설계 결정사항
- 도메인 설계: DDD 기반 도메인 모델 및 비즈니스 규칙 상세 설명
- 작업 로그: 프로젝트 개발 과정 및 주요 구현 내용 기록
- TODO 리스트: 구현 항목
- 관리자 별 권한제어
- 수업 상태 자동 변경 (시작/종료 시간 기준)
- 체크인 리마인더 알림
- 캐시 정합성 정기 점검
- 실시간 알림 (Server-Sent Events)
- 예약 확정/취소/승격 알림
- 수업 리마인더 알림
- 비즈니스 메트릭 수집
- 성능 지표 모니터링
- 알림 및 대시보드 구축