계산 로직에 버그가 있었고, 이미 그 결과가 데이터베이스에 저장돼 있습니다. 로직을 고치는 것은 쉽지만, 이미 저장된 과거 결과는 저절로 바뀌지 않습니다. 이 글은 그 간극을 메우는 정산 재계산 설계를, 다지점 방문 케어 서비스 프랜차이즈의 급여 정산 자동화 사례를 기준으로 정리합니다.
정산 재계산이 필요한 이유
정산 재계산은 단가나 계산 로직을 고친 뒤, 이미 저장된 과거 정산을 현재 규칙으로 다시 계산해 정정하는 일입니다. 급여·정산처럼 계산 결과를 저장해 두는 시스템에서는, 로직 수정과 저장된 데이터 사이에 항상 간극이 생깁니다. 이 간극을 사람이 손으로 메우면 건수만큼 오류가 늘어나므로, 시스템이 일괄로 메우게 만듭니다.
핵심 원칙은 **"입력은 보존하고 파생만 다시 계산한다"**입니다. 정산에서 사람이 확정한 사실(어떤 관리사가 어떤 서비스를 몇 건 했는가)은 그대로 두고, 규칙에 따라 파생되는 값(단가·소계)만 현재 설정으로 다시 계산합니다. 건수를 다시 세지 않기 때문에, 재계산이 원본 사실을 훼손하지 않습니다.
재계산의 동작: 건수는 보존, 단가만 다시
재계산 API는 다음 순서로 동작합니다. 저장된 급여 항목(관리사·서비스·건수)을 읽고, 현재 관리사 단가표를 조회해, 각 항목의 단가를 다시 적용한 뒤 소계를 새로 냅니다. 그리고 기존 항목을 지우고 새 값으로 한 번에 다시 넣습니다.
건수는 보존하고 단가·소계만 다시 계산해 멱등하게 치환합니다
count(건수)는 손대지 않고 unit_price와 subtotal만 다시 계산하는 것이 요점입니다. 삭제 후 일괄 삽입(delete + insert)으로 처리하면, 같은 정산에 재계산을 여러 번 돌려도 결과가 같은 멱등 치환이 됩니다.
항목을 한 줄씩 수정하지 않고 일괄 삭제 후 한 번에 삽입하는 데는 실용적 이유도 있습니다. 이 API는 Cloudflare Workers 위에서 도는데, 한 요청이 외부(데이터베이스)로 보내는 호출 수에 제약이 있습니다. 건마다 개별 update를 보내면 138건이면 138번의 호출이 되지만, 삭제 1회 + 일괄 삽입 1회로 묶으면 건수와 무관하게 두 번의 호출로 끝납니다. 재계산 비용이 건수에 비례하지 않는 것은 사용자 경험만이 아니라 실행 구조에서도 그렇습니다.
왜 "확정 전"에만 안전한가
재계산에는 경계가 있어야 합니다. 이 사례의 정산은 draft → confirmed → sent 상태로 흐르는데, 재계산은 확정(confirmed) 전 draft 정산에만 적용하는 것이 안전합니다. 이미 확정하고 관리사에게 명세서를 보낸 정산을 조용히 바꾸면, 발송된 문서와 데이터가 어긋나기 때문입니다.
| 상태 | 의미 | 재계산 |
|---|---|---|
| draft | 작성 중 | 안전하게 재계산 가능 |
| confirmed | 확정·잠금 | 되돌리려면 확정 해제(unconfirm)부터 |
| sent | 명세서 발송 완료 | 함부로 바꾸지 않음 |
즉 "확정은 잠금"이라는 불변성과 "확정 전은 자유롭게 재계산"이라는 유연성을 상태로 분리합니다. 확정 정산의 불변성을 지키는 반대 각도의 설계는 정산 확정 후 잠금을 다루는 글에서 이어지며, 이 사례에서는 그 반대편, 즉 확정 전 정산을 안전하게 재계산·정정하는 쪽을 설계했습니다.
이 경계가 없으면 재계산 기능은 오히려 위험한 도구가 됩니다. "다시 계산해서 맞추면 되지"라는 생각으로 확정된 정산까지 재계산 대상에 넣으면, 이미 관리사에게 전달된 명세서의 숫자와 시스템 안의 숫자가 조용히 달라질 수 있습니다. 재계산은 강력한 만큼, 어디까지 적용할 수 있는지를 상태값 하나로 명확히 막아두는 게 기능 자체보다 더 중요한 설계 결정입니다.
이 재계산이 실제로 만든 결과가 정산 자동화 ROI 사례이고, 전체 파이프라인은 급여 정산 자동화 사례에서 볼 수 있습니다.
자주 묻는 질문
로직을 수정한 뒤 이미 저장된 계산을 어떻게 정정하나요?
저장된 입력(건수)은 그대로 두고, 현재 단가·규칙으로 파생값(단가·소계)만 다시 계산합니다. 기존 항목을 지우고 새 값으로 한 번에 다시 넣어, 여러 번 실행해도 결과가 같은 멱등 치환으로 처리합니다.
왜 확정 전 정산만 재계산하나요?
이미 확정하고 명세서를 발송한 정산을 조용히 바꾸면, 발송된 문서와 데이터가 어긋나기 때문입니다. 그래서 재계산은 draft(작성 중) 정산에만 적용하고, 확정된 정산은 확정 해제부터 거치도록 상태로 분리합니다.
재계산이 원본 데이터를 훼손하지 않나요?
훼손하지 않습니다. 사람이 확정한 사실인 건수는 다시 세지 않고 보존하며, 규칙으로 파생되는 단가·소계만 다시 계산합니다. 입력과 파생을 분리했기 때문에 재계산이 원본 사실을 바꾸지 않습니다.
여러 번 재계산해도 괜찮은가요?
괜찮습니다. 삭제 후 일괄 삽입 방식이라 같은 정산에 재계산을 반복해도 항상 같은 결과가 나옵니다. 이 멱등성 덕분에 재계산을 안심하고 여러 번 실행할 수 있습니다.