콘텐츠로 이동

전자결재 — 결국 "사건 → 판단 → 사람의 승인"이었다

전자결재는 우리가 만든 네 개의 핵심 모듈 가운데 AI 에이전트의 작동 방식에 가장 가까운 시스템이었습니다. 만들고 나서야 깨달았습니다 — 전자결재는 결재 도장을 디지털로 옮긴 게 아니라, “사건이 일어나면 시스템이 흐름을 판단하고, 마지막 결정은 사람이 내린다”는 에이전트의 원형(原型) 그 자체였다는 것을. 양식 11종을 만드는 줄 알았던 작업이 실은 **상태(state)와 전이(transition)**를 다루는 일이었다는, 그 반전의 기록입니다.

SL.AIMS 전자결재 문서함 — 문서번호·종류(품의서·자금일보·출장신청서·연차계)·상태(승인 완료·반려)·현재 단계(1~3단계)·작성일 열로 구성된 목록
실제 전자결재 문서함. 제목·기안자는 가렸지만, 이 글이 말하는 골격이 그대로 드러납니다 — 양식은 제각각이어도 모두 종류 → 상태 → 현재 단계라는 하나의 흐름 위에 있습니다. 색 배지(승인 완료·반려)와 단계(1·2·3)가 곧 상태 머신입니다.

회사에서 돈을 쓰거나, 휴가를 가거나, 물건을 사거나, 출장을 가려면 보통 “윗선의 허락”이 필요합니다. 종이 시절에는 결재판에 서류를 끼워 부서장 책상에 올려 두고, 도장을 받아 다음 사람에게 넘겼습니다. 전자결재는 이 과정을 화면 안으로 옮긴 것입니다. 신청서를 쓰고(상신), 정해진 사람들이 순서대로 보고, 승인 도장을 찍거나 반려합니다.

구매요청서, 지출결의서, 출장신청서, 연차신청, 법인카드 사용, 견적서, 공문서, 업무보고서, 회의록… 양식은 11종이 넘습니다. 하지만 회사의 거의 모든 업무는 결국 한 문장으로 수렴합니다 — “누군가 신청하고, 누군가 승인한다.” 이 공통 골격을 보는 순간, 만들어야 할 것이 “11개의 서로 다른 화면”이 아니라 “1개의 흐름 엔진 + 11개의 서식”이라는 게 분명해졌습니다.

업무 성격대표 양식(예)공통 골격
돈을 쓰는 일지출결의서 · 법인카드 · 구매요청서신청 → 결재선 → 승인/반려
자리를 비우는 일연차신청 · 출장신청서신청 → 결재선 → 승인/반려
알리고 보고하는 일공문서 · 업무보고서 · 회의록 · 견적서신청 → 결재선 → 승인/반려

표에서 보듯, 양식의 칸은 제각각이어도 흐름은 하나입니다. 그래서 “양식마다 따로 만들기”가 아니라 “흐름은 공유하고 칸만 갈아 끼우기”로 설계의 방향을 잡았습니다. 새 양식을 추가하는 일이 “또 하나의 화면을 짜는 일”이 아니라 “서식 정의 한 벌을 등록하는 일”이 되도록.

2. 왜 외주를 끊고 직접 만들었나

섹션 제목: “2. 왜 외주를 끊고 직접 만들었나”

원래는 외주 전자결재(메신저와 묶인 패키지)를 쓰고 있었습니다. 빠르고 편했습니다. 그런데 우리가 지향하는 방향 — 사람이 데이터를 떠먹이는 ERP가 아니라, 에이전트가 사건을 감지해 먼저 일하고 사람은 승인만 하는 ERP — 에서 보면 외주 결재는 치명적인 한계가 있었습니다. 우리 업무 흐름과 깊게 엮을 수 없다는 것이었습니다.

결재는 회사 업무의 길목입니다. 출퇴근 정정도, 구매도, 휴가도 전부 이 길목을 지납니다. 그 길목을 외주의 닫힌 상자 안에 두면, 나중에 에이전트가 그 흐름에 끼어들 자리가 없습니다. 업무의 심장은 직접 쥔다는 원칙에 따라, 전자결재는 직접 만들기로 했습니다.

3. 진짜 어려운 건 양식이 아니라 “상태”였다

섹션 제목: “3. 진짜 어려운 건 양식이 아니라 “상태”였다”

처음엔 “양식 11개 만들면 끝”이라고 생각했습니다. 완전히 틀렸습니다. 양식은 입력 칸의 모음일 뿐입니다. 진짜 어려운 건 문서가 살아 움직이는 방식, 즉 상태였습니다.

문서 하나가 작성(DRAFT) → 상신(SUBMITTED) → 결재중(IN_APPROVAL) → 승인(APPROVED) 또는 반려(REJECTED)로 흐릅니다. 결재선이 여러 단계면 “결재중” 상태가 한참 이어집니다. 문제는, 코드 곳곳에서 제멋대로 상태를 바꾸기 시작하면 금세 엉망이 된다는 것입니다. 어떤 화면은 반려된 문서를 다시 승인 가능하게 만들고, 어떤 처리는 완료된 문서를 슬쩍 작성중으로 되돌립니다. 그렇게 무결성이 무너집니다.

