커머스 혹은 유통 도메인 설계에 대한 연작

그간 간헐적으로 설계에 대한 이야기를 써왔는데, 최근 8년정도 몸담고 있는 유통(리테일 혹은 커머스) 업무에 대해서 비즈니스 해석과 개념 설계 활동을 프로그램 구현과 연결하는 실제 현장 이야기 써볼까 합니다. 실제 현장이야기인지라 정제해서 쓰기 어려워 독자분들에게 어떤 가치가 있을지는 의문입니다. 그럼에도 불구하고 노하우 추출을 위한 첫발 정도의 의미로 연재를 시도합니다.
그 시작은 '상품'이란 주제에 대한 고민을 푸는 과정입니다. 시작하죠.
어느날 동료와 시스템 구조 변경에 대한 이야기를 했습니다. 필자는 전체적인 서비스 설계자 역할을 하고, 동료는 핵심 기능 개발을 합니다. 개발자인 동료가 수정해야 할 폭이 크다고 여겼습니다. 그래서, 필자가 요구하는 사항을 듣고 난  동료가 몇 시간 후에 아래와 같은 그림을 그려 와서 저에게 확인을 요청합니다.
presentation
동료가 그린 내 요구 모델

상품 혹은 카타로그

필자가 발언한 변화 필요성에 대하여 자신이 이해한 내용을 그린 것입니다. 개발에 착수하기 전에 모호한 부분을 확인하고자 하는 것이죠. 먼저 Catalog이하 카타로그와 Product이하 상품을 병기한 이유는 모듈수준에서는 혼용해서 쓰고 있었기 때문입니다. 모듈 내부로 들어가면 카타로그와 상품은 1-대-다 관계를 갖습니다. 모듈이라는 말은 마이크로 서비스 형태에서 배포단위로 보셔도 좋고, 개발 코드의 프로젝트 단위로 봐도 무리가 없습니다.
상품에는 다수의 선택사항Option이 달립니다. 선택사항은 예를 들어 상품이 옷인 경우 색상과 사이즈의 조합일 수 있습니다. 사용한 용어에 대한 엄밀한 정의는 하지 않은 상태입니다. 읽는 분들도 각 단어의 의미를 다르게 이해할 수 있으리라 생각합니다. 그럴 때 일수록 그림 즉, 모델이 지니는 기능을 명확히 해둘 필요가 있습니다.

관점View을 이해 혹은 정의하기

동료가 그린 박스 바깥의 원은 UML과 같은 엄밀한 표기법을 따른 것은 아닙니다. 동료는 앱이나 화면을 개발하는 일이 드물고 주로 API를 개발하는 친구입니다. 그래서, 원은 본인이 제공해야 할 기능의 사용처 즉 클라이언트 프로그램 자체거나 그 쓰임새를 담은 것으로 볼 수 있습니다. 각 클라이언트에 대한 개괄적 설명은 아래와 같습니다.
  • 캠페인은 우리가 판매행사를 구현하는 단위입니다. 당연히 상품 목록에 해당하는 카타로그를 사용하겠죠.
  • Early Bird는 우리가 만든 앱 이름인데, 판매사가 손님에게 팔기 원하는 상품을 고르는 역할을 합니다. 판매 등록을 하는 PoS와 비슷한 듯 하지만, PoS는 매장 공용이라면 Early Bird는 판매사 개인 욕구에 초점을 맞추고 있습니다.
  • 클릭이나 판매수 정보는 특정 앱에 나타나는 것이 아니라 향후 로그를 통해 성과를 분석하기 위한 정보 수집 쓰임새를 의미합니다.
  • mini app listing이라고 표현한 것은 중국에서 위챗 기반으로 구동하는 미니 프로그램小程序을 의미하는데, 간편한 앱으로 이해하셔도 이 글 이해에는 지장이 없습니다.
우리 이야기를 이해하시기 위한 배경정보를 길게 설명했는데, 여기서 위 모델(그림)은 어떤 기능을 할까요? 본인이 이해한 것에 오류나 누락이 없는지 파악한 후에 점선으로 표기한 부분을 API로 구현하기 위해 그린 것입니다.

3개월 비즈니스 베타를 겪고 나서

