결제 모니터링·영상 다운로더 직접 제작한 이직 첫 달 적응기
목차
3월, 새 회사 첫 달. 공식 등록은 아직이었는데, 그건 절차의 문제고 실제 작업은 3월 초부터 시작됐다.
이직 직후 첫 달이라는 게 특이한 상태다. 새 환경인데 이미 뭔가를 해야 하고, 코드베이스는 낯선데 기대치는 있고. 그 긴장감을 어떻게 쓰냐에 따라 적응 속도가 꽤 달라진다. 나는 불안보다 자극으로 받아들이는 편이었는데, 3월은 그 선택이 잘 맞아들어간 달이었다.
새로운 환경, 빠른 흡수
이전 회사보다 규모가 달랐다. 다루는 데이터 양, 서비스 트래픽, 결산의 복잡도. 숫자 자체가 달랐고, 그 숫자를 다루는 코드의 결도 달랐다. 배워야 할 것들이 한꺼번에 쏟아졌는데 그게 오히려 좋았다. 오랫동안 원했던 더 복잡한 도메인이었으니까.
익숙한 것만 계속 반복하면 성장이 멈춘다는 걸 이전 직장 후반에 느꼈다. 비슷한 패턴의 작업이 반복될수록 개선 아이디어는 줄고 그냥 처리하는 감각만 남는다. 그게 불편했다. 새로운 복잡도가 학습의 재료가 됐고, 복잡할수록 좋았다.
새 코드베이스를 빠르게 파악하는 방법은 사람마다 다른데, 나는 보통 이 순서로 접근한다.
- 최근 커밋 히스토리를 주요 파일 단위로 훑기. "왜 이 코드가 여기 있나"를 이해하면 현재 구조가 훨씬 빨리 보인다
- 테스트 코드 먼저 읽기. 어떤 케이스를 보호하고 있는지가 곧 도메인 요구사항의 요약이다
- 배포 스크립트·CI 파악. 릴리즈 흐름을 모르면 PR을 올려도 뭘 기다려야 하는지 모른다
처음 두 주는 낯설었다. PR 코멘트 다는 것도 조심스러웠고 변수명 하나도 확신이 없었다. 3주차부터 기여할 수 있는 부분이 보이기 시작했다. 그 변곡점이 생각보다 빨리 왔는데, 이전 회사에서 쌓은 맥락 덕분이었다. 패턴을 새로 배우는 게 아니라 이미 아는 패턴이 다른 규모에서 어떻게 나타나는지를 보는 것이었으니까 적응 속도가 빨라진 거라고 생각한다.
낮엔 새로운 코드를 읽고, 밤엔 slecs를 쳤다. 에너지가 넘쳤다. 낮에 배운 것과 밤에 만드는 것이 서로를 증폭시키는 구조였다. 업무와 사이드가 분리된 게 아니라 피드백 루프였다.
이달의 레포별 현황
| 레포 | 커밋 | 내용 |
|---|---|---|
| slecs | 362 | 신 회사 업무 이해 기반 사이드 확장 |
| pay-monitor | 63 | 결제 모니터링 도구 |
| VideoDownloader | 11 | 영상 감지 + 다운로드 도구 |
slecs 362커밋은 단순 숫자가 아니다. 새 회사 도메인을 이해하면서 그것과 연결되는 사이드를 계속 확장한 결과다. 새로운 환경에서 배운 것이 사이드에 반영되고, 사이드를 구현하면서 업무에서 놓친 관점을 다시 확인하는 순환이었다.
pay-monitor는 결제 모니터링 도구다. 결제 도메인 특성상 이상이 생겨도 유저가 즉시 알아채지 못하거나 조용히 이탈하는 경우가 많다. 서버 로그만 보면 늦고, 실제 트랜잭션 흐름을 직접 감시하는 레이어가 없으면 어느 구간에서 문제가 생겼는지 파악이 늦어진다. 그래서 직접 모니터링 도구를 만들었다. 결제 플로우의 특정 구간에서 이상 신호를 잡아내는 게 목표였다. 새 회사 결산 복잡도를 이해하면서 필요성이 더 선명해진 도구기도 하다.
VideoDownloader
이달에 새로 생긴 레포다. 개인 도구 성격이었지만, 필요한 게 있으면 직접 만드는 주의라 빡빡하게 짰다.
기능 범위:
- iframe 내 영상 감지
- XHR 응답 파싱으로 영상 URL 추출
- 광고 차단
- 외부앱 이동 차단(딥링크, intent 스킴)
핵심은 XHR 인터셉션이었다. XMLHttpRequest.prototype.open을 오버라이드해서 응답 흐름 안에 감지 로직을 끼워 넣는 방식이다.
const origOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url, ...rest) {
this.addEventListener('load', function() {
if (isVideoUrl(url)) {
captureVideoUrl(url, this.response);
}
});
return origOpen.call(this, method, url, ...rest);
};
광고 차단은 URL 패턴 매칭으로 처리했다. 외부앱 이동 차단은 intent:// 스킴이나 딥링크를 걸러내는 형태. 영상 플레이어가 광고 노출과 앱 이동 유도를 한데 섞어두는 패턴이 많아서 이 둘은 같이 잡아야 했다.
iframe 감지는 MutationObserver로 DOM 변화를 감시하면서 새로 삽입되는 iframe의 src를 실시간으로 분석했다. 영상 플레이어가 동적으로 iframe을 삽입하는 경우가 많은데, 로드 시점이 아닌 삽입 시점을 잡는 게 포인트였다. 로드 이후에 감지하면 이미 재생이 시작된 뒤라 원하는 URL을 놓치는 케이스가 생긴다.
트레이드오프가 있다. XHR 오버라이드는 강력하지만 페이지 전체 네트워크 요청을 감시하게 돼서 성능 오버헤드가 따라온다. 오버헤드를 줄이려면 감지 조건을 최대한 앞단에서 필터링해야 한다. isVideoUrl() 같은 체크를 가볍게 유지하는 게 핵심이다. 컨텐츠 타입이나 URL 확장자를 먼저 확인하고, 무거운 파싱은 후순위로 미루는 식. 커밋이 11개로 적은 건 기능이 단순해서가 아니라 초반에 방향을 잡고 빠르게 수렴했기 때문이다. 직접 만들수록 이런 디테일을 전부 직접 챙겨야 한다는 것도 다시 실감했다.
3월이 끝나갈 무렵 새 회사 코드베이스가 어느 정도 눈에 들어오기 시작했다. 처음 두 주의 낯섦이 당연한 거였고, 그걸 무리하게 줄이려다 헤매는 것보다 그냥 충분히 읽는 시간을 확보하는 쪽이 결국 빨랐다. 3월 내내 이 페이스로 달린 게 나중에 생각해도 무리했다. 그런데 그때는 그냥 됐다. 새로운 환경의 자극이 에너지로 전환됐고, 그게 커밋 수로 나왔다. 그 페이스가 4월 638커밋으로 이어졌다. 유지가 됐다는 게 신기하긴 했다.
댓글 0
첫 댓글 달아줘.