현대글로비스 광주 BSA WCS 프로젝트 회고





광주 BSA WCS 프로젝트는 JIS(Just In Sequence) 운영을 위한 상위 시스템의 주문 데이터 순차처리, 데이터 그룹핑, 설비 자동화 시스템 개발 프로젝트입니다. 프로젝트의 시작부터 끝까지 개발자 포지션으로 참여하였고 단독으로 진행하였습니다.
뒤죽박죽 혼용 되는 용어
물류라는 거대한 도메인 안에서 개발자의 입장에서는 취급하는 물건 자체가 중요하다고 생각한적은 없었습니다. 무엇을 취급하든 입고, 이송, 보관, 분류, 합포, 출하라는 행위 자체는 크게 달라지지 않았기 때문입니다.
다만 자동차 부품을 다루는 프로젝트를 진행하면서 생각이 조금 달라졌습니다. 이번 프로젝트는 데이터를 이해하는데 있어 용어가 조금 중요했었습니다. 대표적인 사례로 ‘차종 코드’ 가 기억에 남아 이야기해보려 합니다.
기아 JIS 시스템은 우리 공장에서 취급하거나 필요한 주문만 내려주는 구조가 아니었습니다. 필요한 모든 주문정보를 공개하고 그 중 우리 공장에 해당하는 주문을 필터링 하는 개념에 가까웠습니다.
| 프로젝트 명 | OV1 |
|---|---|
| 차량 명 | EV5 |
| 차종 코드 | X9 |
문제는 위 세 가지 용어가 이번 프로젝트에서는 사실상 같은 대상을 의미한다는 것이었습니다.
개발자 입장에서는 ‘차종 코드’ 만 알고 있으면 충분했습니다. 하지만 회의나 인터페이스 협의 할 때는 ‘프로젝트 명’, ‘차량 명’, ‘차종 코드’ 가 모두 혼용 되어 다시한번씩 확인하게되는 용어였습니다.
이 사실을 뒤늦게 알게되어 실제 데이터를 검토하는 과정에서도 불필요한 시간이 더 소모되었었습니다.
머리로는 알고 있었지만 이번 경험으로 다시한번 Ubiquitous Language 가 얼마나 중요한지 다시한번 느꼈었습니다.
Anti Corruption Layer

대부분의 프로젝트는 standalone 시스템인 경우가 많지 않습니다. 기존 레거시 시스템과의 연동이 빠질수가 없습니다. 그러다 보니 개인적으로는 외부 시스템의 용어와 스타일이 우리 시스템 내부까지 그대로 들어오는 것이 항상 마음에 걸렸습니다.
예를 들면 단순한 네이밍(약어), 타입, null 처리 방식 등이 있습니다.
- 외부 시스템에서는 Y, N 으로 boolean 을 사용하지만, 우리는 True, False 로 처리할 경우
- 외부 시스템에서는 car_type_cd 를 사용하지만, 우리는 vehicleTypeCode 를 사용할 경우
- 외부 시스템에서는 1, 2, 3 으로 상태 코드를 관리하지만, 우리는 Waiting, Working, Completed 로 관리할경우
- 외부 시스템에서는 값이 없을때 null 을 사용하지만, 우리는 null 없이 기본값 NONE 으로 표기할 경우
해결법은 단순합니다. 외부 시스템의 데이터 모델과 우리 시스템의 모델을 분리하는것입니다. 분명 귀찮은 작업이지만 제가 아닌 다른사람이 이어받을 때 혼용되면 개발자는 혼란스럽습니다.
어렵게 생각할 필요는 없습니다. 외부 시스템 용어에 휩쓸리지 않고
우리 시스템의 언어로 번역하는것
이 작업은 정말 단순하고 별것 없어보이지만 장기적인 소프트웨어 라이프 사이클엔 영향을 미친다고 생각합니다.
어떤 작은변화가 ACL 선에서 끝날것인가 아니면 코어까지 영향을 미칠것인가 이기도 하니까요.
중요한건 에러 핸들링
정상 플로우가 잘 동작하는것은 기본입니다. 따라서 시스템에서 정말 중요한 것은 에러가 발생했을 때 어떻게 처리하는것 입니다.
저는 이것을 ‘정상 플로우로 돌려놓는 것’ 이라고 표현 합니다.
에러가 발생하지 않는 시스템을 만드는건 현실적으로 불가능에 가깝습니다. 중요한 것은 에러가 발생한 이후 얼마나 빨리 인지하고 처리하고 다시 작업을 이어갈 수 있는가 입니다.
이 작업은 시스템이 자동으로 하는경우도 있겠지만, 대부분은 사람의 힘이 필요합니다.
대부분의 에러는 경계에서 발생한다
WCS 프로그램의 입장에서의 경계는, 상위 시스템 (ERP, WMS, MES 등), 설비, 사람이 대표적입니다.
- 네트워크 불안정으로 인한 인터페이스 실패
- 센싱 오류로 인해 인식 실패
- 입고시 물건의 개수를 오입력 했을 때
에러를 즉시 발견할수도 있고 뒤늦게 발견할수도 있습니다.
중요한건 그 때 어떤 식으로 ‘정상 플로우’ 로 돌려놓을 수 있는지 그 해결 프로세스가 준비되어있는지 입니다. 그리고 그 과정은 심플하면 심플할수록 좋습니다.
예를 들어, 센싱 오류로 인식하지 못했다면 경광등과 소리로 인지시키고 전산 조작없이 다시 읽히게 하면 됩니다.
모든걸 소프트웨어로 해결할 필요는 없다.
에러가 발생했을 기술적으로 가능하더라도 모든 상황을 소프트웨어로 처리하려고 할 필요는 없습니다. 때로는 코드를 추가하는 것보다 업무 프로세스나 운영 방식을 변경하는 것이 더 좋은 해결책일 수 있습니다.
예를 들어 잘못된 품목이 투입되는 문제가 있다고 해서 이를 소프트웨어에서 감지하고 취소하고 복구하는 모든 과정을 자동화할 필요는 없습니다. 알림과 작업자의 수동 개입 조합 (반자동화) 가 오히려 더 단순하고 명확한 해결책일 수도 있습니다.
중요한 것은 문제가 발생했을 해결하는 방법이 소프트웨어만 있는것이 아니고, 이 문제가 정말 소프트웨어가 해결해야 하는 문제인지 먼저 판단하는 것이라고 생각합니다.
마치며
SI 프로젝트는 구축할때는 참 재밌지만, 프로젝트가 끝나고 한 발 물러서서 바라보면 아쉬운점이 항상 눈에 밟히기 마련입니다. 한정된 시간안에 설계하고 개발하고 테스트하고 안정화하고 인수인계 해야하니 언제나 시간에 쫒기기 마련입니다.
이 프로그램이 향후 10년간 문제없이 오랫동안 잘 쓰였으면 좋겠습니다.