회사에 맞춰 ERP를 만든다는 말을 방문자가 자기 일에 대입해 볼 수 있으려면 무엇을 보여줘야 할까. 2026년 10월 20일, 메인에 직원과 대표의 화면을 넣는 작업에서 이 질문이 구체적인 체험 페이지로 이어졌다.

나는 화면의 배치와 문구, 가상 금액의 계산, 부분 납품과 취소, 자료 검토와 복구를 하나의 설명으로 연결했다. 실제 업체 정보를 사용하지 않고 그 체험을 만든 판단과 코드를 남긴 제작기다.

직원과 대표는 같은 회사에서 다른 질문을 한다

메인에 회사 맞춤 ERP를 소개한 뒤, 직원이 쓰는 화면과 대표가 현황을 확인하는 화면을 함께 보여 달라는 요청이 이어졌다. 매출·매입·미수금도 예시로 보여 주자는 방향이 더해졌다. 나는 이 요청에서 같은 자료를 보는 사람도 서로 다른 질문을 한다는 점을 먼저 잡았다.

직원은 어떤 주문을 처리하고 어떤 문서를 준비할지 알아야 한다. 대표는 얼마가 거래됐고 얼마를 아직 받아야 하며 누구에게 무엇을 확인할지 알고 싶다. 그래서 직원 쪽에는 품목·수량·매입처와 다음 작업을, 대표 쪽에는 금액·상태·확인 순서를 배치했다.

이번 글의 대상은 이 질문을 공개 홈페이지에서 설명하기 위해 새로 만든 체험 페이지다. 실제 회사의 운영 ERP를 그대로 옮긴 화면이나 실거래 보고서가 아니다. 이전 ERP 제작기가 원래 업무의 판단을 다뤘다면, 여기서는 내가 공개용 예시의 구성과 동작을 어떻게 설계했는지 기록한다.

메인은 요약하고, 별도 페이지는 바꿔 보게 했다

메인에는 직원과 대표의 화면을 나란히 두고, 작은 화면에서는 위아래로 이어지게 구성했다. 수량과 매입처를 바꾸고 예시 요청서를 준비하면 대표 쪽 주문 상태가 따라 바뀐다. 한 번 입력한 내용이 다음 업무로 이어진다는 뜻을 짧은 행동으로 전달하고 싶었다.

금액의 세부 내역, 부분 납품, 역할별 메뉴, 기존 자료 검토까지 메인에 모두 펼치면 첫 방문자의 읽는 순서가 길어진다. 그래서 요약을 이해한 뒤 더 살펴볼 수 있도록 상세 체험을 별도 페이지로 뒀다. 대표 현황·업무 연결·맞춤 구성·기존 자료로 바로 이동하는 경로도 붙였다.

한국어와 영어는 같은 체험 구조와 계산을 공유한다. 언어를 바꾸었을 때 수량과 금액의 의미가 달라지지 않게 하려는 선택이다. 읽는 사람이 필요한 깊이를 고를 수 있도록 정보의 위치와 조작의 순서를 함께 설계했다.

금액에서 거래와 다음 행동까지 내려가게

대표 화면은 매출 4,800만원, 매입 3,120만원, 미수금 1,260만원, 미지급금 840만원의 가상 월간 예시로 시작한다. 받은 금액은 3,540만원, 지급한 금액은 2,280만원이다. 큰 숫자를 읽은 다음에는 무엇을 확인해야 하는지까지 이어져야 한다고 생각했다.

미수금의 내역에는 가상 거래처 A의 720만원과 B의 540만원이 나온다. A의 거래 금액은 2,400만원이며 1,000만원과 680만원을 나누어 받은 기록이 있다. 카드의 합계와 거래별 남은 금액은 같은 장부에서 계산한다. 요약과 내역에 숫자를 따로 적어 두면 수정할 때 의미가 어긋날 수 있기 때문이다.

