레코드를 건드리지 않고 워크플로우 비즈니스 규칙 버전 관리하기
안전한 저장 패턴과 일관된 과거 동작을 유지하는 규칙 버전 관리 방법과 워크플로우를 위한 실용적 점진 마이그레이션 단계를 알아보세요.

규칙 변경이 이전 기록을 깨뜨리는 이유
워크플로우 규칙을 변경하면 앞으로는 더 나은 결정을 얻고 싶어집니다. 문제는 이전 레코드가 사라지지 않는다는 점입니다. 이전 레코드는 다시 열리고, 감사되고, 보고 대상이 되며 재계산됩니다.
문제가 되는 것은 대개 명백한 충돌이 아닙니다. 더 흔한 경우는 동일한 레코드가 지난달과는 다른 결과를 내는데, 이유는 오늘의 로직으로 평가되고 있기 때문입니다.
규칙 버전 관리는 동작을 일관되게 유지합니다: 새로운 작업에는 새로운 동작, 이전 작업에는 이전 동작. 레코드는 생성되었을 때나 결정이 내려졌을 때 유효하던 논리를 유지해야 하며, 정책이 나중에 바뀌어도 그 논리를 잃어선 안 됩니다.
몇 가지 유용한 용어:
- 규칙: 결정이나 계산(예: “$500 이하 자동 승인”).
- 워크플로우: 작업을 진행시키는 단계(제출, 검토, 승인, 지급).
- 레코드: 처리되는 저장된 항목(주문, 티켓, 클레임).
- 평가 시점: 규칙이 적용되는 순간(제출 시, 승인 시, 야간 작업).
구체적 예: 비용 처리 워크플로우에서 식대는 매니저 승인 없이 $75까지 허용되었고, 이를 $100으로 올렸다고 합시다. 과거 보고서를 새 한도로 평가하면 이전에 제대로 에스컬레이션되던 항목이 감사 로그에서 “잘못된 것”처럼 보일 수 있습니다. 승인 유형별 합계도 달라질 수 있습니다.
작게 시작해도 나중에 확장할 수 있습니다. 레코드가 워크플로우에 들어갈 때마다 “rule version 3” 같은 값을 저장하는 기본적인 접근만으로도 대부분의 놀라움을 방지할 수 있습니다.
실제 워크플로우에서 비즈니스 규칙으로 간주되는 것들
비즈니스 규칙은 워크플로우가 다음에 무슨 일을 할지, 무엇을 기록할지, 혹은 누군가에게 무엇을 보여줄지를 결정하는 모든 논리입니다. 한 줄의 논리를 바꾸는 것이 실제 케이스의 결과를 바꿀 수 있다면 버전 관리를 고려해야 합니다.
대부분의 규칙은 다음 범주에 속합니다: 승인 한도, 가격 및 할인(세금, 수수료, 반올림 포함), 적격성 검사(KYC, 신용, 지역, 플랜 수준), 라우팅(어떤 큐·팀·벤더로 보낼지), 타이밍(SLA, 기한, 에스컬레이션 규칙).
하나의 규칙이 여러 단계에 영향을 미치는 경우가 많습니다. 예를 들어 “VIP 고객” 플래그는 승인 경로를 바꾸고 응답 시간 목표를 단축하며 티켓을 특수 큐로 라우팅할 수 있습니다. 일부만 업데이트하면 동작이 맞지 않게 됩니다: 레코드는 VIP지만 에스컬레이션 타이머는 여전히 일반으로 취급할 수 있습니다.
숨겨진 의존성 때문에 규칙 변경이 고통스러워집니다. 규칙은 워크플로우 단계를 구동할 뿐만 아니라 보고서, 감사, 외부 메시지의 형성에도 영향을 줍니다. “배송비를 환불하는 시점”을 조금 바꾸는 것만으로도 재무 합계, 고객 이메일의 설명, 몇 달 뒤의 컴플라이언스 검토 기대치가 모두 바뀔 수 있습니다.
팀마다 영향이 다르게 느껴집니다:
- 운영팀: 예외와 수동 수정을 줄이는 것을 신경 씁니다.
- 재무팀: 금액의 정확성과 깔끔한 대조를 신경 씁니다.
- 고객지원: 일관된 설명을 원합니다.
- 컴플라이언스·감사: 무엇이 언제 왜 실행되었는지를 증명하는 것을 중요하게 생각합니다.
규칙 버전 관리는 단순한 기술적 세부사항이 아닙니다. 워크플로우를 발전시키면서도 일상 작업의 일관성을 지키는 방법입니다.
결정해야 할 핵심 설계 사항
규칙 버전 관리를 구현하기 전에 시스템이 다음 질문에 어떻게 답할지 정하세요: “이 레코드에 지금 어떤 규칙이 적용되어야 하는가?” 이 질문을 건너뛰면 변경이 테스트에서는 괜찮아 보였어도 감사나 엣지 케이스에서 실패합니다.
가장 중요한 세 가지 선택:
- 버전 선택 방법 (레코드에 고정, 날짜로 선택, 상태로 선택)
- 규칙을 언제 평가할지 (생성 시, 처리 시, 또는 둘 다)
- 버전 컨텍스트를 어디에 저장할지 (레코드 내부, 규칙 테이블, 이벤트/히스토리 로그)
시간은 팀을 혼란스럽게 만드는 부분입니다. created_at은 레코드가 처음 존재한 시점입니다. processed_at은 결정이 내려진 시점으로, 며칠 후일 수도 있습니다. created_at을 사용해 버전을 선택하면 요청이 접수되었을 때의 정책을 보존합니다. processed_at을 사용하면 승인자가 승인 버튼을 클릭했을 때의 정책을 반영합니다.
결정 가능성(Determinism)은 신뢰를 쌓습니다. 동일한 입력이 나중에 다른 출력으로 이어진다면 과거의 결과를 설명할 수 없습니다. 감사에 친화적인 동작을 위해서는 버전 선택이 안정적이어야 합니다. 레코드는 동일한 평가를 재실행해 동일한 결과를 얻을 수 있도록 충분한 컨텍스트를 담아야 합니다.
실무에서는 ExpenseApproval 같은 안정적인 규칙 키와 v1, v2, v3 같은 별도 버전을 유지합니다.
규칙 버전을 저장하는 방법: 세 가지 실용 패턴
놀라움 없는 버전 관리를 원하면 과거를 무엇으로 “잠그는지” 결정하세요: 레코드, 달력(시간), 또는 결과. 실제 시스템에서 다음 세 가지 패턴이 자주 사용됩니다.
패턴 1: 각 레코드에 버전 고정(pinned)
비즈니스 객체(주문, 클레임, 티켓)에 rule_version_id를 규칙이 처음 적용되는 순간에 저장하세요.
가장 단순한 모델입니다. 나중에 레코드를 확인할 때 동일한 버전을 다시 실행합니다. 모든 레코드가 자신이 사용한 정확한 규칙을 가리키므로 감사가 쉽습니다.
패턴 2: 유효 기간 사용(valid_from / valid_to)
레코드에 버전을 고정하는 대신, 시간으로 규칙을 선택합니다: “이벤트가 발생했을 때 활성화된 규칙을 사용하라.”
규칙이 모두에게 동시에 변경되고 트리거 순간이 명확할 때 잘 작동합니다(submitted_at, booked_at, policy_start). 어려운 점은 타임스탬프, 시간대, 어떤 순간을 진실로 볼지에 대해 정확해야 한다는 것입니다.
패턴 3: 평가된 결과(및 주요 입력) 스냅샷
결과가 절대 변하면 안 되는 결정(가격, 적격성, 승인)에 대해서는 결과와 사용된 주요 입력을 저장하세요.
나중에 규칙 로직, 룰 엔진, 데이터 모델이 바뀌어도 정확히 왜 그 결정이 났는지 보여줄 수 있습니다. 일반적인 하이브리드는 추적성을 위한 rule_version_id를 저장하고 영향이 큰 결정만 스냅샷으로 남기는 방식입니다.
간단한 비교 기준:
- 저장 비용: 스냅샷은 공간을 더 차지하고, 버전 ID와 날짜는 작습니다.
- 단순성: 레코드에 고정된 버전 ID가 가장 쉽고, 유효 기간은 정확한 타임스탬프가 필요합니다.
- 감사성: 스냅샷이 가장 강력하고, 버전 ID는 과거 로직을 여전히 실행할 수 있다면 충분합니다.
- 미래 대비: 규칙이나 코드가 크게 바뀌면 스냅샷이 보호막을 제공합니다.
과거 결과를 자신 있게 설명할 수 있게 해주는 가장 가벼운 옵션을 선택하세요.
과거 결과를 설명할 수 있도록 규칙 히스토리 모델링하기
규칙을 제자리에서 편집하는 것은 간단해 보이지만 위험합니다. 조건이나 임계값을 덮어쓰는 순간 다음과 같은 기본 질문에 답할 능력을 잃습니다: “왜 이 고객은 작년 3월에 승인되었는데 오늘은 거부되었는가?” 정확히 사용된 규칙을 재실행할 수 없다면 추측에 의존하게 되고 감사는 논쟁이 됩니다.
더 안전한 접근은 추가 전용(append-only) 버전입니다. 변경할 때마다 새 버전 레코드를 만들고 이전 버전은 그대로 두세요. 이것이 버전 관리의 핵심입니다: 오늘의 로직을 앞으로 진행시키되 어제의 것을 다시 쓰지 않습니다.
각 버전에 명확한 수명 주기 상태를 주어 무엇이 안전하게 실행 가능한지 알게 하세요:
- Draft: 편집·테스트·검토 중
- Active: 새로운 평가에 사용
- Retired: 새 작업에는 사용하지 않음, 기록용으로 보관
퍼블리싱은 우발적 저장이 아니라 통제된 행동이어야 합니다. 누가 변경을 제안하고, 누가 승인이 필요하며, 누가 버전을 Active로 만들 수 있는지 결정하세요.
각 버전에 평문(change notes)을 저장하세요. 미래의 독자가 다이어그램이나 코드를 읽지 않고도 무엇이 바뀌었는지 이해할 수 있어야 합니다. 버전마다 일관된 메타데이터를 유지하세요:
- 무엇이 바뀌었는가(한 문장)
- 왜 바뀌었는가(비즈니스 이유)
- 누가 언제 승인했는가
- 유효 시작일(및 선택적 종료일)
- 예상 영향(누가 영향을 받는가)
시간에 따른 과거 동작 일관성 유지하기
과거 일관성은 간단한 약속에서 시작합니다: 과거 레코드를 당시 방식대로 재평가하면 동일한 결과가 나와야 합니다. 이 약속은 규칙이 오늘의 데이터를 읽거나 외부 서비스를 호출하거나 평가 중에 작업을 트리거할 때 깨집니다.
평가 계약 정의하기
규칙이 의존할 수 있는 것(입력), 반환하는 것(출력), 절대 해선 안 되는 것(부작용)을 문서로 작성하세요. 입력은 케이스의 명시적 필드나 해당 필드의 스냅샷이어야 합니다. “고객 프로필이 지금 어떻게 보이는가”처럼 불명확한 것을 피하세요. 출력은 “approve/deny”, “필요한 승인자”, “리스크 점수”처럼 작고 안정적이어야 합니다.
평가를 순수하게 유지하세요. 평가 단계에서 이메일을 보내거나 결제를 생성하거나 테이블을 업데이트하면 안 됩니다. 그런 작업은 그 결정을 소비하는 워크플로우 단계의 몫입니다. 이 분리는 과거를 재실행해도 실제 현장 작업이 반복되는 일을 막아줍니다.
감사를 쉽게 하려면 모든 결정 이벤트에 세 가지 사실을 저장하세요:
- 평가 타임스탬프(규칙이 실행된 시점)
- 선택된 규칙 버전 식별자
- 사용된 정규화된 입력(또는 변경 불가능한 스냅샷에 대한 포인터)
누군가 “작년에 왜 이것이 승인되었나”라고 물으면 추측할 필요 없이 대답할 수 있습니다.
누락되거나 이후에 변경된 입력 처리
필요한 입력이 없는 경우 어떻게 할지 미리 결정하세요. “거짓으로 처리(treat as false)”와 “닫힘으로 실패(fail closed)”는 매우 다른 히스토리를 만듭니다. 규칙별로 한 가지 정책을 선택하고 버전 간에 안정적으로 유지하세요.
또한 이후 편집이 과거 결과를 바꿀지 여부를 결정하세요. 실용적인 접근은: 편집은 향후 새로운 평가를 촉발할 수 있지만 과거 결정은 원래 버전과 입력을 유지하게 하는 것입니다. 예를 들어 고객이 주문 승인 후 주소를 변경하면 배송 사기(fraud)를 재검토할 수는 있지만 원래 승인을 다시 쓰지는 않습니다.
단계별: 새 규칙 버전 안전하게 도입하기
안전한 규칙 변경은 명명으로 시작합니다. 각 규칙에 변경되지 않는 키(예: pricing.discount.eligibility 또는 approval.limit.check)를 부여하고 정렬 가능한 버전 체계(v1, v2 또는 날짜 2026-01-01)를 추가하세요. 키는 사람들이 규칙을 지칭하는 방식이고, 버전은 시스템이 무엇을 실행할지 결정하는 방법입니다.
버전 선택을 데이터에서 명시적으로 만드세요. 나중에 평가될 수 있는 모든 레코드(주문, 클레임, 승인)는 사용한 버전을 저장하거나 버전에 매핑되는 유효 날짜를 저장해야 합니다. 그렇지 않으면 결국 레코드를 새 로직으로 재실행해 결과를 조용히 변경하게 됩니다.
새 버전을 기존 버전 옆에 게시하세요. 오래된 버전을 제자리에서 편집하지 마세요, 작은 수정이라도 마찬가지입니다.
안전한 롤아웃은 보통 다음과 같습니다:
- v1을 유지하고 동일한 규칙 키 아래에 v2를 별도 버전으로 추가합니다.
- 새로 생성되는 레코드는 v2로 라우팅하고 기존 레코드는 저장된 버전을 유지하게 합니다.
- 승인율, 예외 수, 예기치 않은 결과를 모니터링합니다.
- 롤백은 규칙 편집이 아니라 라우팅 변경으로 수행하세요(v1로 다시 라우팅).
- 열린 상태이거나 다시 처리 가능한 레코드가 더 이상 v1에 의존하지 않을 때까지 v1을 은퇴시키지 마세요.
예: 구매 승인 한도가 $5,000에서 $3,000으로 바뀌면 새로운 요청만 v2로 라우팅하고 이전 요청은 v1에 남겨 두어 감사 기록이 일관되게 유지되도록 합니다.
위험을 줄이는 점진적 마이그레이션 전략
규칙 변경 시 가장 큰 위험은 조용한 변화(silent drift)입니다. 워크플로우는 계속 작동하지만 결과가 사람들이 기대하는 것과 서서히 달라집니다. 점진적 롤아웃은 커밋 전에 증거를 제공하고, 문제가 있으면 깔끔하게 되돌아갈 수 있는 방법을 줍니다.
새 규칙과 기존 규칙을 병행 실행하기
모두에게 스위치를 한 번에 켜는 대신, 오래된 규칙을 소스 오브 트루스로 유지하고 새 규칙을 병행 실행하세요. 작은 샘플로 시작해 결과를 비교하세요.
간단한 방법은 새 규칙이 무엇을 했는지 기록만 하고 최종 결과를 새 규칙이 결정하지 않게 하는 것입니다. 신규 승인 중 5%에 대해 두 결정을 모두 계산하고, 이전 결정, 새 결정, 이유 코드를 저장하세요. 불일치율이 예상보다 높으면 롤아웃을 중단하고 규칙을 수정하세요(데이터를 수정하지 마세요).
명확한 조건으로 트래픽 라우팅하기
기능 플래그나 라우팅 조건을 사용해 누가 어떤 버전을 쓰는지 제어하세요. 나중에 설명하기 쉽고 재현하기 쉬운 조건을 고르세요. 유효 날짜, 지역/사업부, 고객 등급, 워크플로우 유형이 복잡한 조건보다 보통 더 낫습니다.
백필(backfill) 처리를 어떻게 할지도 결정하세요. 과거 레코드를 새 규칙으로 재평가할지, 원래 결과를 유지할지 정하세요. 대부분의 경우 감사와 공정성을 위해 원래 결과를 유지하고 새 규칙은 새 이벤트에만 적용하세요. 과거 결과가 확실히 잘못되었고 명확한 승인 절차가 있다면 백필을 고려하세요.
짧은 마이그레이션 계획을 작성하세요: 무엇이 바뀌는지, 누가 검증하는지(운영, 재무, 컴플라이언스), 확인할 리포트, 그리고 정확한 되돌리는 방법.
조용한 데이터 버그를 일으키는 흔한 실수
대부분의 워크플로우 규칙 변경은 조용히 실패합니다. 아무 것도 충돌하지 않지만 숫자가 달라지거나, 고객에게 잘못된 이메일이 가거나, 몇 달 뒤 누군가 케이스를 열었을 때 그 케이스가 “틀려 보이는” 일이 발생합니다.
가장 큰 원인은 오래된 버전을 제자리에서 수정하는 것입니다. 빠른 것처럼 보이지만 감사 추적을 잃고 과거 결정의 이유를 설명할 수 없게 됩니다. 이전 버전은 읽기 전용으로 다루고 작은 수정이라도 새 버전을 만드세요.
또 다른 함정은 유효 기간에 의존하면서 시간에 대해 정확하지 않은 처리입니다. 시간대, 서머타임, 지연 실행되는 백그라운드 잡은 레코드를 잘못된 버전으로 밀어넣을 수 있습니다. 한 지역에서 00:05에 생성된 레코드가 다른 지역에서는 아직 “어제”일 수 있습니다.
주의해야 할 다른 조용한 버그 패턴:
- 규칙 변경 후 과거 레코드를 재평가하면서 재실행했다는 사실(어떤 버전을 사용했는지)을 기록하지 않음.
- 누가 왜 수동으로 덮어썼는지 저장하지 않고 규칙 로직과 수동 오버라이드를 섞음.
- 원래 결과에 의존하는 송장, 알림, 분석 같은 하류 영향력을 잊음.
- 멱등성(idempotency)을 깨서 재시도 시 두 번째 메시지 전송이나 중복 청구가 발생함.
- “현재 상태”만 저장하고 그 상태를 만들어낸 이벤트 히스토리를 잃음.
간단한 예: 승인 한도를 바꾸고 나서 야간 작업이 모든 열린 주문에 대해 “승인 필요”를 재계산합니다. 어떤 주문이 재계산되었는지 표시하지 않으면 고객지원은 지난주 고객이 본 결과와 다른 모습을 보게 됩니다.
규칙을 변경하기 전 빠른 체크리스트
규칙 변경을 배포하기 전에 어제 무슨 일이 있었는지, 내일은 무엇이 일어날지 증명할 방법을 결정하세요. 좋은 버전 관리는 화려한 로직보다 결정을 설명하고 재현할 수 있게 하는 것에 가깝습니다.
우선 레코드가 받은 결정을 어떻게 “기억”하는지 확인하세요. 주문, 티켓, 클레임이 나중에 재평가될 수 있다면 핵심 결정 지점(승인, 가격, 라우팅, 적격성)에 사용된 버전으로 명확한 포인터가 필요합니다.
체크리스트:
- 핵심 결정 지점을 지나는 모든 레코드에 규칙 버전과 결정 타임스탬프를 저장하세요.
- 규칙은 추가 전용으로 취급하세요: 새 버전을 발행하고 이전 버전은 읽기 전용으로 보관하며, 명시적으로 은퇴시키세요.
- 리포팅이 변경을 인식하게 하세요: 버전과 유효 날짜로 필터링해 “전”과 “후”를 섞지 않도록 합니다.
- 재현성 확인: 저장된 입력과 참조된 버전으로 과거 결정을 재실행하면 동일한 결과가 나와야 합니다.
- 롤백은 라우팅으로 계획하세요: 새 레코드를 이전 버전으로 라우팅해 히스토리를 다시 쓰지 마세요.
한 가지 더: 소유권을 부여하면 나중에 팀들이 절약됩니다. 승인과 문서화 책임자를 정하세요(또는 소규모 그룹). 무엇이, 왜 바뀌었는지, 어떤 레코드에 영향이 있는지 기록하세요.
예시: 히스토리를 다시 쓰지 않고 승인 워크플로우 업데이트하기
환불이 흔한 사례입니다. 이전에는 $200 초과 환불에 대해 매니저 승인을 요구했지만 정책이 바뀌어 임계값이 $150이 되었다고 합시다. 문제는 오래된 티켓이 아직 열려 있고 그들의 결정을 설명할 수 있어야 한다는 것입니다.
승인 로직을 버전화된 규칙 세트로 취급하세요. 새 티켓은 새 규칙을 사용하고 기존 티켓은 시작할 때 사용한 버전을 유지합니다.
다음은 각 케이스(또는 티켓)에 저장할 수 있는 작은 구체적 레코드 형태입니다:
case_id: "R-10482"
created_at: "2026-01-10T09:14:00Z"
rule_version_id: "refund_threshold_v1"
decision: "auto-approved"
이제 동작은 명확합니다:
- v1: amount > 200이면 매니저 승인
- v2: amount > 150이면 매니저 승인
지난주에 생성되어 rule_version_id = refund_threshold_v1인 티켓은 오늘 처리되더라도 $200 임계값으로 계속 평가됩니다. 롤아웃 이후에 생성된 티켓은 refund_threshold_v2를 받아 $150 임계값을 사용합니다.
고객지원이 감당할 수 있는 점진적 롤아웃
v2를 릴리스하되 먼저 소수의 신규 티켓(하나의 채널 또는 팀)에만 할당하세요. 지원 화면에는 사례에 버전과 평문 설명(예: “v1 임계값 $200”)이 표시되어야 합니다. 고객이 “왜 이것이 승인되었나요?”라고 물으면 담당자가 추측 없이 대답할 수 있습니다.
변경 후 측정할 항목
정책이 기대한 대로 작동하는지 확인하려면 몇 가지 신호를 추적하세요:
- 규칙 버전별 승인율(v1 vs v2)
- 에스컬레이션 및 매니저 큐 크기
- 감사 질문: “왜”를 묻는 빈도와 답변 속도
다음 단계: 워크플로우 프로세스에 버전 관리 도입하기
간단하게 시작하세요. 규칙의 영향을 받는 모든 레코드에 rule_version_id(또는 workflow_version) 필드를 추가하세요. 규칙이 바뀌면 새 버전을 만들고 이전 것을 삭제하지 말고 은퇴 표시만 하세요. 오래된 레코드는 워크플로우에 들어가거나 결정이 내려졌을 때 사용한 버전을 계속 가리키게 하세요.
이를 정착시키려면 규칙 변경을 임시 편집이 아닌 실무 프로세스로 다루세요. 간단한 규칙 레지스트리라도 도움이 됩니다(테이블이나 스프레드시트로 시작해도 좋음). 소유자, 목적, 짧은 변경 노트가 있는 버전 목록, 상태(draft/active/retired), 적용 범위(어떤 워크플로우와 레코드 타입인지)를 추적하세요.
복잡성이 커지면 필요할 때만 다음 계층을 추가하세요. 누군가 “그 날짜에 결정은 어땠을까?”라고 묻는다면 유효 날짜를 추가하세요. 감사인이 “어떤 입력이 사용되었나?”라고 묻는다면 규칙이 사용한 사실(핵심 필드, 임계값, 승인자 목록)의 스냅샷을 저장하세요. 변경이 위험하면 새 버전이 실환경에 적용되기 전에 승인 절차를 요구하세요.
팀이 속도는 유지하면서 히스토리를 잃고 싶지 않다면 노코드 플랫폼이 도움이 될 수 있습니다. AppMaster (appmaster.io)은 비즈니스 로직으로 완전한 애플리케이션을 구축하도록 설계되었으므로 규칙 레지스트리를 모델링하고 레코드에 버전 ID를 저장하며, 오래된 케이스를 원래 사용하던 논리에 묶어두면서 워크플로우를 진화시킬 수 있습니다.
자주 묻는 질문
규칙 버전 관리는 이전 기록이 생성되거나 결정되었을 때 적용되던 동일한 논리를 보존하도록 합니다. 버전 관리가 없으면 레코드를 다시 열거나 재계산할 때 원래와 다른 결과가 나와 감사나 보고에서 혼란이 생깁니다.
과거 레코드는 여전히 열리고, 감사되고, 재계산됩니다. 현재의 논리가 과거 사례에 적용되면 동일한 입력으로도 이전과 다른 출력이 나올 수 있어, 데이터 자체에 문제가 없더라도 결과가 달라 보일 수 있습니다.
실제 결과를 바꿀 수 있는 모든 논리는 버전 관리 대상입니다. 흔한 예로 승인 한도, 가격·세금 계산, 적격성 판정, 팀·벤더로의 라우팅, SLA 같은 타이밍 규칙이 있습니다.
레코드에 rule_version_id를 고정하는 방식은 각 레코드가 규칙을 처음 적용받을 때 해당 버전을 저장하고 이후 항상 그 버전을 재실행합니다. 반면 유효 기간(effective dates)은 제출 시점이나 결정 시점 같은 타임스탬프를 기준으로 버전을 선택하며, 정확한 시간 처리가 요구됩니다.
‘제출된 시점(policy as filed)’을 원하면 생성/제출 시점(created/submitted time)을 기준으로 버전을 선택하세요. ‘결정된 시점(policy as decided)’을 원하면 승인자가 조치를 취한 시점(processed_at)으로 선택하세요. 일관되게 사용하고 평가 시간을 기록해 설명할 수 있어야 합니다.
결정이 이후 절대 바뀌어서는 안 되는 경우(최종 가격, 적격성, 승인 등)에는 결과와 핵심 입력을 스냅샷으로 저장하세요. 이렇게 하면 규칙 로직이나 데이터 모델이 바뀌어도 과거의 결정을 설명할 수 있습니다.
규칙 버전은 덧붙이는 방식(append-only)으로 관리해 이전 버전을 덮어쓰지 마세요. 각 버전에 draft, active, retired 같은 상태를 부여하고, 퍼블리싱은 의도적인 절차로 처리하세요.
평가는 부작용이 없어야 합니다. 즉, 결정만 반환하고 이메일 발송, 카드 결제, 테이블 업데이트 같은 작업은 하지 마세요. 워크플로우의 소비 단계가 그 결정을 받아 실제 작업을 수행하도록 분리하면 과거 결정을 재실행해도 실제 작업이 반복되지 않습니다.
새 규칙을 전면 적용하기 전에 소량의 레코드에서 병행 실행해 보세요. 새 규칙이 실제로 무엇을 결정했는지 기록하고 불일치 비율을 확인해 문제를 고친 뒤 확장하면 안전합니다.
핵심 의사결정 지점을 지나는 레코드에 rule_version_id와 결정 타임스탬프를 저장하는 것부터 시작하세요. AppMaster (appmaster.io) 같은 노코드 플랫폼에서는 규칙 레지스트리를 모델링하고 레코드에 버전 컨텍스트를 저장하며, 오래된 사례를 원래 사용하던 버전에 묶어두면서 워크플로우를 발전시킬 수 있습니다.


