Search
moon
sun

배달의민족 전자계약서 화면 개편기: AI에게 맡긴 것과 사람이 챙긴 것

URL
생성 일시
2026/09/18 08:06
최종 편집 일시
2026/09/18 08:06
태그
우아한형제들
파일과 미디어
들어가며 전자계약서는 파트너(사장님)가 배달의민족을 처음 시작할 때 작성하는 전자문서입니다. 영업 담당자가 파트너와 함께 작성하고, 계약 내용을 바꿀 때도 같은 문서를 씁니다. 이 문서를 쓰는 작성 화면은 사업자 정보, 가게 정보, 광고 정보 같은 섹션이 모여 계약서 한 장을 이루는 큰 폼입니다. 2026년 4월부터 6월까지 이 작성 화면을 개편했습니다. 작성자가 계약서를 더 편하게 쓸 수 있게 […] The post 배달의민족 전자계약서 화면 개편기: AI에게 맡긴 것과 사람이 챙긴 것 first appeared on 우아한형제들 기술블로그. || 들어가며 전자계약서는 파트너(사장님)가 배달의민족을 처음 시작할 때 작성하는 전자문서입니다. 영업 담당자가 파트너와 함께 작성하고, 계약 내용을 바꿀 때도 같은 문서를 씁니다. 이 문서를 쓰는 작성 화면은 사업자 정보, 가게 정보, 광고 정보 같은 섹션이 모여 계약서 한 장을 이루는 큰 폼입니다. 2026년 4월부터 6월까지 이 작성 화면을 개편했습니다. 작성자가 계약서를 더 편하게 쓸 수 있게 하는 것이 목표였습니다. 그렇게 해서 계약서 한 장을 작성하는 데 드는 시간도 줄이려 했습니다. 그런데 기존 화면과 코드 위에서는 이 일이 쉽지 않았습니다. 화면은 Bootstrap과 Ant Design 위에서 디자이너 없이 개발자가 그린 것이어서, 사내 디자인시스템을 쓰는 디자이너와 함께 만들 수 없었습니다. 코드에는 폼 값을 관리하는 체계가 없어서, 값을 어디서 바꾸고 어디까지 다시 그려야 하는지 알기 어려웠습니다. 그래서 화면과 코드 구조도 함께 바꿨습니다. 코드는 처음부터 새로 썼고, 그 대부분을 AI 코딩 도구(클로드 코드)로 만들었습니다. 이 글은 그 과정에서 무엇을 AI에게 맡기고 무엇을 직접 챙겼는지 정리한 기록입니다. 개편하는 동안 부딪힌 질문은 세 가지였습니다. AI가 만든 코드가 아무 데나 생기는 것을 어떻게 막을까 AI에게 로직을 맡길 때 "그게 아니고"를 반복하지 않으려면 어떻게 해야 할까 그래서 실제로 얼마나 빨라지고, 배포 뒤 품질은 어땠을까 같은 고민을 하는 분께 이 글이 참고가 되면 좋겠습니다. 무엇이 바뀌었나 먼저 개편 전후 화면입니다. 개편 전 전자계약서 개편 후 전자계약서 가장 큰 변화는 디자인입니다. 기존 화면은 외부 라이브러리로 만든 것이어서 디자이너의 작업을 그대로 옮기기도, 디자인을 고쳐 달라고 부탁하기도 어려웠습니다. 개편 후에는 사내 디자인시스템인 우아한공방을 적용했습니다. 디자이너는 이 디자인시스템을 기준으로 작업하기 때문에, 이제 처음부터 디자이너와 함께 화면을 만들 수 있습니다. 작성자가 편하게 쓸 수 있도록 편의 기능도 두 가지 더했습니다. 오른쪽의 첨부 서류 모아보기: 기존에는 서류가 섹션마다 흩어져 있어서 하나씩 찾아가 확인해야 했습니다. 이제는 계약서에 첨부된 이미지를 한 곳에서 볼 수 있습니다. 왼쪽의 앵커 메뉴: 기존에는 잘못 입력한 값을 찾으려면 긴 폼을 위에서부터 훑어야 했습니다. 이제는 메뉴에서 섹션 사이를 바로 이동하고, 잘못 입력한 값이 있는 섹션은 메뉴에 에러 메시지로 표시됩니다. 코드는 왜 새로 썼나 기존 코드의 문제는 폼 값을 관리하는 체계가 없다는 것이었습니다. 전자계약서 화면은 전체가 하나의 폼이라서, 어느 섹션의 값을 바꿔도 결국 같은 계약서 데이터를 고치는 일입니다. 그런데 그 데이터를 다루는 방식이 정해져 있지 않았습니다. 기존에는 계약서 전체를 담은 큰 객체 하나를 props로 내려보냈습니다. 값을 바꿀 때는 그 객체를 직접 수정하고, 컴포넌트 트리에서 상위 컴포넌트를 골라 강제로 다시 그렸습니다. // 계약서 전체를 하나의 객체로 만들어 최상위에서 props로 내려보낸다 const contractData = new ContractData(data) // 깊은 곳의 컴포넌트(사업자등록번호 입력란)에서 값을 바꿀 때 class BusinessNumberInput extends React.Component { handleChange = (e