프로젝트를 불러오는 중…
프로젝트를 불러오는 중…
Select 호텔 도메인의 데이터는 네 개의 다른 소스에 흩어져 있었다 — Supabase의 정적 메타데이터(호텔·지역·브랜드·혜택), Sabre의 실시간 요금, 분석 이벤트 로그, 추천·후기·통계 콘텐츠. 프론트엔드가 각 소스를 직접 호출하면 세 가지 문제가 누적된다.
| 문제 | 영향 |
|---|---|
| 인증·캐싱·에러 처리 중복 | 프론트 코드가 비대해지고 정책이 갈라짐 |
| 외부 API(Sabre) 장애가 그대로 노출 | 사용자가 5xx를 본다 |
| 분석 이벤트 기록이 산발적 | 통계 일관성 부재 |
목표는 세 가지로 좁혔다.
24개 테이블 모델링이 선행되어 있어 하루 안에 모든 인프라를 푸시할 수 있었다 — SQLAlchemy 모델 + 호텔·메타·Sabre·분석·미디어 API + 통합 테스트 + Docker + CI/CD까지 한 번에.
| 항목 | 내용 |
|---|---|
| 모델 | SQLAlchemy 2.0 async · 24 테이블 · Pydantic 스키마 매핑 |
| API | 호텔 CRUD · 검색 · 지역/브랜드/체인 · 블로그·피처슬롯·추천·후기·통계 · Sabre 프록시 · 분석 이벤트 |
| 인프라 | Docker · Cloud Run · GitHub Actions |
각 tier가 명확히 한 일만 하니, 캐시는 Service에만, DB는 Repository에만, 인증은 Router 진입점에만 박혀 있다. 변경 시 영향 반경이 한 tier로 제한된다.
SabreProxyService에 5회 실패 / 30초 윈도우 circuit breaker를 적용. Sabre가 흔들리면 5번 안에 회로를 열고, 30초 동안은 외부 호출 없이 빠른 실패를 반환한다. 프론트는 5xx 대신 명시적 "외부 일시 장애" 응답을 받아 처리할 수 있다.
데이터 변화 빈도에 따라 캐시 수명을 다르게 설정.
| 도메인 | TTL | 이유 |
|---|---|---|
| 호텔 메타 | 120s | 운영 중 변경 가능 (가격·상태) |
| 지역·브랜드·혜택 | 1800-3600s | 거의 정적 |
| Sabre 요금 | (캐시 없음) | 실시간성 우선 |
분석 이벤트는 응답 경로에서 빼냈다 — Router가 BackgroundTasks에 enqueue하고 즉시 202를 반환, 백그라운드에서 Repository를 통해 기록된다. 사용자 응답 지연 0, 통계 일관성 유지.
배포 후 Supavisor connection pooler와 asyncpg의 prepared statement 캐시가 충돌했다. 해결: statement_cache_size=0. 운영에서 잡힌 사고가 코드에 영구 기록된 사례.
| 시기 | 주요 변경 |
|---|---|
| Day 1 (2026-02-12) | 24 테이블 · 55+ 엔드포인트 · Sabre 프록시 · 분석 · Docker · CI/CD 한 번에 |
| Week 2 (~02-25) | API 완성도 — Promotions/Benefits/Tags CRUD · OpenAPI 메타데이터 · testimonials → reviews 리네이밍 · ruff format |
| Week 2 사고 | Supavisor 비호환 · statistics 500 (테이블 참조 교체) · Docker uv.lock 누락 |
| Month 2 (2026-04-03) | Sabre rates 새 가격 API 통합 |
| Month 2 (2026-04-20) | /regions에 country 필터·by-slug 라우트 추가 (이슈 #1440, #1441 대응) — 도시·국가 식별자 후속 |
Day 1의 빠른 푸시 이후, 운영 사고와 후속 요청을 점진적으로 흡수한 패턴이다.
| 항목 | 결과 |
|---|---|
| 통합 진입점 | FastAPI 단일 백엔드 · 55+ 엔드포인트 |
| 도메인 모델 | 24 테이블 SQLAlchemy 2.0 async |
| 외부 격리 | Sabre circuit 5회/30초 |
| 캐시 계층 | TTL 120 ~ 3600s 다층 |
| 분석 응답 지연 | 0ms (BackgroundTasks 202) |
| 운영 학습 | Supavisor statement_cache_size=0, statistics fix, Docker uv.lock |
기술적·운영적으로 가져간 학습은 네 가지다.
BackgroundTasks로 옮긴 순간 응답 지연이 0이 됐고, 동시에 분석 기록 누락도 사라졌다. 통계 일관성과 응답 속도는 트레이드오프가 아니다.privia-front-common이 시작점이 된 호텔매핑 과제의 도시·국가 식별자 모델과 정렬 (04-20 변경이 그 방향의 첫 걸음).