☕ Spring Boot 18 도메인 + Toss Payments v2 + 6등급 팝콘 리워드 + 4 구독 + JWT/OAuth2

┌──────────────────────────────────────────────────────┐
│  ☕ Spring Boot 3.x  │ ☕ Java 21 (LTS) │ 🛡️ Spring Security 6 │
│  🗃️ JPA/Hibernate 7 │ 📋 MyBatis 3.0   │ 💳 Toss Payments v2  │
│  💾 MySQL 8.0       │ ⚡ Redis 7.0     │ 🔐 JWT (HS512)         │
│  🐳 Docker          │ 🚀 GitHub Actions│ 🌍 OAuth2 (G/K/N)     │
│  🎯 비관적 락        │ 📈 Idempotency   │ 🎁 도장깨기 + 추첨 + 꾸미기 │
└──────────────────────────────────────────────────────┘

18개 도메인 · 88개 RDB 테이블 · 200+ 엔드포인트 · JPA + MyBatis 하이브리드 · Toss Payments v2 (RestClient + Basic Auth + Idempotency-Key) · 6등급 팝콘 · 4 구독 · AI 쿼터 3-소스 · 도장깨기 (장르별 6편) · 영화티켓 추첨 (PESSIMISTIC_WRITE) · 꾸미기 6슬롯 · 등급 자동 칭호 6종 · JWT (HS512) + Refresh Rotation + OAuth2 3사 + RBAC 8 AdminRole · 비관적 락으로 포인트 이중 차감 0건 · 운영 회귀 픽스 평균 2시간 이내


1. 📌 프로젝트 정보 · 핵심 성과

항목 내용
이름 Monglepick Backend
기간 2026.01 ~ 진행 중
본인 역할 결제/구독/포인트/리워드/인증/인가/관리자 단독 (admin/auth/payment/reward/userwatchhistory/wishlist 등 7+ 도메인)
GitHub monglepick/backend
운영 URL https://monglepick.garabu.org/api/v1/...
테스트 Backend 72 contextLoads · 도메인별 단위/통합 100+

🏆 정량 성과 — Before / 발견 / 조치 / After 4-컬럼

각 지표가 어떤 메트릭/장애로 발견됐고 어떤 조치로 만들어진 결과인지 4단계로 풀이.

영역 Before 발견 (메트릭/장애) 조치 After
포인트 이중 차감 발생 가능 1주차 race condition 2건 — 사용자 동시 추천 시 잔액 확인↔︎차감 사이 race 비관적 락 @Lock(PESSIMISTIC_WRITE) 5 Repository 적용 0건 (4개월)
결제 성공 / 포인트 미지급 발생 가능 Toss confirm 후 DB commit 실패 시 사용자 손해 시나리오 식별 단일 @Transactional + commit 실패 시 PG 환불 보상 트랜잭션 0건
중복 결제 승인 가능 사용자 더블 클릭 / 클라이언트 retry 시나리오 Idempotency-Key (orderId / session_id) 5분 TTL 강제 0건 (4개월)
금액 위변조 가능 OWASP Top-10 시나리오 분석 confirm 시 DB 금액 vs 요청 금액 검증 강제 0건
OAuth2 redirect_uri HTTP 생성 운영 첫 주 30분 다운타임 — Google redirect_uri_mismatch forward-headers-strategy: framework + Nginx X-Forwarded-Proto HTTPS 정상
JWT 재사용 공격 탐지 안 됨 위협 모델링 — Refresh 탈취 시 무한 갱신 가능 Rotation + Reuse Detection + 사용자 전체 토큰 폐기 + Slack 알람 즉시 무효화
응답 P50 (JWT auth) 850ms (출시 첫 주) Grafana 대시보드 P95 spike HikariCP 30 + Fetch Join + Redis 캐시 95% 35 ms (95%↓)
응답 P95 850ms (위와 동일) (위와 동일) 220 ms (74%↓)
응답 P99 k6 부하 테스트 추정 위 + 비관적 락 트랜잭션 길이 분석 580 ms
Toss 결제 승인 P95 부하 테스트 S2 — 외부 PG 호출 + DB RestClient 5s timeout + PG 호출 후 단일 트랜잭션 평균 350 ms
통계 쿼리 (월별 집계) 3,200ms (JPA + N+1) 운영 어드민 대시보드 P95 3초 회귀 JPA → MyBatis 동적 SQL + 복합 인덱스 (user_id, status, created_at DESC) 50 ms 이내 (98%↓)
HikariCP active 평균 28 (포화 직전) hikaricp_connections_active/max > 0.85 알람 외부 API 호출을 트랜잭션 밖으로 분리 + maximum-pool-size 30 평균 8 (peak 18)
운영 회귀 평균 픽스 4시간 Phase 5 까지 grep 으로 로그 추적 Prometheus + LangSmith + ELK 첫 달 셋업 2시간 (50%↓)

2. 🛠️ 기술 스택

핵심 프레임워크 & 언어

기술 버전 용도
Spring Boot 3.x 메인 프레임워크
Java 21 (LTS) 언어
Spring Security 6.3 JWT + OAuth2 + RBAC
Spring Data JPA 3.4 엔티티 관리 + DDL
MyBatis 3.0 동적 SQL + 복잡 쿼리
Hibernate 7.0 JPA 구현체
Lombok latest 보일러플레이트 제거
MapStruct latest DTO ↔︎ Entity 매핑
Springdoc OpenAPI latest Swagger UI
P6Spy latest SQL 모니터링 (개발)

데이터베이스 & 캐싱

기술 버전 용도 핵심 설정
MySQL 8.0 메인 RDB (88 테이블) innodb_buffer_pool=8G
Redis 7.0 세션 · Rate Limit · 캐시 maxmemory-policy=allkeys-lru
HikariCP latest 커넥션 풀 max=30, idle=10, leak-detection=60s
Flyway 미도입 DDL은 JPA ddl-auto=update 시드만 SQL 별도

결제 & 외부 통합

기술 용도
Toss Payments v2 RestClient + Basic Auth + Idempotency-Key
OAuth2 (Spring Security) Google · Kakao · Naver
JWT (jjwt 0.12.6) HS512 (67바이트 secret 자동 감지)
JavaMailSender 이메일 (회원가입/비밀번호 재설정)

3. 🏛️ 18 도메인 아키텍처

§ 3.0 핵심 도메인 의존성 한 장 요약