코인 결제·스타일 고정·셀카를 한 번에 배포한 이유
목차
코인 결제 시스템, 스타일 고정, 환영 셀카, 신규 캐릭터 씬까지—한 커밋에 네 가지 기능이 한꺼번에 들어갔다. 보통은 각 기능별로 브랜치를 나누고 차례대로 배포하지만, 이번엔 특수한 상황이 있었다.
네 가지가 왜 함께?
먼저 각 기능의 성격을 보자:
| 기능 | 담당 파일 | 특징 |
|---|---|---|
| Polar 코인 결제 | polar/checkout, polar/webhook |
외부 PG 연동, 비동기 처리 필수 |
| 스타일 관계별 고정 | sql/migrate-art-style.sql |
DB 구조 변경, 기존 데이터 영향 |
| 환영 셀카 | selfie/route.ts |
신규 엔드포인트, UX 개선 |
| 신규 캐릭터 씬 | chat/route.ts |
기존 흐름 확장 |
결제 기능이 먼저 탑재되지 않으면 뒤따르는 기능들의 테스트가 막혔다. 스타일 고정이 DB에서 완료되지 않으면 캐릭터 씬 렌더링이 꼬였다. 일정상 동시 진행이 불가피했지만, 배포 시점에는 모두 준비 완료여야 했다. 팀과의 조율 끝에 한 번에 푸시하기로 결정했다.
구현 관점의 배운 점
결제와 웹훅의 분리: checkout과 webhook을 따로 파일로 둔 이유가 있다. 체크아웃 흐름은 동기식, 동기식이지만 Polar의 결제 확인은 서버-투-서버 콜백이다. 웹훅 핸들러가 비동기로 돌 때 메인 결제 로직 에러로 인해 끌려가면 안 되기 때문. 요청 파이프라인에서 이 둘이 겹치지 않도록 명확히 분리한 것.
checkout → 결제 페이지 리다이렉트
webhook ← Polar 결제 완료 후 비동기 콜백
DB 마이그레이션의 타이밍: sql/migrate-art-style.sql은 배포 직전에 돌려야 한다. 마이그레이션이 먼저 적용되지 않으면, 앱에서 새로운 스타일 관계 칼럼을 찾을 수 없다. 반대로 앱이 먼저 배포되고 마이그레이션이 밀리면 런타임 에러를 맞게 된다. 이런 순서 의존성은 배포 체크리스트에 명시했다.
API 라우트의 확장성: chat, gift, selfie 라우트를 보면 각각의 책임이 명확하다. 셀카 라우트가 추가되어도 기존 채팅이나 선물 로직에 영향 없다. 이게 가능한 이유는 API 엔드포인트를 도메인별로 설계했기 때문. 앞으로 더 많은 사용자 상호작용 기능이 추가될 때도 이 구조가 확장 가능하게 유지된다.
멀티 기능 배포의 체크포인트
여럿이 진행되는 작업이다 보니, 몇 가지를 특히 신경 썼다:
- DB 마이그레이션 테스트: 로컬에서 마이그레이션 스크립트를 실제로 돌려보고, 롤백도 검증했다. 프로덕션에 가서 "칼럼이 없네?" 하는 상황을 피하려면 이 단계가 필수다.
- 웹훅 엔드포인트 보안: Polar 웹훅이 정말 Polar에서 오는 요청인지 검증하는 로직이 들어있는지 확인했다. 웹훅은 공개 URL이기 때문에 스푸핑 공격 가능성이 있다.
- 기능별 롤백 계획: 만약 배포 후 버그가 발견되면, 어느 기능부터 다시 빼고 다시 테스트할지 미리 정해뒀다. "모든 게 한 번에 들어갔으니 모두 롤백" 같은 상황을 피하려고.
- 팀과의 커뮤니케이션: 이 커밋이 올라가는 시점에 각 팀이 어떤 부분을 담당하는지, 누가 배포 후 모니터링을 할 건지 명확히 했다.
큰 작업을 한 커밋으로 담되, 그 안에 논리적인 경계는 유지하는 것. 이게 이번 배포에서 배운 균형이다.
🛒 이 글과 어울리는 추천 상품
*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.
댓글 0
첫 댓글 달아줘.