@@ -56,7 +56,7 @@ AWS 위에 **3-Tier Architecture** 기반으로 구성되어 있습니다.
5656
5757<br >
5858
59- <img width =" 1098 " height = " 722 " alt = " image " src =" https://github.com/user-attachments/assets/bfa6f77b-7c61-4acd-a8c1-5dcc8afa897d " />
59+ <img width =" 1098 " alt = " 3-Tier Architecture " src =" docs/img.png " />
6060
6161<br >
6262
@@ -72,6 +72,62 @@ AWS 위에 **3-Tier Architecture** 기반으로 구성되어 있습니다.
7272
7373<br >
7474
75+ ### 아키텍처 최적화 — VPC Endpoint 도입
76+
77+ 기존에는 S3 접근 트래픽이 ** NAT Gateway → 인터넷** 을 거쳐 나갔지만, 이 경로를 ** VPC Endpoint** 로 전환했습니다.<br >
78+ AWS 내부망으로 S3에 직접 연결되도록 하여 ** 보안·비용·속도** 를 동시에 개선했습니다.
79+
80+ <img width =" 1098 " alt =" Architecture Optimization " src =" docs/img_1.png " />
81+
82+ <br >
83+
84+ ### 검증 — 아웃바운드 트래픽 출구 확인
85+
86+ 설계 검토 과정에서 ** 설계와 실제 설정의 불일치** 를 발견하고, AWS 콘솔로 직접 검증했습니다.<br >
87+ NAT Gateway는 ** Public Subnet에 속한 리소스** 이므로, 자신이 속한 서브넷의 라우팅 테이블(` NailAgent-public-rt ` )을 따라갑니다.<br >
88+ 즉, 아웃바운드 트래픽의 ** 최종 출구는 NAT이 아닌 IGW(Internet Gateway)** 임을 콘솔 검증을 통해 확인했습니다.
89+
90+ <img width =" 1098 " alt =" Verification " src =" docs/img_2.png " />
91+
92+ <br >
93+
94+ ---
95+
96+ ## 트러블슈팅
97+
98+ ### 💳 결제 실패 — ` RESERVATION_NOT_FOUND ` (ORDERID 중복)
99+
100+ ** 문제 상황** <br >
101+ 결제 시 ` RESERVATION_NOT_FOUND ` 가 발생했습니다. 결제창 인증은 통과했지만 서버에서 예약을 찾지 못해 결제 승인에 실패했습니다.
102+
103+ ** 근본 원인 — DB 초기화 후 ORDERID 중복** <br >
104+ 개발 중 테스트 목적으로 DB를 직접 초기화하면 우리 쪽 ` AUTO_INCREMENT ` 는 1로 리셋되지만, ** Toss는 이미 처리한 ORDERID를 기억** 하고 있습니다.<br >
105+ 같은 ORDERID로 재요청 시 Toss가 이를 거절하거나 이전 예약과 매핑 오류가 발생했습니다.
106+
107+ ** 해결 방법 — ORDERID에 타임스탬프 추가** <br >
108+ ORDERID를 ` booking_{id}_{timestamp} ` 형식으로 변경하여, DB가 초기화되더라도 타임스탬프가 달라 ** 항상 유일한 ORDERID를 보장** 하도록 했습니다.
109+
110+ <img width =" 1098 " alt =" Troubleshooting - Payment ORDERID " src =" docs/img_3.png " />
111+
112+ <br >
113+
114+ ### 🗂️ DB 스키마 설계 — 고객 중복 생성 (UNIQUE 제약 재설계)
115+
116+ ** 문제 상황** <br >
117+ 예약 진행 시 백엔드는 ** 이름 + 전화번호** 로 기존 고객 존재 여부를 확인하고, 없으면 신규 고객을 자동 등록하도록 설계되어 있었습니다.<br >
118+ 그런데 고객이 이름이나 전화번호를 잘못 입력한 뒤 이를 인지하지 못한 채 정정하면, ** 같은 카카오톡 플러스친구 ID 하나에 서로 다른 고객 레코드가 2건** 생성되었습니다.<br >
119+ 이렇게 중복 생성된 고객은 이후 다른 업로드 로직에서 ** 충돌** 을 일으켰습니다.
120+
121+ ** 근본 원인 — UNIQUE 제약을 고객의 입력 자율성에 맡김** <br >
122+ 이름·전화번호는 ** 고객이 자유롭게 입력하는 값** 이라 오타·변경이 언제든 발생할 수 있습니다.<br >
123+ 이런 가변적인 값을 식별 기준(UNIQUE)으로 삼은 것이 중복의 직접 원인이었습니다.
124+
125+ ** 해결 방법 — 식별 기준을 불변값인 플러스친구 ID로 전환** <br >
126+ UNIQUE 제약을 ` (이름, 전화번호) ` 에서 시스템이 보장하는 불변값인 ** 카카오톡 플러스친구 ID** 로 변경하여 고객을 식별하도록 했습니다.<br >
127+ 이를 통해 ** UNIQUE 제약은 사용자 입력 자율성에 맡기면 안 되며, 시스템이 통제 가능한 불변 식별자에 부여해야 한다** 는 점을 체감했습니다.
128+
129+ <br >
130+
75131---
76132
77133## 주요 기능
0 commit comments