확인 목록에는 담당자, 예정일, 다음 행동을 붙였다. 미수금 전체와 예정일이 지난 금액도 구별했다. 가상 기준일은 2030년 4월 15일이며 실제 회사의 오늘을 뜻하지 않는다. 해당 월의 거래를 설명하는 예시라 이월·세금·급여 등은 생략했고, 매출과 매입의 차이를 순이익으로 표시하지 않았다.

코드와 구현 살펴보기

현재 공개 체험 모델의 발췌다. 의존 함수를 포함한 전체 코드는 아래에서 내려받을 수 있다.

export function ledgerRows(key){
  if(!['sales','purchases','receivables','payables'].includes(key))throw Error('Unknown example ledger');
  const ledger=syntheticLedger(),source=['sales','receivables'].includes(key)?ledger.sales:ledger.purchases;
  return source.map(row=>({...row,settled:row.receipts.reduce((n,v)=>n+v,0),balance:row.amount-row.receipts.reduce((n,v)=>n+v,0)})).filter(row=>!['receivables','payables'].includes(key)||row.balance>0);
}

공개할 자료는 처음부터 따로 만들었다

공개 체험에는 가상 거래처와 품목, 설명을 위한 날짜와 금액을 만들었다. 원래 회사의 장부를 이 페이지의 입력 자료로 쓰지 않았다. 이름만 바꾸어도 거래의 조합이나 문서 형태로 업체가 드러날 수 있으므로, 이번 설명에 필요한 관계를 새로 구성했다.

가상 자료에도 지켜야 할 조건이 있다. 받은 금액과 미수금을 더하면 해당 거래의 금액이 되어야 하고, 거래별 미수금의 합은 카드와 맞아야 한다. 공급처에 지급한 금액과 남은 지급액도 같은 원리로 이어져야 한다. 나는 이 관계를 먼저 정하고 화면에 올렸다.

월간 재무 예시와 직원의 업무 단계 체험은 서로 독립이다. 직원 쪽 요청서 준비 버튼을 누르면 주문 상태가 바뀐다. 이 동작으로 월간 매출이 증가하지는 않는다. 각 체험이 다루는 범위를 화면에도 적어 두었다.

상태를 바꾸고, 계산은 그 상태에서 읽었다

업무 체험은 수량, 진행 단계, 상황이라는 작은 상태에서 시작한다. 견적·주문·요청서 준비·납품 확인·수금 확인을 순서대로 보여 주되 준비된 문서와 실제 발송은 구별했다. 다음 단계를 체험해도 운영 시스템에 문서가 저장되거나 거래가 실행되지 않는다.

계산 함수는 상태를 읽어 결과를 만들고 화면은 그 결과를 표시한다. 수량이나 상황을 바꾸면 진행 단계도 처음으로 돌아간다. 납품을 확인한 뒤 수량만 바뀌었는데 완료 표시가 그대로 남으면 잘못된 기대를 만들 수 있다. 값을 고친 다음 어떤 확인을 다시 해야 하는지까지 담으려 했다.

수량이 잠시 비거나 허용 범위를 벗어나면 입력을 지우지 않고 다음 진행을 막는다. 이 체험의 수량 범위는 1~20의 정수다. 가상 단가와 납품 기준 금액은 설명용 규칙이며 실제 회사의 수량 제한이나 회계 처리 기준을 구현한 것은 아니다.

코드와 구현 살펴보기

현재 공개 체험 모델의 발췌다. 의존 함수를 포함한 전체 코드는 아래에서 내려받을 수 있다.

export function editJourney(s,key,value){
  if(key==='quantity'&&typeof value==='string')return {...s,quantity:value,phase:0};
  if(key==='scenario'&&scenarios.includes(value))return {...s,scenario:value,phase:0};
  throw Error('Unsupported synthetic edit');
}

부분 납품과 취소도 직접 바꿔 보게 했다

정상 완료만 보여 주면 일부만 끝난 업무에서 무엇이 남는지 알기 어렵다. 같은 주문에서 정상 진행, 부분 납품·부분 수금, 1개 반품, 주문 취소를 고를 수 있게 했다. 선택한 상황은 실제로 계산 결과를 바꾼다.

