01
Nextour
AI가 찾아주는 맞춤형 패키지 여행 예약 플랫폼
측정
ADR
61건
0001–0061, 결번 없음
테스트
1,324건
165개 파일 · 2026.08 기준
구조
결제
2-phase
좌석 선점 → PG 승인 → DB 확정
환불
3-phase saga
외부 IO를 DB 트랜잭션 밖으로 격리
멱등성
3중
Idempotency-Key · RefundJob 게이트 · providerEventId
아키텍처
FSD 5-레이어
app · widgets 13 · features 20 · entities 10 · shared
성능 계측
자체 RUM
Web Vitals p75 · PostgreSQL percentile_cont
화면
검색 — AI 자연어 하이브리드 랭킹 결과 상품 상세(PDP) — 일정·출발일·실시간 좌석 체크아웃 — 2-phase 결제 플로우 관리자 대시보드 — 매출·점유율·취소율
아키텍처
트러블슈팅
외부 PG 호출을 DB 트랜잭션 밖으로
- Situation
- 환불은 자사 DB와 외부 PG(토스)에 걸친 분산 트랜잭션입니다. PG 호출과 DB 갱신이 한 트랜잭션 안에 있으면, PG는 성공했는데 DB 커밋이 실패하는 순간 고객 돈은 나갔지만 시스템은 환불을 모르는 상태가 됩니다.
- Cause
- 외부 네트워크 호출이 트랜잭션 안에 있으면 두 가지가 동시에 문제가 됩니다. PG 응답을 기다리는 수 초 동안 DB 락이 유지되고, 실패 지점에 따라 결과가 갈립니다.
- Solution
- Phase를 셋으로 쪼갰습니다. Phase 1(DB Tx)에서 멱등 게이트를 통과시키고 원장을 조건부 차감해 예약합니다. Phase 2는 트랜잭션 밖에서 PG를 호출합니다. Phase 3(DB Tx)에서 정산하고 이벤트를 적재합니다. PG 호출이 실패하면 RefundJob을 PENDING으로 적재하고 지수 백오프로 cron worker가 재시도합니다. 그동안에도 예약 상태는 무결성을 유지합니다.
- Outcome
- 락 윈도우가 마이크로초 단위로 줄었고, PG 실패가 데이터 불일치로 이어지지 않습니다. 3중 멱등성으로 이중 환불도 차단됩니다. (ADR-0003)
기술 스택
- Next.js 16 (App Router)
- TypeScript
- PostgreSQL + pgvector
- Prisma ORM
- Anthropic Claude API
- Auth.js v5
- 토스페이먼츠
- Vercel