diff --git a/README.md b/README.md index b2e21080..f299a223 100644 --- a/README.md +++ b/README.md @@ -1,54 +1,163 @@ -# WEB7_9_B2ST_BE -> **TT(Ticket & Trade)** — 공연 예매(대기열/좌석 선점/추첨·신청 예매)와 교환·양도(거래), 결제 흐름을 지원하는 백엔드 서버입니다. +# TT (Ticket & Trade) - Backend -## 🎯 프로젝트 소개 -image +> 공연 예매(대기열/좌석 선점/추첨·신청 예매)와 티켓 거래(교환/양도), 결제 흐름을 지원하는 Spring Boot 기반 백엔드 서버 -(작성) +

+ Java 21 + Spring Boot 4.0.0 + PostgreSQL + Redis Cluster + Docker +

-## 👥 팀 구성 & 링크 -- 팀 구성: (작성) -- 배포 링크: https://doncrytt.vercel.app/ -- Frontend Github: https://github.com/prgrms-web-devcourse-final-project/WEB7_9_B2ST_FE -- Backend Github: https://github.com/prgrms-web-devcourse-final-project/WEB7_9_B2ST_BE +## 📋 목차 +- [프로젝트 개요](#-프로젝트-개요) +- [팀 구성](#-팀-구성) +- [링크](#-링크) +- [핵심 기능](#️-핵심-기능) +- [기술 스택](#️-기술-스택) +- [시스템 아키텍처](#️-시스템-아키텍처) +- [ERD](#️-erd) +- [프로젝트 구조](#-프로젝트-구조) +- [모니터링 구성](#-모니터링-구성) +- [협업 규칙](#-협업-규칙) -## ⚙️ 핵심 기능 +--- + +## 🎯 프로젝트 개요 + +**TT(Ticket & Trade)** 는 공연 티켓 예매 및 2차 거래(교환/양도) 플랫폼의 백엔드 서버입니다. -### 🎫 공연/회차 -- 공연 생성/조회(관리자/사용자 분리) -- 회차(공연 일정) 생성 및 조회 -- 좌석 등급/가격 정책 관리 +### 개발 기간 -### ⏳ 대기열 -- 예매 트래픽 집중 상황에서 대기열 기반 접근 제어 -- Redis 기반 상태 관리(환경 설정으로 on/off 가능) +- 2024.12.03 ~ 2025.01.12 -### 🪑 좌석 선점/예매 -- 좌석 선점(HOLD) → 예매 확정(SOLD) 흐름 -- 선점 만료/실패 처리로 좌석 상태 복구 +### 주요 도메인 -### 🎲 추첨 예매 -- 추첨 응모 생성 및 내 응모 내역 조회 -- 추첨 결과 처리 및 좌석 배정 흐름 지원 +| 도메인 | 설명 | +|:------------|:---------------------------------------| +| **대기열** | Redis 기반 트래픽 분산, 순차 접근 제어 | +| **좌석 예매** | 좌석 선점(HOLD → SOLD), 만료 자동 복구 | +| **추첨 예매** | 등급별 응모, 공정 추첨, 당첨 알림 | +| **사전신청 예매** | 오픈/마감 정책 기반 신청 처리 | +| **거래** | 티켓 소유권 검증, 교환·양도 흐름 | +| **결제** | 도메인별 결제 흐름 분리, 상태 관리 | +| **인증** | JWT + Refresh Token Rotation, 카카오 OIDC | -### 📝 신청 예매(사전신청) -- 신청 예매 오픈/마감 정책 -- 신청/예약 생성 및 만료 처리 +--- -### 💳 결제 -- 도메인별 결제 흐름 분리(예매/신청/추첨/거래) -- 결제 상태 관리 및 후처리 구조 +## 👥 팀 구성 -### 🔁 교환·양도(거래) -- 거래 등록/조회 -- 거래 요청/승인 흐름 -- 티켓 상태와 소유권 검증 +| 이름 | 역할 | GitHub | +|:--------------:|:-------:|:----------------------------------------------------------------------------------------------------------------------------------:| +| whyin | Backend | [![GitHub](https://img.shields.io/badge/-whyin-181717?logo=github&logoColor=white)](https://github.com/whyin) | +| Chehyeon-Kim23 | Backend | [![GitHub](https://img.shields.io/badge/-Chehyeon--Kim23-181717?logo=github&logoColor=white)](https://github.com/Chehyeon-Kim23) | +| Nomi | Backend | [![GitHub](https://img.shields.io/badge/-77r77r-181717?logo=github&logoColor=white)](https://github.com/77r77r) | +| Minhyung Park | Backend | [![GitHub](https://img.shields.io/badge/-minibr-181717?logo=github&logoColor=white)](https://github.com/minibr) | +| WeeRim | Backend | [![GitHub](https://img.shields.io/badge/-weilim0513--tech-181717?logo=github&logoColor=white)](https://github.com/weilim0513-tech) | -### 🧑‍💼 관리자 -- 관리자 전용 API(`/api/admin/**`) 권한 분리 -- 공연/예매/거래 운영 지원 기능 +--- +## 🔗 링크 + +| 구분 | 링크 | +|:-----------:|:--------------------------------------------------------------------------------------:| +| 🌐 배포 | [https://doncrytt.vercel.app](https://doncrytt.vercel.app/) | +| 💻 Frontend | [WEB7_9_B2ST_FE](https://github.com/prgrms-web-devcourse-final-project/WEB7_9_B2ST_FE) | +| 🔧 Backend | [WEB7_9_B2ST_BE](https://github.com/prgrms-web-devcourse-final-project/WEB7_9_B2ST_BE) | +| 📖 API 문서 | [Swagger UI](http://15.165.115.135:8080/swagger-ui/index.html#/) | + +--- + +## ⚙️ 핵심 기능 + +### 🔐 인증/인가 (Auth) + +| 기능 | 구현 상세 | +|:---------------|:-----------------------------------------------------------------------| +| JWT 인증 | Access Token(30분) + Refresh Token(7일, Redis 저장) | +| Token Rotation | 재발급 시 Family/Generation 기반 탈취 감지, 이전 토큰 사용 시 전체 세션 무효화 | +| 카카오 OIDC | ID Token RSA 서명 검증(JWKS 24시간 캐싱), nonce 1회성 검증, 자동 계정 연동 | +| 로그인 보안 | 5회 실패 시 10분 잠금(Redis TTL), Lua Script 원자적 카운팅 | +| 위협 탐지 | Credential Stuffing(IP당 10+ 계정), Brute Force(IP당 50+ 실패) 탐지 → Slack 알림 | + +### 👤 회원 (Member) + +| 기능 | 구현 상세 | +|:-------|:--------------------------------------------------| +| 회원가입 | BCrypt 암호화, IP별 Rate Limiting(시간당 3회, Lua Script) | +| 이메일 인증 | SecureRandom 6자리 코드, Redis TTL 5분, 시도 횟수 제한(5회) | +| 탈퇴/복구 | Soft Delete + 30일 복구 유예, 복구 토큰(UUID, 24시간 TTL) | +| 감사 로그 | 로그인/가입 이벤트 비동기 저장(@Async + REQUIRES_NEW) | + +### ⏳ 대기열 (Queue) + +| 기능 | 구현 상세 | +|:-------|:---------------------------------------| +| 대기열 진입 | Redis Sorted Set 기반, 타임스탬프 스코어로 순서 보장 | +| 순번 조회 | ZRANK 명령으로 실시간 대기 순번 반환 | +| 입장 처리 | 순차적 입장 토큰 발급, 유효 시간 제한 | +| 상태 관리 | WAITING → PROCESSING → COMPLETED 상태 전이 | +| 환경 설정 | 대기열 on/off 설정 가능, 트래픽 상황에 따라 유연하게 적용 | + +### 🪑 좌석 예매 (Reservation) + +| 기능 | 구현 상세 | +|:------|:-------------------------------------------| +| 좌석 선점 | AVAILABLE → HOLD 상태 전이, 5분 TTL 설정 | +| 중복 방지 | 동일 좌석 동시 선점 시도 시 낙관적 락으로 충돌 감지 | +| 예매 확정 | 결제 완료 시 HOLD → SOLD 상태 전이 | +| 선점 만료 | 스케줄러 기반 TTL 만료 좌석 자동 복구 (HOLD → AVAILABLE) | +| 예매 취소 | 예매 취소 시 좌석 상태 원복, 환불 처리 연동 | + +### 🎲 추첨 예매 (Lottery) + +| 기능 | 구현 상세 | +|:-------|:---------------------------| +| 응모 등록 | 회차/등급별 응모, 중복 응모 검증 | +| 응모 제한 | 1인당 등급별 최대 응모 수량 제한 | +| 추첨 처리 | SecureRandom 기반 공정 추첨 알고리즘 | +| 당첨 처리 | 당첨자 좌석 자동 배정, 결제 기한 설정 | +| 결과 알림 | 당첨/낙첨 이메일 비동기 발송 | +| 미결제 처리 | 결제 기한 초과 시 자동 당첨 취소, 좌석 반환 | + +### 📝 사전신청 예매 (Pre-Reservation) + +| 기능 | 구현 상세 | +|:------|:------------------------| +| 신청 기간 | 오픈/마감 일시 기반 신청 가능 기간 검증 | +| 신청 등록 | 회차/등급별 사전신청, 수량 지정 | +| 신청 확정 | 신청 → 결제 대기 → 결제 완료 흐름 | +| 만료 처리 | 결제 기한 초과 시 신청 자동 만료 | +| 신청 취소 | 사용자 요청에 의한 신청 취소 처리 | + +### 💳 결제 (Payment) + +| 기능 | 구현 상세 | +|:--------|:--------------------------------------------------| +| 도메인별 분리 | 좌석예매/추첨/사전신청/거래 각각 독립된 결제 흐름 | +| 상태 관리 | PENDING → PROCESSING → COMPLETED/FAILED/CANCELLED | +| 환불 계좌 | 계좌번호 마스킹 저장, BankCode Enum 매핑 | + +### 🔁 거래 (Trade) + +| 기능 | 구현 상세 | +|:-------|:-----------------------| +| 거래 등록 | 티켓 소유권 검증, 중복 등록 방지 | +| 거래 요청 | 구매자 거래 요청, 판매자 승인 대기 | +| 거래 승인 | 판매자 승인 시 결제 프로세스 진입 | +| 소유권 이전 | 결제 완료 시 티켓 소유권 구매자로 변경 | + +### 🧑‍💼 관리자 (Admin) + +| 기능 | 구현 상세 | +|:------|:------------------------------------------------| +| 회원 관리 | 검색/필터링/페이징, 대시보드 통계 | +| 인증 관리 | 로그인/가입 로그 조회, 계정 잠금 해제 | +| 권한 분리 | `/api/admin/**` URL 레벨 + `@PreAuthorize` 메서드 레벨 | + +--- ## 🛠️ 기술 스택 @@ -60,6 +169,7 @@ ![QueryDSL](https://img.shields.io/badge/QueryDSL-000000?style=for-the-badge) ![Gradle](https://img.shields.io/badge/Gradle-02303A?logo=gradle&logoColor=white&style=for-the-badge) ![Swagger](https://img.shields.io/badge/Swagger-85EA2D?logo=swagger&logoColor=black&style=for-the-badge) + ### \ ![PostgreSQL](https://img.shields.io/badge/PostgreSQL-4169E1?logo=postgresql&logoColor=white&style=for-the-badge) ![H2 Database](https://img.shields.io/badge/H2%20Database-1A73E8?logo=h2database&logoColor=white&style=for-the-badge) @@ -88,24 +198,162 @@ ![Testcontainers](https://img.shields.io/badge/Testcontainers-000000?logo=testcontainers&logoColor=white&style=for-the-badge) ![JUnit](https://img.shields.io/badge/JUnit-25A162?logo=junit5&logoColor=white&style=for-the-badge) -## 🏗️ 아키텍처 -(작성) +--- + +## 🏗️ 시스템 아키텍처 + +Image + +--- ## 🗂️ ERD -(작성) -## 🎬 시연 영상 -(작성) +![Image](https://github.com/user-attachments/assets/3c393c6a-5186-444d-80fc-b69c17f406c1) + +--- + +## 📁 프로젝트 구조 + +
+펼쳐보기 + +``` +src/main/java/com/back/b2st/ +├── domain/ +│ ├── auth/ # JWT, OAuth, 로그인 보안, 토큰 관리 +│ │ ├── client/ # KakaoApiClient, KakaoJwksClient +│ │ ├── controller/ # AuthController, AuthAdminController +│ │ ├── service/ # AuthService, LoginSecurityService, SecurityThreatDetectionService +│ │ ├── entity/ # RefreshToken(Redis), LoginLog, OAuthNonce +│ │ ├── listener/ # LoginEventListener (비동기 로그 저장) +│ │ └── metrics/ # AuthMetrics, SecurityMetrics +│ │ +│ ├── member/ # 회원 CRUD, 탈퇴/복구, Rate Limiting +│ ├── email/ # 이메일 인증, 비동기 발송 +│ ├── performance/ # 공연 관리 +│ ├── performanceschedule/# 공연 회차 +│ ├── seat/ # 좌석 관리 +│ ├── scheduleseat/ # 회차별 좌석 상태 +│ ├── queue/ # 대기열 시스템 +│ ├── reservation/ # 좌석 예매 +│ ├── prereservation/ # 사전 신청 +│ ├── lottery/ # 추첨 예매 +│ ├── payment/ # 결제 +│ ├── ticket/ # 티켓 관리 +│ ├── trade/ # 거래 (교환/양도) +│ ├── venue/ # 공연장 +│ └── bank/ # 은행 코드 Enum +│ +├── global/ +│ ├── alert/ # SlackAlertService (Webhook 연동) +│ ├── config/ # Redis, S3, Redisson, Alert 설정 +│ ├── error/ # GlobalExceptionHandler, ErrorCode +│ ├── jwt/ # JwtTokenProvider, JwtAuthenticationFilter +│ ├── jpa/ # BaseEntity, QueryDslConfig, AuditorAware +│ ├── s3/ # S3Service, PresignedUrl +│ ├── util/ # MaskingUtil, CookieUtils, SecurityUtils +│ └── metrics/ # MetricsConfig +│ +└── security/ # Spring Security 설정 + ├── SecurityConfig.java + ├── CustomUserDetails.java + ├── CustomUserDetailsService.java + ├── JwtAuthenticationEntryPoint.java + └── JwtAccessDeniedHandler.java + +docker/ +├── docker-compose.yml # 전체 스택 (App, DB, Redis Cluster, Monitoring) +├── monitoring/ +│ ├── prometheus/ +│ │ ├── prometheus.yml +│ │ └── rules/auth-alerts.yml +│ ├── grafana/ +│ │ ├── provisioning/ +│ │ └── dashboards/ +│ └── alertmanager/ +│ └── alertmanager.yml +└── init-*.sh # Redis Cluster 초기화 스크립트 +``` + +
+ +--- + +## 📊 모니터링 구성 + +
+Grafana 대시보드 + +| 계층 | 대시보드 | 주요 메트릭 | +|:------------|:-------------------------|:----------------------------------------------------------------------------| +| **Service** | tt-service-overview | 요청 수, 에러율, 응답 시간 분포 | +| **Domain** | tt-auth-dashboard | `auth_login_total`, `auth_account_locked_total`, `auth_token_reissue_total` | +| | tt-email-dashboard | `email_sent_total`, `email_verification_total` | +| | tt-queue-dashboard | 대기열 상태, 처리량 | +| | tt-reservation-dashboard | 예매 생성, 좌석 선점/취소 | +| | tt-lottery-dashboard | 응모 수, 당첨 처리 | +| | tt-payment-dashboard | 결제 요청/완료/실패 | +| | tt-trade-dashboard | 거래 등록/완료 | +| **Infra** | tt-jvm-dashboard | 힙 메모리, GC, 스레드 풀 | +| | tt-database-dashboard | 커넥션 풀, 쿼리 성능 | +| | tt-redis-dashboard | 메모리, 커맨드/sec, 키 상태 | + +
+ +
+Alertmanager 규칙 + +```yaml +// 예시 +groups: + - name: auth-alerts + rules: + - alert: HighLoginFailureRate + expr: rate(auth_login_total{result="failure"}[5m]) > 0.1 + for: 2m + labels: + severity: warning + annotations: + summary: "로그인 실패율 증가" + + - alert: AccountLockDetected + expr: increase(auth_account_locked_total[5m]) > 0 + labels: + severity: critical + annotations: + summary: "계정 잠금 발생" +``` + +
+ +--- + ## 🧩 협업 규칙 -### 💬 코드 컨벤션 +
+펼쳐보기 + +### 코드 컨벤션 + - **Naver Java Convention** 기반 -- **기본 원칙** - - 가독성 최우선 - - 특별한 이유가 없는 경우 **IntelliJ IDEA 자동 서식** 준수 +- IntelliJ IDEA 자동 서식 준수 + +### Git 브랜치 전략 + +- `main`: 프로덕션 +- `develop`: 개발 통합 +- `feature/*`: 기능 개발 +- 머지 조건: 최소 1명 리뷰 승인 + +
+ +--- ### 🏷️ 네이밍 & 작성 규칙 +
+펼쳐보기 + #### 이슈(Issue) - **제목 규칙**: `[타입] 작업내용` - 예시: `[feat] 로그인 기능 추가` @@ -134,6 +382,8 @@ | `refactor` | 코드 리팩토링(동작 변화 없음) | | `test` | 테스트 코드 추가/수정 | +
+## 📄 라이선스 - +프로그래머스 K-Digital Training 파이널 프로젝트