가상 단가 10만원에 수량 6개를 고르면 견적은 60만원이다. 부분 납품 상황에서 납품 확인까지 진행하면 3개가 납품되어 납품 기준 금액이 30만원이 된다. 수금 확인까지 가면 15만원을 받고 15만원이 남는다. 아직 납품하지 않은 3개도 따로 보인다.

수량 6개에서 1개 반품을 고르면 납품 기준 수량은 5개, 금액은 50만원이다. 취소는 주문 단계에서 멈추고 요청서 준비나 수금 단계로 넘어가지 않는다. 단순한 예시라도 남은 수량과 반품 수량, 받은 금액을 함께 보여 주어야 자신의 업무와 비교할 수 있다고 판단했다.

회사 맞춤을 메뉴와 항목의 선택으로 보여 주었다

회사 맞춤이라는 표현을 화면에서 설명하고 싶었다. 직원·담당자·대표를 선택하면 남는 항목이 달라진다. 직원은 오늘 처리할 주문과 품목을, 담당자는 요청서와 납기를, 대표는 금액 요약과 확인할 업무를 보는 방식이다.

납기일·현장 메모·재고 확인·승인 상태도 필요에 따라 추가할 수 있다. 거래처 중심, 현장 중심, 프로젝트 중심은 같은 업무를 어떤 기준으로 묶어 볼지 설명하는 예시다. 실제 질문이 생기면 이 구성은 더해 갈 수 있다.

역할을 바꾸는 동작은 공개된 가상 화면을 구성하는 체험이다. 실제 권한 서버에서 원가나 개인정보를 차단하는 기능을 검증한 것은 아니다. 실제 제작에서는 로그인과 데이터 접근 권한을 설계하고, 화면에서 숨기는 것과 API에서 조회를 거부하는 것을 각각 확인해야 한다.

기존 자료를 가져오는 장면에는 검토를 넣었다

새 프로그램을 쓰려면 기존 엑셀이나 문서가 어떻게 이어질지도 궁금할 수 있다. 미리 만든 가상 표 네 행에 중복된 자료 ID, 수량이 비어 있는 행, 준비 가능한 행을 섞었다. 수량 열을 잘못 연결하면 입력 가능 후보가 나오지 않게 했다.

이 동작은 실제 파일을 읽는 엑셀 가져오기 기능이 아니다. 이관 전에 어떤 검토가 필요한지 설명하는 모델이다. 실제 업로드가 없으며 검토 뒤에도 저장하지 않는다는 점을 표시했다. 검토와 이관의 완료를 한 단어로 약속하지 않으려 했다.

주문과 현황부터 시작하고 재고나 승인 같은 기능을 필요할 때 연결하는 예시도 넣었다. 구성을 고르면 이어지는 업무 설명이 달라진다. 실제 구축 범위는 기존 자료와 업무 순서, 권한을 살펴 정한다. 페이지에서 체크한 기능이 운영 시스템에 설치됐다고 해석되지 않게 설명했다.

다시 이어갈 상태를 공유 가능한 코드로 남겼다

최종 구현에서는 가상 장부·업무 상태·검증·금액 계산을 모델로 분리했다. 화면은 그 결과를 표현한다. 한국어·영어와 초기 HTML, 이후의 조작이 같은 계산을 이어 쓰도록 하려는 선택이었다. 문구를 바꾸는 일과 계산 규칙을 바꾸는 일의 위치도 분명해진다.

업무 체험에는 페이지 메모리에 상태를 백업하고 그 상태로 복구하는 버튼을 넣었다. 진행 단계를 백업한 뒤 처음으로 돌아갔다가 복구하면 수량·상황·진행 단계가 함께 돌아온다. JSON 다운로드에는 이 가상 업무 상태만 담는다.

복구할 때는 형식 표시, 가상 자료 표시, 허용된 필드와 값의 범위를 검사한다. 메모리 백업은 새로고침하면 사라진다. 실제 서비스의 영구 보관이나 회사 파일 복원 기능과는 범위가 다르다. 공유 모델 코드에서 계산과 상태 전환을 살펴볼 수 있게 했다.

