일본의 의료 청구 시스템은 연령별 규칙, 소득별 본인 부담금, 공공 보조금, 고액 의료비 상한제, 희귀 질환 지원금 등 여러 보험 시스템이 복잡하게 얽혀 있어 계산이 매우 어렵습니다. DENTIS는 이러한 복잡성을 해결하기 위해 Ruby를 활용하여 다음과 같은 기술적 접근 방식을 채택했습니다.
1. 복잡한 일본 치과 청구 시스템 모델링
-
보험 모델링: 환자당 단일 보험 대신 시간 기반 기록으로 보험을 모델링합니다. 각 보험 및 공공 지원금 항목은 시작일, 종료일, 본인 부담률, 소득 범주, 고액 계산 규칙을 포함합니다.
-
청구 처리: 청구 시 해당 날짜에 활성화된 모든 보험 및 보조금을 선택하고, 지불자 조합을 구성하며, 정책 규칙을 적용하고, 비용을 할당하여 최종 환자 부담 금액을 계산합니다. 이는 실제 정책 로직을 반영하는 Ruby 기반 도메인 엔진으로 구현되었습니다.
2. ActiveRecord 콜백의 한계와 워크플로우 엔진 도입
-
콜백의 문제점: 초기 DENTIS는 ActiveRecord 콜백을 사용하여 비즈니스 로직을 구현했으나, 단일 의료 행위가 점수 재계산, 구강 상태 변경, 보험 재평가, 청구 재계산 등 수많은 연쇄 반응을 일으켜 숨겨진 실행 순서, 순환 종속성, 예측 불가능한 부작용을 초래했습니다.
-
Interactor 기반 워크플로우: 팀은 콜백 대신 클린 아키텍처의 오케스트레이션 계층인 Interactor를 도입했습니다. 각 비즈니스 액션은 트랜잭션 안전 파이프라인(예: 치료 추가 → 유효성 검사 → 보험 확인 → 치아 업데이트 → 보철물 업데이트 → 점수 재계산 → 수정자 적용 → 영구 저장 → 알림)으로 구성됩니다. 이는 명시적인 실행 순서, 실패 시 전체 롤백, 격리된 비즈니스 규칙, 예측 가능한 동작을 제공하며, Ruby의 표현력 덕분에 규제 변화에도 불구하고 워크플로우를 가독성 높고 유지보수하기 쉽게 만듭니다.
3. 치아 상태 이력 관리의 복잡성 해결
-
치아 도메인의 도전: 치아는 발치, 충전, 크라운, 분할, 이식 등 다양한 상태 변화를 겪으며, 보험 적용은 각 날짜의 정확한 치아 상태에 따라 달라집니다.
-
스냅샷 시스템의 실패: 초기에는 모든 변경 후 전체 치아 스냅샷을 저장했으나, 과거 치료가 수정될 경우 모든 미래 스냅샷이 잘못되어 이력 수정이 계산적으로나 논리적으로 불가능해지는 문제가 발생했습니다.
-
이벤트 기반 치아 시스템: 최종 해결책은 각 치아가 자체 이벤트 이력(치아 ID, 상태, 타임스탬프, 순서, 연결된 치료)을 저장하는 것이었습니다. 특정 날짜의 구강 상태를 재구성하기 위해 SQL은 해당 날짜 이전의 각 치아에 대한 최신 기록을 선택합니다. 이는 Rails와 PostgreSQL을 통해 완전히 구현된 이벤트 소싱, 시간적 쿼리, 완전한 이력 정확성을 제공합니다.