사용자와 트레이너를 연결하는 PT 매칭 플랫폼
PTMatch는 사용자(회원)와 트레이너 간 PT 매칭을 중개하는 플랫폼입니다. 사용자는 지도 기반 검색으로 근처 트레이너를 탐색하고, 원하는 일정을 선택해 매칭을 신청할 수 있습니다.
핵심 기능 요약
- 지도 기반 트레이너 탐색 (PostGIS + S2 Geometry 공간 쿼리)
- 트레이너-사용자 매칭 요청 및 수락/거절
- 매칭 수락 후 WebSocket 1:1 채팅
- Toss Payments 연동 결제
- Spring Batch 기반 트레이너 월별 통계 집계
- Prometheus + Grafana + Loki + Tempo 모니터링 스택
| 분류 | 기술 |
|---|---|
| Language / Runtime | Java 17 |
| Framework | Spring Boot 3.5 |
| ORM | Spring Data JPA (Hibernate) |
| Security | Spring Security, JWT (jjwt 0.11) |
| Real-time | Spring WebSocket + STOMP |
| Batch | Spring Batch |
| Cache | Redis, Caffeine |
| Storage | MinIO (S3 호환) |
| API Docs | SpringDoc OpenAPI (Swagger UI) |
| Retry | Spring Retry |
| 분류 | 기술 |
|---|---|
| RDBMS | PostgreSQL + PostGIS |
| 공간 인덱싱 | S2 Geometry Library |
| Cache | Redis |
| 분류 | 기술 |
|---|---|
| Container | Docker, Docker Compose |
| Web Server | Nginx (Reverse Proxy + SSL) |
| DNS | Cloudflare |
| CI/CD | GitHub Actions |
| Monitoring | Prometheus, Grafana, Loki, Tempo, OpenTelemetry |
flowchart LR
subgraph Client
U[사용자 / 트레이너 브라우저]
end
subgraph Infra
CF[Cloudflare DNS]
N[Nginx]
end
subgraph App[Spring Boot]
A[PTMatch API]
end
subgraph Storage
DB[(PostgreSQL + PostGIS)]
RD[(Redis)]
MN[(MinIO)]
end
subgraph Monitoring
PR[Prometheus]
GR[Grafana]
LK[Loki]
TP[Tempo]
OT[OpenTelemetry Collector]
end
U -- HTTPS / WSS --> CF
CF --> N
N --> A
A --> DB
A --> RD
A --> MN
A --> PR
A --> LK
A --> OT
OT --> TP
PR --> GR
LK --> GR
TP --> GR
💳 결제
- Toss Payments 위젯 연동 (prepare → confirm 2단계)
- 금액 위변조 방지 이중 검증 (DB 저장 금액 vs Toss 응답 금액)
- 상태 기반 보상 트랜잭션 (결제 실패 시 스케줄/매칭 롤백)
- 재조정 스케줄러 (UNKNOWN 상태 주문 자동 재조회)
- 만료 스케줄러 (TTL 초과 주문 자동 EXPIRED 처리)
🔐 인증 / 인가
- JWT Access Token + Refresh Token 토큰 방식
- Refresh Token은 Redis에 저장하여 TTL 기반 자동 만료
- Spring Security 기반 ROLE_USER / ROLE_TRAINER 권한 분리
💬 채팅
- WebSocket + STOMP 프로토콜 실시간 메시지 송수신
- Redis Pub/Sub 기반 멀티 인스턴스 fan-out 지원
PT_Match/
├── src/main/java/com/solo/ptmatch/
│ ├── chat/ # 채팅 (WebSocket, 메시지, 채팅방)
│ ├── common/ # 공통 (설정, 예외, 응답 포맷, 보안)
│ ├── location/ # 위치 (행정구역 데이터)
│ ├── matching/ # 매칭 (요청, 수락, 스케줄)
│ ├── payment/ # 결제 (Toss 연동, 보상 트랜잭션, 스케줄러)
│ │ ├── presentation/ # PaymentController, request/response DTO
│ │ ├── application/ # PaymentPrepareService, PaymentConfirmService, PaymentConfirmTxService
│ │ ├── domain/ # PaymentOrder, PaymentStatus, PaymentProvider
│ │ ├── infrastructure/ # PaymentOrderRepository, Toss API 클라이언트, 설정
│ │ └── scheduler/ # PaymentReconcileScheduler, PaymentExpireScheduler
│ ├── review/ # 리뷰
│ ├── statistics/ # 통계 (Spring Batch)
│ ├── trainer/ # 트레이너 프로필, 지도 검색
│ └── user/ # 사용자, 인증 (JWT)
│
├── frontend/ # React + TypeScript + Vite
└── docker-compose.yml
Swagger UI에서 전체 API를 확인할 수 있습니다.