버튼이 약속하는 일과 실제 동작을 맞췄다

문의는 반복 입력, 미수금·지급 예정 파악, 직원 업무와 대표 보고 연결 같은 문제에서 시작하게 했다. 선택한 문제에 맞는 이메일 초안을 만들고 방문자의 이메일 앱에서 직접 확인해 보내는 방식이다. 체험이 회사 실데이터를 받아 자동으로 외부에 보내지는 않는다.

공개 반영 검사에서는 검토한 HTML과 실제 응답의 이메일 표시가 달랐다. 기존 이메일 보호 처리가 주소와 링크를 변환하고 있었다. 보호 설정을 바꾸기보다 실제 목적지와 초안 내용을 확인해 비교했고, 체험 초기화 때도 올바른 초안 링크를 명시적으로 만들었다. 이 검사는 실제 메일 수신을 확인한 검사가 아니다.

통계에서도 체험 조작, 제작기 이동, 이메일 작성 의향을 나눴다. 수량이나 초안 본문을 보내는 대신 미리 정한 기능 이름만 집계한다. 이메일 앱을 열었다고 실제 문의가 도착한 것으로 세지 않는다. 어떤 설명을 보완할지 살필 준비를 했지만 방문자의 이해나 문의 성과가 개선됐다고 주장할 근거는 아직 없다.

확인한 범위를 공개 설명에 남겼다

코드에서는 수량 1~20, 네 가지 상황, 다섯 진행 단계의 400개 조합을 대조했다. 받은 금액과 미수금이 납품 기준 금액으로 이어지는지, 반품 뒤 수량과 금액이 음수가 되지 않는지, 취소 뒤 진행이 멈추는지 같은 관계를 확인했다. 화면 이벤트 연결은 최소 DOM 대역에서 별도로 검사했다.

공개 페이지에서는 한영 본문·정적 자산·체험 링크와 제작기 이동 경로를 확인했다. 새 페이지를 추가하면서 이전 콘텐츠가 바뀌지 않았는지도 비교했다. 콘텐츠·미디어·소스를 백업한 뒤 로컬 복구 검사를 거쳤고, 로컬 합성 자료에서는 통계 수집과 순서를 확인했다.

이 작업에서 실제 브라우저와 물리 기기의 화면 조작 검수는 수행하지 않았다. 반응형 규칙과 마크업·계산·이벤트 연결을 검사한 범위는 실제 휴대전화에서 키보드를 올려 조작한 범위와 다르다. 숫자의 정확성과 실제 사용성을 함께 완성하려면 그 차이를 기록해야 한다고 본다.

독자가 자기 회사의 질문을 꺼낼 수 있도록

이 페이지를 보고 모든 회사가 같은 구성을 원할 것이라고 생각하지는 않는다. 내가 만들고 싶었던 것은 자기 일을 대입할 출발점이다. 대표가 보는 숫자에서 직원의 다음 업무로, 기존 자료에서 새로운 구성으로 이어지는 관계가 보이면 무엇을 더 살펴야 할지 이야기하기 쉬워진다.

직접 구성한다면 대표가 매일 묻는 질문 하나와 직원이 반복하는 작업 하나를 적어 보면 좋겠다. 그 둘을 같은 자료로 연결할 수 있는지, 카드의 합이 세부 내역과 맞는지, 일부만 끝났을 때 남은 일을 설명할 수 있는지를 작은 가상 예시로 확인할 수 있다. 메뉴를 늘리는 결정은 그다음에 검토해도 된다.

제작 과정과 계산 원리는 충분히 공개하려 한다. 여기서 보인 판단을 자기 상황에 적용하는 데 도움이 되고, 실제 자료와 업무에 맞춘 구현이 필요하면 현재 불편한 점부터 이야기할 수 있으면 좋겠다. 이번 체험도 그 질문을 더 잘 듣기 위해 계속 다듬어 갈 페이지다.