위와 같은 그림 수준으로 대강의 요구를 정의하고 최소한의 화면기획과 주 단위 작업 할당으로 서비스를 빠르게 현장에 출시했습니다. XP에서 제안한 방법과 같습니다. 출시 대상은 소수의 사용자를 대상으로 한 베타 서비스입니다. 우리는 이를 '비즈니스 베타'라고 불렀는데, 3개월간 이를 수행하고 나니 많은 변경이 필요했습니다. 변경이 필요한 동기를 구분하면 대략 3가지 정도로 볼 수 있었습니다.
  • 서비스의 현장 가치가 모호해서 초점을 맞추려고 하니 소통을 위한 개념 정립 필요
  • 레거시 코드와 충돌이 나는 부분을 절충하기 위한 기준이 필요한데, 레거시에서 불명확한 부분이 많아 일단 개념 수준에서 맞춤
  • 모듈 별로 서비스 운영시에 어떤 데이터를 봐야 할지 명료하게 구분할 필요가 생김 (개발 부담도 마찬가지)
고치려고 마음을 먹고 동료 개발자들 의견을 들어보니, 추가로 수정할 부분이 상당했습니다. 또한, 일단 배포를 하고 나니[1] 병행 운영 부담으로 인해 여러 버전의 API가 돌아가야 하는 일은 피할 수 없는 현실로 다가왔습니다. 다행히 이 부분이 우리를 멈추게 할 정도는 아니었지만, 이를 변화를 수용하기 위해 발생하는 피할 수 없는 시행착오[2]로 보면 다음과 같은 사항을 배울 수 있었습니다.
  • 가급적 빨리 현장에 나가서 시나리오를 점검해보자.
  • 개발자가 노트북으로 개발하니 모든 사용자 이벤트를 모니터 화면 아니면 휴대폰으로 생각했지만, 터치 패드 형태의 태블릿이 있다!
  • 주문을 생성하거나 판매를 기록하는 프로그램인지라 매장 현장의 기기와 판매 방식(백화점과 쇼핑몰 입점 형태)에 따라 사용자 이벤트나 UI 동선이 달라져야 함
  • 모듈(개별 마이크로 서비스)은 최대한 작은 단위를 지향하자.
  • 개발팀이 다수면 변경할 때, 엮인 부분이 많아 갈등이 커진다.
  • API 호출이나 이벤트를 주고 받는 식이면 같은 프로젝트 내 코드를 여럿이 수정하는 형태보다 분업/협업 부담이 한결 덜하다.
  • 실질적인 리더를 빨리 찾아내자
  • 나이, 연차나 직급으로 인한 소모적인 소통 낭비를 걷어내고 누가 정말 해당 작업에 애정이 있고 책임감을 발휘하며 실질적으로 끌고 나가는지 모두가 알게 투명한 소통을 한다.

코드 수정외에 얻은 개념 정제 하나

상당한 코드 수정이 있었습니다. 그리고, 또 하나 얻은 내용이 있습니다. 아래 그림인데요.
presentation
두 계층으로 나누어 연결한 상품 개념
사용자가 보통 상품(商品)이라고 부를 때 말이나 화면에 보이는 표기는 상품이지만, 정보는 층을 나눠 저장하자는 제안입니다. 판매자(커머스) 입장에서 Product란 개념은 생산하거나 판매하려고 구입한 실제 물건을 지칭하고, Product를 지칭하거나 참조하지만 판매 관련한 정보는 별도의 개념(Item)으로 구분하자는 것이죠. 몇 가지 이유가 있는데 대략 예를 들면 이렇습니다.
  • 제조사가 다루는 관리번호와 판매자가 부여하는 식별번호는 다르다.
  • 같은 상품이라도 프로모션이나 수수료 계약에 따란 다른 가격을 부여해 판매조건이 달라진다.
  • 같은 상품 여러 개 혹은 다른 상품을 묶어 파는 경우는 흔히 있다.
  • 일차 판매자가 팔고 남은 물건을 다른 판매사가 사다가 파는 형태(아웃렛 혹은 Off-price-retails)가 있다.
  • 파는 단위를 고정하지 않고 구매할 때 단위와 가격이 정해지기도 한다. (슈퍼마켓에서 저울에 달아 사는 과일처럼)

연작 첫 글을 마치며

현장에서 느낀 바를 두서없이 일단 기록해두자는 성격으로 쓴 글이라 독자분들이 읽을 만한 가치가 있을지는 의문입니다. 다만, 연재로 계속 쓰면서 정제하고 또 소통을 원하는 분이 있다면 함께 나누면서 시간이 조금 더 흐른 후에 사회적 가치를 만들 수 있기를 기대하며 첫 발을 내딛습니다.

주석

[1] Martin Fowler가 지적하는 Published Interface 문제죠.
[2] 개발자가 흔히 겪는 일상 삽질인데, 경영자들이 흔히 혁신이라 부르는 일을 생산하는 아주 좋은 방법 중 하나죠.