위반 480건 위에 아키텍처 규칙을 도입하기: 신규 코드는 100% 강제, 레거시는 점진 정리 Notes 음원 콘텐츠 플랫폼(MCP)을 화면 중심 API에서 도메인 중심 구조로 재설계하는 동안, 백엔드 세 명이 같은 코드베이스에서 동시에 작업했다. 이 글은 “구조를 이렇게 가자”는 합의가 왜 코드 리뷰만으로는 지켜지지 않았는지, 규칙을 테스트로 만들면 무엇이 달라지는지, 그리고 이미 수백 건의 위반이 있는 코드베이스에 규칙을 도입할 때 빌드를 막지 않으면... 2026/09/14 Notes, Common
Heap Dump가 가리킨 곳은 데이터가 아니라 영속성 컨텍스트였다: Tasklet에서 Chunk로, XSSF에서 SXSSF로 Notes 배치가 가끔 죽었다. 로그에는 OutOfMemoryError: Java heap space가 찍혀 있었고, 죽지 않은 날에도 Full GC가 반복되며 처리 시간이 늘어졌다. 이 글은 그 원인을 어떻게 특정했는지, 왜 “메모리를 늘린다”가 답이 아니었는지, 그리고 배치 구조와 Excel 생성 구조를 각각 어떻게 바꿨는지 정리한 기록이다. 이 글의... 2026/09/14 Notes, Common
2021년의 결제대행 API 연동을 2026년의 질문으로 다시 보기 Notes 2021년 여름, 더파이러츠에서 넉 달 동안 백엔드 개발자로 일했다. 맡은 일 중 하나가 제휴 상점의 자동 결제 시스템을 만들고 결제 대행업체 API를 연동하는 것이었다. 이력서에는 오래 “PG 모듈 연동”이라고 적혀 있었는데, 정확한 표현은 아니다. PG사와 직접 계약하고 연동한 것이 아니라, API 호출만으로 결제를 처리할 수 있는 중간 결제대행업... 2026/09/14 Notes, Common
폴링 배치를 SQS 이벤트 파이프라인으로 바꾼 이유: 재시도, DLQ, 메시지 ID 멱등 Notes 글로벌 유통 시스템(MDS)에서는 파트너사가 앨범을 올리고, 관리자가 검수하고, 검수가 끝나면 해외 플랫폼으로 전송하는 흐름이 계속 발생한다. 처음에는 이 작업들을 폴링 배치가 순서대로 처리했다. 이 글은 그 구조가 어디서 한계에 부딪혔는지, 큐로 바꾸면서 무엇을 새로 떠안게 됐는지(중복 전달, 순서, 실패 격리), 그리고 각각을 어떻게 다뤘는지 정리... 2026/09/14 Notes, Common
모든 도메인이 100% 정합성을 요구하지는 않는다: Post-Commit 이벤트와 재시도 3회 정책을 정한 기준 Notes 크리에이터 스튜디오는 누구나 오디오 콘텐츠를 만들어 배포할 수 있게 하는 B2C 플랫폼이었다. 콘텐츠가 생성되거나 수정되면 Braze(마케팅 자동화)와 Mixpanel(행동 분석)에 그 사실을 알려야 했다. 이 글은 그 외부 호출을 어디에 둘지 정한 과정과, “실패하면 어떻게 하는가”에 대한 답이 왜 “3회 재시도 후 로그만”이었는지, 그리고 그 답이... 2026/09/14 Notes, Common
Shadow Release로 조회를 옮기기: MyBatis 결과와 QueryDSL 결과를 나란히 비교하며 전환한 기록 Notes 음원 콘텐츠 플랫폼(MCP) 재설계에서 데이터 접근 구조를 바꾼 방식은 “전부 JPA로 옮기기”가 아니었다. 변경은 MyBatis에 그대로 두고, 조회만 QueryDSL로 분리했다. 이 글은 왜 조회만 옮겼는지, 옮기면서 결과가 달라지는 것을 어떻게 잡았는지, 그리고 어디까지 그 절차를 적용했는지 정리한 기록이다. 이 글의 코드는 회사의 실제 ... 2026/09/14 Notes, Common
ParityPay로 검증하는 결제 정합성 4 - 실험 26종이 찾아낸 결함 12건: 문서와 코드를 읽어서 나온 것은 하나도 없었다 Notes ParityPay의 설계 문서는 열여섯 개였다. 제품 기획서부터 도메인 상태 전이, 원장 분개 카탈로그, 정합성과 장애 복구 설계, 테스트 전략까지. ADR도 열한 개였다. 자동화 테스트는 백엔드 317개, 프론트엔드 56개, E2E 7개이고 전부 통과한다. 그 상태에서 부하와 장애 실험 26종을 돌렸다. 결함 12건이 나왔다. 이 글은 그 12건이... 2026/09/14 Notes, ParityPay
ParityPay로 검증하는 결제 정합성 1 - 장애가 나도 지켜야 할 금융 불변조건 여섯 가지 Notes GitHub 저장소 ParityPay는 플랫폼 내장형 페이머니를 구현한 개인 프로젝트다. 사용자가 은행 계좌에서 페이머니를 충전하고, 주문을 결제하고, 취소하고, 판매자에게 정산되는 흐름을 백엔드로 만들었다. 기능 목록만 보면 흔한 결제 API 연동 과제처럼 보인다. 이 프로젝트의 목표는 그 기능들이 정상 요청에서 동작하는 것이 아니라, 중복 요청,... 2026/09/14 Notes, ParityPay
ParityPay로 검증하는 결제 정합성 2 - 잠금을 필요 이상으로 오래 쥐고 있었다: 추론을 측정으로 바꾼 기록 Notes 1편에서 잔액 비음수(INV-003)를 조건부 원자 UPDATE로 강제한다고 썼다. 이 글은 그 UPDATE가 동시 결제 아래에서 어떻게 동작했는지, 느려진 원인을 “안다”고 생각했던 것이 어디까지 측정이고 어디부터 추론이었는지, 그리고 측정 방법 자체가 결론을 만들 뻔한 두 번의 실수를 정리한 기록이다. 수치는 전부 실측값이고, 측정 조건과 설명하지... 2026/09/14 Notes, ParityPay
ParityPay로 검증하는 결제 정합성 3 - 외부 승인 응답이 사라졌을 때: 타임아웃은 실패가 아니다 Notes 외부기관을 호출하는 결제 시스템에는 세 번째 결과가 있다. 성공도 실패도 아닌 “모른다”다. 이 글은 ParityPay가 그 상태를 어떻게 다뤘는지, 왜 그것이 예외 처리가 아니라 상태 모델의 문제인지, 그리고 실험이 설계 문서에 없던 구멍을 어떻게 드러냈는지 정리한 기록이다. 문제: 응답이 없다는 것은 실패가 아니다 충전 요청의 흐름은 단순하다.... 2026/09/14 Notes, ParityPay