시작은 단순했습니다
기정떡 공장을 위한 생산관리 시스템을 만들기로 했습니다. 재고 관리, 레시피 관리, 생산계획, 반죽일지 등 제조 현장에서 필요한 기능들을 담은 웹 애플리케이션입니다.
Rails라는 프레임워크를 선택했는데, 이게 정말 빠르더군요. "품목 관리 기능 만들어줘"라고 하면 목록, 등록, 수정, 삭제 화면이 한 번에 생성됩니다. 이런 식으로 재고, 레시피, 생산계획 등 주요 화면들의 뼈대를 잡는 데는 며칠이면 충분했습니다.
"와, 이 속도면 금방 끝나겠다"라고 생각했죠. 그게 착각이었습니다.
---
진짜 문제는 그 다음이었습니다
데이터가 없으면 어떡하죠?
가장 많이 마주친 에러는 "존재하지 않는 것을 보여달라"는 상황이었습니다.
생산계획 목록을 보여주는 화면에서 오류가 났습니다. 원인을 찾아보니, 누군가 생산계획을 만들어놓고 완제품을 연결하지 않은 경우였습니다.
시스템은 "이 계획의 완제품 이름을 보여줘"라고 하는데, 완제품 자체가 없으니 에러가 나는 거죠.
이 런 경우가 생각보다 많습니다. 레시피 없는 완제품, 품목이 삭제된 입고 기록, 사용자가 입력하다 만 데이터들... "데이터가 완벽하게 있을 것이다"라는 가정은 현실에서 통하지 않았습니다.
모든 화면에서 "만약 이게 없으면?"을 고려해야 했습니다.
현장의 언어를 이해해야 합니다
기정떡은 일반 빵과 만드는 방식이 다릅니다. 오늘 반죽해서 오늘 굽는 게 아니라, 하루 전에 1차 반죽을 하고, 다음 날 2차 반죽 후 생산합니다.
처음에 "오늘 할 일 목록"을 보여주는 화면을 만들 때 이걸 고려하지 않았습니다. 그냥 생산일 기준으로 만들었더니 아무리 봐도 사용을 하는데 너무 불편하게 생겼습니다.
"오늘 1차 반죽해야 하는 것"과 "어제 반죽해둔 걸 오늘 마무리하는 것"이 화면에 구분이 잘 되도록 보여져야 하는데, 그 구분이 모호했거든요.
결국 섹션을 나우어서 관리하게 됐습니다. 오늘 작업을 할 내용과 내일을 위한 준비를 위한 섹션을 한 화면에서 색깔과 섹션으로 구분해서 보여줍니다. 이런 로직은 어떤 프레임워크도 그냥 만들어줘라고 하면 바로 만들어주지 않을꺼라 생각됩니다. 공장에서 어떻게 일하는지 이해해야만 짤 수 있는 코드입니다.
단순해 보이는 기능의 함정
캘린더에서 날짜를 더블클릭하면 수량을 입력할 수 있는 기능을 넣었습니다. 말로 하면 한 문장인데, 실제로 구현하려니 생각할 게 많았습니다.
더블클릭을 감지하고, 입력창을 띄우고, 숫자를 입력받고, 저장 버튼을 누르면 서버에 전송하고,
성공하면 캘린더 셀을 업데이트하고, 실패하면 에러 메시지를 보여주고... 여기에 "입력창이 떠 있는 동안 다른 곳을 클릭하면 어떡하지?"까지 고려해야 합니다.
한 번은 저장 후 페이지 전체가 새로고침되면서 사용자가 보던 월이 오늘 날짜로 돌아가버리는 버그가 있었습니다. 사용자 입장에서는 "저장했더니 다른 달로 튕겼네?"가 되는 거죠. 이런 사소한 불편함을 하나씩 잡아가는 데 시간이 꽤 들었습니다.
재고 관리의 복잡함
식품 공장이니까 유통기한 관리가 중요합니다. 같은 재료라도 먼저 들어온 걸 먼저 써야 합니다. 이걸 선입선출, FIFO라고 하죠.
구현은 어렵지 않았습니다. 입고 목록에서 유통기한 순으로 정렬해서 차감하면 됩니다. 문제는 예외 상황들이었습니다.
유통기한이 없는 재료는요? 정렬에서 맨 앞으로 올까요, 맨 뒤로 갈까요? 봉지를 뜯어서 일부만 쓴 "개봉품"은 어떻게 추적하죠? 재료 사용을 취소하면 다시 재고로 돌려놔야 하는데, 이미 그 개봉품을 다 썼으면요?
처음에 30줄이던 코드가 200줄이 넘어갔습니다. 기본 기능은 간단한데, 현실의 복잡한 상황들을 다 담으려니 그렇게 됐습니다.
---
배운 것들
80-20 법칙이 정말이었습니다
기본 기능의 80%는 전체 시간의 20%로 만들었습니다. 나머지 20%를 다듬는 데 80%의 시간이
들어갔습니다. 화면이 동작하는 것과 실제로 쓸 만한 것 사이에는 큰 차이가 있습니다.
버튼을 누르면 저장되는 것까지는 빨리 만듭니다. 하지만 저장 중에 로딩 표시를 보여주고, 성공하면 알림을 띄우고, 실패하면 왜 실패했는지 설명하고, 네트워크가 끊겼을 때 대응하고... 이런 디테일들이 시간을 잡아먹습니다. 이전에는 95% 프로그램 완성을 했다고 생각을 했는데 지금 심 정으로는 95% 남은 것 같습니다. ㅠㅠ
복잡한 자동화보다 단순한 입력
처음에는 시스템이 많은 걸 자동으로 계산해주길 바랐습니다. 레시피 구조를 분석해서 필요한 재료를 자동으로 파악한다든지, 과거 데이터를 보고 생산량을 예측한다든지.
그런데 자동화가 복잡해질수록 "왜 이렇게 계산됐지?"라는 의문이 생깁니다. 잘못 계산되면 어디서 틀렸는지 찾기도 어렵고요.
결국 많은 부분을 사용자가 직접 입력하는 방식으로 바꿨습니다. 시스템이 똑똑해지려고 하기보다. 사용자가 쉽게 입력할 수 있게 만드는 게 더 나았습니다.
업무 이해의 중요성
가장 중요한 건 현장을 이해하는 것이었습니다. "반죽일지에 뭘 기록하나요?", "재고 확인은 언제
하나요?", "생산계획은 어떻게 세우나요?" 이런 질문들에 대한 답을 알아야 제대로 된 시스템을 만들 수 있습니다.
코드 작성 능력보다 업무 이해가 먼저입니다. 틀린 이해로 만든 완벽한 코드보다, 올바른 이해로 만든 거친 코드가 낫습니다.
---
마무리
아직 끝난 게 아닙니다. 쓰다 보면 새로운 요구사항이 나오고, 생각 못 했던 버그가 발견되고, "이것도 되면 좋겠는데"라는 아이디어가 떠오릅니다.
프로그램을 "완성"하는 게 아니라 "계속 다듬어가는" 것 같습니다. 뼈대는 빨리 세울 수 있지만, 좋은 시스템으로 만드는 건 시간과 경험이 필요한 일인 것 같습니다.