문서가 거치는 상태와, 허용된 전이만 작성중 DRAFT 상신됨 SUBMITTED 결재중 IN_APPROVAL ↻ 승인됨 APPROVED 다단계 반복 반려됨 REJECTED · 종착 취소됨 · 종착 CANCELED 재오픈 REOPENED ✗ 금지: 승인됨 → 작성중 (완료 문서 직접 되돌리기) 승인 후엔 오직 취소·재오픈으로만. 반려·회수·취소는 종착(terminal) — 더 못 돌린다.
전자결재 문서의 상태 전이도. 파랑=진행, 주황=조건부, 초록=완료, 빨강=종착. 핵심은 "승인됨"에서 거꾸로 작성중으로 가는 길이 막혀 있다는 것. 한번 끝난 결재는 함부로 못 되돌립니다.

4. 처방: 모든 상태 변경은 단 하나의 문(門)을 통과한다

섹션 제목: “4. 처방: 모든 상태 변경은 단 하나의 문(門)을 통과한다”

그래서 규칙을 하나로 못 박았습니다. 상태를 바꾸려는 모든 코드는, 쓰기 직전에 단 하나의 “전이 심판관(state machine)“을 거쳐야 한다. 심판관은 단순한 질문 하나를 합니다 — “지금 이 전이(예: 결재중 → 승인됨)가 허용 목록에 있는가?” 없으면 막습니다.

// 개념 예시 — 상태를 쓰기 직전, 한 곳에서 검문
assertStateTransition(현재상태, 바꿀상태); // 불법 전이면 여기서 거부
// '승인됨' → '취소됨' ✅ 허용
// '승인됨' → '작성중' 🚫 거부 (완료 문서 직접 되돌리기 금지)
// '반려됨' → 무엇이든 🚫 거부 (종착 상태)
문서.status = 바꿀상태; // 통과해야만 여기 도달

5. 완료된 문서는 절대 못 고친다 — 왜 그렇게까지

섹션 제목: “5. 완료된 문서는 절대 못 고친다 — 왜 그렇게까지”

전자결재는 단순한 메모가 아니라 법적 효력을 갖는 기록입니다. 결재가 끝난 지출결의서의 금액을 나중에 슬쩍 고칠 수 있다면, 그 결재는 법적으로 무의미해집니다. “승인받았다”는 사실 자체를 믿을 수 없게 됩니다.

같은 정신이 두 곳에 더 적용됐습니다.

  1. 전자서명 — 한번 기록된(RECORDED) 서명은 “삭제”가 아니라 “무효화(REVOKE) 기록 추가”만 됩니다. 서명을 지우는 게 아니라, 무효화했다는 사실을 또 하나의 기록으로 남깁니다. 전자서명법의 정신을 그대로 코드에 옮긴 것입니다.
  2. 마감기간 — 회계 마감이 끝난 기간의 문서는 재오픈 자체를 거부합니다. 마감된 장부를 함부로 다시 여는 건 회계 감사에서 치명적이기 때문입니다.
대상금지한 것이유
승인 완료 문서 본문몰래 수정법적 효력 상실
반려·회수·취소된 문서다시 살리기종착 상태 — 흐름의 명확성
전자서명 이력삭제전자서명법 — 무효화 기록만
마감기간 문서재오픈회계 감사 무결성

6. 그리고 출퇴근이 결재와 만났다

섹션 제목: “6. 그리고 출퇴근이 결재와 만났다”

가장 인상적이었던 순간은 출퇴근 정정 요청을 전자결재에 통합했을 때였습니다. 사무직 직원이 “어제 퇴근 시각이 잘못 찍혔어요”라고 정정을 신청하면, 같은 트랜잭션 안에서 전자결재 문서가 자동으로 생성되어 결재선을 탑니다. 최종 승인이 떨어지는 순간 근태 데이터에 정정이 반영됩니다.

  1. 직원이 모바일에서 근태 정정을 신청합니다.
  2. 시스템이 같은 작업 단위 안에서 “정정 결재 문서”를 자동 생성하고 결재선을 붙입니다.
  3. 결재자가 승인/반려합니다(사람의 판단).
  4. 승인 시점에만, 한 번만(중복 방지 가드) 근태가 실제로 고쳐집니다.

핵심은 정정이 “별도의 수정 기능”이 아니라 **“결재 흐름을 탄 사건”**이 됐다는 것입니다. 누가, 언제, 무엇을, 왜 고쳤는지가 결재 기록으로 영구히 남습니다. 단일 백엔드 위에서 모듈이 한 데이터를 공유하기에 가능한 일이었습니다.

7. 다 만들고 나서 본 것 — 에이전트의 원형

섹션 제목: “7. 다 만들고 나서 본 것 — 에이전트의 원형”

완성하고 나서야 구조가 눈에 들어왔습니다. 전자결재의 골격은 우리가 지향하는 AI 에이전트와 똑같았습니다.

같은 골격, 다른 이름 전자결재 문서 상신 결재선 흐름 사람이 승인/반려 AI 에이전트 사건 감지 판단·제안 사람이 승인(HITL)
위는 전자결재, 아래는 에이전트. 사건 → 판단 → 사람의 승인이라는 골격이 같습니다. 우리는 에이전트를 "새로" 만든 게 아니라, 결재에서 이미 그 형태를 연습하고 있었습니다.

그래서 AI를 붙일 때도 같은 안전 원칙을 그대로 가져왔습니다 — 에이전트의 자율 행동은 기본적으로 꺼져 있고, 사람의 결재로만 켜집니다. 모든 판단은 근거(Evidence)와 함께 기록으로 남습니다. 결재가 “함부로 안 고친다 / 한 곳에서 강제한다 / 흔적을 남긴다”였듯, 에이전트도 같은 규율 위에 세웠습니다.


이 글은 SL.AIMS를 만들며 겪은 현장 회고 중 하나입니다. 전체 그림은 〈사례연구: SL.AIMS〉에 있습니다.