운영 중인 신선식품 커머스를 다른 법인이 넘겨받게 됐고, 시스템을 인수해 운영·개발·유지보수까지 맡는 일이 시작됐다. 첫 일은 코드를 여는 것이 아니라 무엇을 언제까지 누가 책임지는지 범위를 나누는 것이었다. 범위를 잘못 나누면 기술 작업이 기술과 무관한 결정을 기다리며 멈춘다.
Table of contents
Open Table of contents
배경 — 노후한 시스템을 기간 단위로 넘겨받는 구조
넘겨받는 시스템은 오래됐고 구조도 아직 다 확인하지 못했다. 미리 파악한 범위만 봐도 고객 웹은 Vue 2.7, iOS 앱은 Tuist 로 생성하는 프로젝트, Android 앱은 Jetpack Compose 이고, 백오피스는 PHP 로 돌며, 서버 쪽에는 Client API 와 Cloud Functions 가 따로 있다. 코드는 GitHub 조직의 저장소 46개에 나뉘어 있고, 넘겨받은 명세도 Client API·Cloud Functions·Database 세 갈래로 따로 묶여 있다. 한 덩어리로 견적을 내면 어느 부분이 늦어지는지 아무도 설명할 수 없는 구성이다.
그래서 처음부터 일회성 과업과 월 단위 운영을 갈랐다. 일회성 과업은 M/M 으로 잡고, 운영은 클라우드 인프라 실비와 기술 대응 인건비를 따로 세운다. 인프라 비용을 인건비에 섞지 않은 이유는 트래픽과 데이터가 늘 때 늘어나는 몫이 누구 것인지 청구서에서 바로 갈려야 하기 때문이다. GCP 계정과 청구서는 넘겨받는 법인 명의로 두고, 운영 쪽은 관리자 권한을 위임받아 관리한다.
과업 네 개 — 상품 등록·출고 처리·결제 전환·클라우드 이전
일회성 과업은 넷으로 나눴다.
- 상품 등록 — 고객 화면에 노출할 상품을 등록하는 관리자 화면. 기존 시스템 구조를 확인하기 전이라 범위와 M/M 은 잠정치로 두고 확인 뒤 다시 산정한다
- 출고 처리 — 주문 조회, 주문 Excel 다운로드, 송장 등록, 송장 Excel 일괄 등록. 기존 WMS 를 쓰지 않는 전제다
- 결제 로직 전환 — 중량에 따라 나중에 결제하던 구조를 주문 시점에 바로 결제하는 구조로 바꾼다
- 클라우드 인프라 이전 — 넘겨받는 법인 명의의 GCP 계정으로 시스템을 옮긴다
넷 중 셋은 기술만으로 끝까지 갈 수 있다. 결제 로직 전환은 다르다. 주문 시점에 값을 받으려면 중량 구간별 고정가 같은 가격 정책과 SKU 표준화가 먼저 정해져야 하고, 그 결정은 기술 쪽이 내릴 수 있는 것이 아니다.
판단 기준 — 정책 확정에 걸린 과업을 떼어 낸 자리
착수 순서를 정하는 방법은 두 가지였다.
- 네 과업을 한 일정으로 묶고 정책이 확정되면 함께 시작한다
- 정책과 무관한 상품 등록·출고 처리·인프라 이전은 바로 시작하고, 결제 로직 전환만 정책 확정을 전제로 따로 둔다
1번은 일정표가 하나라 관리가 단순한 대신, 가장 늦게 확정되는 결정에 네 과업이 모두 묶인다. 반면 2번은 일정표가 둘로 갈리지만 GCP 이전과 출고 처리처럼 운영에 바로 필요한 과업이 먼저 움직인다. 2번을 고른 이유는 정책 확정이 언제 될지 기술 쪽에서 알 수 없는데, 1번은 그 불확실성을 네 과업 전부에 번지게 하기 때문이다. 2번에서는 정책이 늦어지면 결제 로직 전환과 그 후속 일정만 순연된다. 대가는 결제 전환이 다른 과업과 따로 움직여, 나중에 출고·상품 쪽과 다시 맞춰야 할 접점이 생긴다는 점이다.
같은 기준으로 책임의 경계도 그었다. 가격 정책과 그 설계는 넘겨받는 법인의 몫이고, 운영 쪽은 결제 로직과 API 구현까지 책임진다. 표시 중량과 실제 출고 중량이 다를 때의 처리, 즉 오차 허용 범위와 손실 반영 방식도 정책이므로 넘겨받는 법인이 세우고, 운영 쪽은 확정된 정책을 시스템에 반영하는 데까지 맡는다. 정책을 구현 쪽이 대신 정하면 문제가 생겼을 때 그것이 버그인지 정책인지 아무도 가를 수 없다.
영향 범위 — 3개월 기준 기간과 재협상
계약은 3개월을 기준 기간으로 하고, 운영 비용과 투입 범위는 3개월마다 다시 협상한다. 노후한 시스템은 넘겨받은 직후가 가장 위험하고, 그 위험이 얼마인지 지금은 모른다. 처음부터 1년 단위로 고정하면 모르는 위험을 한쪽이 떠안게 되므로 기간을 짧게 끊었다. 기준 기간 뒤에 정상 운영 전환이 확인되면 그 뒤 계약은 따로 맺고, 이 계약은 자동으로 갱신되지 않는다.
데이터 이관 범위도 같은 방식으로 경계를 정했다. 상품 정보·주문 이력·회원 정보 가운데 무엇을 옮길지 확정하는 일과 원 시스템 접근 권한을 확보하는 일은 넘겨받는 법인이 먼저 끝내 제공하는 것으로 두었다. 접근 권한이 없으면 이관 과업 전체가 시작조차 못 하므로, 이것이 범위표에서 가장 앞에 와야 할 선행조건이다.
남은 의문 — 잠정치로 둔 것
- 상품 등록 과업의 범위는 기존 시스템 구조를 열어 보기 전까지 잠정치다. 구조가 예상보다 복잡하면 이 항목이 가장 크게 바뀐다
- 클라우드 이전이 「계정을 새로 만들어 옮기는 일」로 끝날지, 기존 결제·청구 구조와 얽혀 더 큰 일이 될지는 아직 모른다
- 접근 권한이 약속대로 먼저 넘어올지는 이 범위표가 통제할 수 없는 부분이다
결과 — 착수 순서와 책임 경계
- 일정 위험의 격리. 기술 밖의 결정(가격 정책·SKU 표준화)을 기다리는 과업은 결제 로직 전환 하나로 좁혔다. 정책이 늦어도 상품 등록·출고 처리·인프라 이전은 멈추지 않는다
- 책임 경계. 정책은 넘겨받는 법인, 구현은 운영 쪽으로 갈라, 장애가 났을 때 버그인지 정책인지를 가를 기준을 계약 단계에서 세웠다
- 비용 구조. 인프라 실비와 기술 대응 인건비를 나눠, 늘어난 비용의 출처가 청구서에서 바로 갈리게 했다. 3개월 단위 재협상으로 모르는 위험을 숫자로 고정하지 않았다
정리
- 넘겨받을 범위는 과업 단위로 나누되, 기술 밖의 결정을 기다리는 과업을 따로 떼어 둔다. 그래야 기다림이 그 과업에서 멈춘다
- 정책은 넘겨받는 쪽이 정하고 구현은 운영 쪽이 맡는다. 경계가 흐리면 장애가 버그인지 정책인지 가를 수 없다
- 인프라 실비와 기술 대응 인건비를 분리하면, 늘어난 비용이 어디서 왔는지 청구서에서 바로 갈린다
- 노후한 시스템은 기준 기간을 짧게 잡고 재협상한다. 모르는 위험을 계약 안에 숫자로 고정하지 않는다