헬스케어 앱을 위한 예약 시스템 최적화 도구: Michel Gem 공개

Announcing Michel: A scheduling gem for health tech

작성자
발행일
2026년 02월 07일

핵심 요약

  • 1 기존 EHR 시스템의 API는 실제 예약 가능한 시간 슬롯이 아닌 주간 일정 정보만 제공하여 개발자가 직접 가용 시간을 계산해야 하는 기술적 부채를 발생시킵니다.
  • 2 Ruby 애플리케이션 레벨에서 반복문을 통해 가용 시간을 계산하는 비효율적인 방식을 탈피하고 PostgreSQL의 강력한 시간 범위 쿼리 기능을 활용하여 성능을 최적화했습니다.
  • 3 새롭게 공개된 Michel Gem은 Scenic을 기반으로 구체화된 뷰(Materialized View)를 생성하여 대규모의 예약 가능 시간 슬롯을 빠르고 효율적으로 조회할 수 있게 지원합니다.

도입

헬스케어 기술 분야에서 환자가 직접 진료를 예약하는 기능은 필수적이지만, 기술적으로는 매우 까다로운 과제 중 하나입니다. 대다수의 전자 건강 기록(EHR) 시스템은 의료진의 전체 일정만 제공할 뿐, 실제 예약 가능한 세부 시간 슬롯을 계산하여 제공하지 않기 때문입니다. 이 글에서는 thoughtbot이 이러한 스케줄링 병목 현상을 해결하기 위해 개발한 새로운 오픈소스 라이브러리인 'Michel' Gem의 탄생 배경과 그 기술적 해결책을 소개하며, 데이터베이스 중심의 성능 최적화 방안을 제시합니다.

헬스케어 스케줄링의 근본적인 문제점

헬스케어 애플리케이션 개발 시 가장 빈번하게 마주치는 난관은 예약 시스템 구축입니다. 특히 환자가 직접 진료 시간을 선택하는 ‘셀프 스케줄링’ 기능은 운영 효율성을 높이는 핵심 요소이지만, 이를 구현하기 위해서는 단순한 일정 표시 이상의 정교한 계산이 필요합니다. 대부분의 개발자는 기존의 전자 건강 기록(EHR) 시스템과 통합을 시도하는데, 여기서 큰 오해가 발생합니다. EHR API가 제공하는 ‘제공자 가용성(Provider Availability)’ 데이터는 실제 예약 가능한 ‘시간 슬롯’이 아니라, 의료진의 ‘주간 근무 시간표’인 경우가 많기 때문입니다.

기존 방식의 한계와 기술적 병목

전통적인 방식에서는 병원 직원이 전체 달력을 보며 빈 시간을 직접 찾아 환자에게 제안합니다. 하지만 시스템이 이 역할을 대신하려면, 특정 시간 범위 내에서 이미 예약된 시간을 제외하고 남은 빈 블록을 찾아 적절한 시작 시간을 계산해야 합니다. 예를 들어, 15분만 비어 있는 시간에 30분짜리 진료를 예약할 수 없으며, 오후 3시 17분과 같은 비정상적인 시작 시간을 피해야 합니다.

초기에는 이러한 로직을 Ruby 애플리케이션 코드에서 처리하려고 시도했습니다. 데이터베이스에서 예약 정보와 의료진 일정을 가져와 루프를 돌며 가용 시간을 계산하는 방식이었으나, 이는 데이터 양이 많아질수록 급격히 느려지는 성능 저하를 초래했습니다. 단순한 인덱싱이나 복잡한 알고리즘 논문을 적용하는 것만으로는 실질적인 해결책을 찾기 어려웠습니다.

PostgreSQL과 Materialized View를 활용한 최적화

thoughtbot 팀은 이 문제를 해결하기 위해 데이터베이스 계층으로 시선을 돌렸습니다. PostgreSQL은 타임스탬프와 범위(Range)를 쿼리하는 정교한 기능을 갖추고 있습니다. 이를 활용하여 향후 6개월 동안의 모든 의료진에 대한 예약 가능 슬롯을 미리 계산하고, Scenic Gem을 사용하여 ‘구체화된 뷰(Materialized View)’로 저장하는 방식을 채택했습니다.

이 방식의 핵심 장점은 다음과 같습니다: * 속도: Ruby에서 수많은 리스트를 순회하는 대신, 데이터베이스 수준에서 인덱싱된 뷰를 조회하므로 응답 속도가 비약적으로 향상됩니다. * 효율성: 예약 테이블에 의료진과 시간 범위에 대한 인덱스를 추가함으로써, 뷰를 갱신하는 속도 또한 매우 빠르게 유지할 수 있습니다. * 정확성: 복잡한 시간 계산 로직이 데이터베이스 엔진 내에서 처리되어 데이터의 정합성을 보장하기 용이합니다.

Michel Gem의 탄생과 활용

이러한 기술적 성과를 바탕으로 추출된 것이 바로 ‘Michel’ Gem입니다. Michel은 기존 애플리케이션의 예약(Booking), 의료진(Provider), 일정(Schedule) 클래스를 기반으로 구체화된 뷰 기반의 모델을 자동으로 생성해 주는 제너레이터를 제공합니다.

개발자는 새로운 예약이 생성되거나 의료진의 일정이 변경될 때마다 이 뷰를 새로고침(Refresh)하기만 하면 됩니다. 이를 통해 항상 최신 상태를 유지하면서도 매우 빠른 속도로 예약 가능한 시간 슬롯을 조회할 수 있는 강력한 인프라를 갖추게 됩니다. Michel은 헬스케어 분야의 특수한 요구사항을 충족하면서도 범용적인 예약 시스템의 성능 문제를 해결하는 훌륭한 도구입니다.

결론

Michel Gem은 단순히 스케줄링 기능을 제공하는 것을 넘어, 데이터베이스의 고급 기능을 활용하여 애플리케이션의 성능 문제를 해결하는 우수한 사례를 보여줍니다. 특히 PostgreSQL의 시간 범위 처리 능력과 Scenic의 뷰 관리 기능을 결합함으로써, 복잡한 비즈니스 로직을 효율적인 데이터 조회 구조로 변환했습니다. 헬스케어 서비스뿐만 아니라 복잡한 예약 시스템을 구축해야 하는 모든 Ruby on Rails 개발자들에게 Michel은 인프라 비용을 줄이고 사용자 경험을 개선할 수 있는 강력하고 신뢰할 수 있는 도구가 될 것입니다.

댓글 1

댓글 작성

댓글 삭제 시 비밀번호가 필요합니다.

이미 계정이 있으신가요? 로그인 후 댓글을 작성하세요.

0/1000
정중하고 건설적인 댓글을 작성해 주세요.
J
jeff
8시간 전
타임테이블 기반으로 예약 시스템을 만들때 써먹을 수 있을듯