10월 21일 오전, 주문서 무이자 할부 플래그를 운영에서 끄고 아카이브했다. 주문서의 할부 목록은 그대로였다. 원래 그래야 하는 작업이었다.
이 플래그는 7월 22일에 켰다. 전환이 안정되면 2주에서 한 달 안에 지울 생각이었다. 실제로 지운 건 91일 뒤다. 그사이 장애는 한 번도 없었고, 코드도 어렵지 않았다. 10월에 올린 제거 PR 은 7월에 한 번 머지했던 변경을 거의 그대로 다시 올린 것이다.
그 91일 동안 일어난 일은 단순하다. 지울 걸 못 지웠고, 다른 작업을 하는 김에 지워 주겠다며 가져간 사람이 있었고, 그 사람의 일이 급하게 바뀌었고, 그사이 그 사람은 퇴사했다. 그래서 다시 내가 챙겼다. 그리고 그동안 다들 장바구니 CLS 를 봤다.
TL;DR
- 2주~한 달짜리 전환용 플래그가 91일 남았다. 장애 0건. 담당 표시가 두 번 바뀌었고, 다시 잡은 마감일은 세 번 밀렸다.
- 첫 제거는 7월 말에 머지했지만 8월 초 QA 에서 막혀 되돌렸다. QA 환경에 무이자 데이터가 없었고, 그걸 확인해 줄 지원도 없었다. 변경은 맞았는데 검증할 수가 없어서 한 주가 밀렸다.
- 결제수단 API 를 분리하는 작업이 시작되면서 “그 작업을 하는 김에 플래그도 필요 없어진다”는 계획이 나왔다. 제거 작업도 그쪽으로 넘어갔다.
- 그 작업은 3주 만에 방향이 바뀌어 멈췄고, 맡은 동료는 9월에 다른 업무로 옮겼다가 10월에 퇴사했다.
- 9월 마지막 날 멈춰 있던 제거를 내가 다시 가져왔고, 3주 뒤 지웠다.
- 그동안 매주 리포트에서 빨갛게 뜬 건 장바구니 CLS 였다. 91일째 살아 있는 플래그는 어느 리포트에도 없었다.
1. 지울 것을 못 지웠다 (7월 22일 ~ 8월 5일)
플래그가 하는 일은 하나였다. 주문서에서 카드 할부 개월에 “(무이자)”를 붙이는 기준을 예전 필드에서 새 필드로 옮기는 것이다. 새 필드가 운영에서 잘 도는지 보면서 켜고, 문제가 생기면 끄려고 플래그를 뒀다.
- 7월 22일 정기 배포와 함께 켰다. 백엔드와는 “2주에서 한 달 안정화한 뒤 프론트가 플래그를 지우면, 그다음 예전 필드를 내린다”고 정했다. 목표는 8월 5일 정기 배포.
- 7월 29일 제거 PR 을 올렸고 한 시간 만에 배포 브랜치에 머지됐다. 리뷰어 세 명이 같은 걸 물었다. “예전 필드로 돌아가는 길이 있는 동안에는 새 필드가 비어 있어도 티가 안 났을 텐데, 그 길을 없애도 되나?” 운영 응답을 열어 카드 19종을 셌다. 새 필드가 빠진 카드는 0건이었다.
- 8월 4일 정기 배포 전 QA 에서 무이자 표시가 안 뜬다는 보고가 들어왔다. 나는 휴가 중이었고, 동료가 제거 PR 하나만 골라 되돌렸다.
- 8월 5일 원인을 확인했다. QA 환경의 주문서 응답에는 무이자 정보가 카드 전부 비어 있었다. 운영은 정상이었다. 플래그를 켜든 끄든, 지우든 말든 QA 에서는 무이자 표시가 나올 수 없는 상태였다. 백엔드에 QA 에서 무이자 데이터를 만들려면 무엇이 필요한지 물었지만, 답을 받기 전까지는 QA 로 확인할 방법이 없었다. 그날 아침, QA 지원을 받을 수 없어 다음 정기 배포로 일정을 바꿨다.
검증의 구멍이었다. 변경은 맞았고, 운영 데이터도 맞았다. 틀린 건 검증하는 환경이었다. QA 환경에 무이자 데이터가 없으니 맞는 변경도 틀려 보였고, 그 데이터를 채워 줄 백엔드 쪽 QA 지원이 없으니 아무도 “맞다”고 확인해 줄 수 없었다. 코드 한 줄 바뀌지 않았는데 한 주가 밀렸다.
2. 하는 김에 가져갔다 (8월 3일 ~ 8월 18일)
같은 주에 다른 일이 시작됐다.
- 8월 3일 백엔드가 주문서 응답에서 결제수단 정보를 떼어 내 별도 API 로 옮기자고 요청했다. 동료 한 명이 맡았다. 할부 정보도 결제수단에 들어 있으니, 내 플래그가 건드리는 코드와 그대로 겹친다.
- 8월 6일 그 동료가 계획을 공유했다. 새 API 와 기존 응답을 한동안 같이 부르며 차이를 보고, 차이가 없으면 새 API 로 갈아탄다. 그리고 “제 작업에 FF 는 필요 없어질 것 같습니다”라고 덧붙였다. 갈아타는 과정에서 무이자 판정도 새로 쓰게 되니, 플래그도 같이 사라진다는 뜻이었다. 나는 제거를 다다음 정기 배포로 미루고 우선순위를 내렸다.
- 8월 7일 제거 작업의 담당 표시가 그 동료에게 넘어갔다.
- 8월 12일 결제수단 분리의 첫 단계가 main 에 들어왔다. 다시 올려 둔 제거 PR 은 이날부터 main 과 충돌했다.
- 8월 18일 백엔드에 “구매 수단 API 분리를 하면서 자연스럽게 front FF 가 제거될 예정”이라고 공유했다. 같은 날 제거 PR 을 닫았고, 담당 표시는 다시 나에게 돌아왔다.
제거는 이제 독립된 일이 아니라 결제수단 분리의 일부가 됐다. 그 작업이 끝나면 플래그도 같이 없어진다. 계획으로는 그랬다.
3. 일이 급하게 바뀌었다 (8월 13일 ~ 9월 16일)
결제수단 분리는 3주를 가지 못했다.
- 8월 13일 백엔드가 구조를 바꿨다. 기존 주문서 응답은 그대로 두고, 결제수단을 뺀 새 버전의 주문서 API 를 따로 만들기로 했다.
- 8월 21일 두 응답을 같이 불러 보니 실제로 차이가 나왔고, 새 버전은 목표 응답 시간을 맞추기 어렵다는 판단이 나왔다.
- 8월 24일 비교는 서버에서 하기로 했고, 프론트는 “끝나면 알려 달라”며 대기 상태가 됐다.
- 8월 27일 플래그 제거 작업은 백로그로 갔다.
- 9월 16일 그 동료가 다른 업무로 옮긴다는 공지가 나왔다. 같은 달, 정기 배포마다 붙던 QA 지원도 끝나 배포 전 검증은 각자 해야 했다.
플래그를 지워 줄 계획은 8월 24일에 사라졌다. 그 소식이 플래그 쪽으로 오지는 않았다. 그 계획은 결제수단 API 의 일이었지 플래그의 일이 아니었다. 10월에 비교용 호출을 걷어 내는 정리 작업의 분석에는 “이번은 전환 취소”라고 적혔다.
그사이 플래그는 100% 켜진 채로 매일 무이자 표시를 만들었다. 장애도 알람도 없었다. 9월 15일에는 다른 동료가 새 기능의 플래그 사용법을 정리하면서 이 플래그를 모범 예시로 인용했다. 표준 방식대로 잘 쓰인 플래그였으니 틀린 인용은 아니다. 다만 7월에 지워졌어야 할 플래그였다.
4. 그사이 퇴사했다 (10월)
10월 19일, 그 동료는 맡고 있던 다른 작업에 인수인계 메모를 남겼다. 그리고 이번 달 퇴사했다.
플래그 제거를 가져갔던 사람이, 그 일을 다시 꺼내기도 전에 다른 업무로 옮겼고, 회사를 떠났다. 누구의 잘못도 아니다. 계획은 서버 사정으로 바뀌었고, 사람이 옮기는 건 조직이 돌아가는 방식이다. 남은 건 주인 없는 플래그 하나였다.
5. 다시 내가 챙겼다 (9월 30일 ~ 10월 21일)
- 9월 30일 멈춰 있던 제거 작업을 내가 다시 가져왔다. 담당하던 동료가 다른 업무로 옮긴 뒤로 아무도 손대지 않던 일이었다.
- 10월 19일 7월의 커밋을 그대로 가져와, 그사이 main 에서 바뀐 다섯 파일의 충돌만 풀어 다시 올렸다. 운영과 QA 응답도 다시 열어 셌다. 리뷰에서 “그때 센 범위 밖의 결제수단 두 개는?”이라는 질문이 나와 그것도 따로 셌다. 둘 다 새 필드를 제대로 내려 주고 있었다.
- 10월 20일 승인이 거의 다 모였을 때, 하루 먼저 들어온 다른 플래그 제거 PR 과 바로 옆 줄에서 충돌이 났다. 지운 플래그 둘이 서로 부딪혔다. QA 에서는 플래그를 켠 채로, 끈 채로, 아카이브한 뒤로 같은 화면을 세 번 봤다.
- 10월 21일 운영에 배포하고 같은 확인을 운영에서 반복한 뒤 아카이브했다. 아무것도 바뀌지 않았다.
다시 시작한 계기는 새로운 발견이 아니었다. 누군가 다시 집어 드는 것, 그게 전부였다. “아무것도 안 바뀐다”를 보여 주는 방법은 지운 것이 아무것도 바꾸지 않았음을 증명하려면에 따로 적었다.
6. 그 와중에 다들 CLS 만 봤다
그 몇 주 동안 주간 성능 리포트 스레드에는 매주 숫자가 올라왔다. 8월 초 리포트에서 장바구니 데스크톱 화면의 CLS(레이아웃이 밀리는 정도)가 0.844로 나왔다. 로딩 중 높이를 잡아 두지 않은 영역 때문에 첫 화면의 푸터가 아래로 밀려나는 게 원인이었다. 9월 중순 리포트에서는 같은 화면이 0.860, “신규 극단”으로 표시됐다. 그 주는 온콜 담당이 이 리포트를 직접 들여다보기 시작한 첫 주였다.
CLS 와 이 플래그 사이에 인과는 없다. 플래그가 CLS 를 만든 것도, CLS 때문에 플래그가 밀린 것도 아니다. 그런데 둘을 나란히 놓으면 보이는 게 있다.
CLS 는 숫자가 있었다. 매주 리포트에 찍히고, 빨간색이 붙고, 스레드에 답이 달렸다. 플래그는 숫자가 없었다. 켠 지 며칠째인지, 누가 지우기로 했는지, 그 사람이 아직 그 일을 하고 있는지, 어느 화면에도 나오지 않았다. 그러니 다들 CLS 를 봤다. 볼 건 다른 데도 있었는데.
그 리포트는 AI 가 만든다. 매주 데이터를 모아 판정하고, “실질 액션은 CLS”라고 짚고, 액션 후보표까지 붙여 스레드에 올린다. 9월 중순부터는 온콜이 그걸 읽고 공유하기로 했다. 그런데 그 주 리포트의 신규 티켓은 0건이었다. 후보는 표에 있고, 생성은 “팀 논의 후”였다. 같은 리포트에는 “근본 수정 6주째 미배포”라는 줄도 있었다. 리포트는 매주 더 정교해졌지만, 숫자가 왜 나왔는지 읽고 무엇을 할지 정하는 자리는 비어 있었다. 나도 그 스레드에 “읽고 수집은 하겠지만 효과가 좋을지 고민된다”고 남기고 지나갔다.
AI 에게 리포트를 맡기는 건 좋다. 다만 새로 들여다볼 것을 늘리기 전에, 이미 해 놓고 마무리하지 않은 것부터 챙기면 된다. 91일째 살아 있는 플래그, 6주째 배포되지 않은 수정 같은 것들. 그건 리포트가 없어도 눈앞에 있다.
91일을 다시 걸어 보며 남긴 건 셋이다.
- “하는 김에”는 날짜도 주인도 없다는 말이다. 다른 작업과 같이 처리될 것 같아도, 제거는 제거대로 마감일과 담당을 따로 둔다. 같이 끝나면 그때 닫으면 된다.
- 남의 작업에 얹었다면, 그 작업이 바뀌는 날이 다시 꺼낼 날이다. 그 소식은 알아서 오지 않는다. 얹은 쪽이 직접 확인해야 한다.
- 숫자가 없는 일에는 숫자를 붙인다. 켠 지 며칠째인지, 처음 정한 수명이 며칠이었는지, 지우기로 한 사람이 지금 누구인지. 91이라는 숫자가 8월 어딘가에 빨갛게 떠 있었다면 누군가 훨씬 일찍 집어 들었을 것이다.
이번 플래그는 장애 없이 지워졌다. 문제가 없는 것은 아무도 보지 않고, 아무도 보지 않는 것은 사라지지 않는다. 결국 지운 건, 다시 집어 든 사람 하나였다.
AI 는 리포트를 대신 써 준다. 하지만 떠난 사람의 일을 대신 이어받지는 않고, 숨 쉬듯 매일 챙겨야 하는 일을 대신 해 주지도 않는다. 그건 여전히 남은 사람이 한다.