선택 프로젝트 — 주요 경력 프로젝트
임상 안전성 사례 관리 플랫폼
임상시험 중 발생하는 안전성 사례를 등록·검토하고 진행 상태와 후속 업무를 관리하는 서비스입니다. 많은 정보를 다루는 사용자가 필요한 정보를 빠르게 판단하고 업무를 이어갈 수 있도록 효율적인 화면 구조와 인터랙션을 설계했습니다.
코어 프론트엔드 · 전체 2,010커밋 중 1,025건(51%), 이슈 247건 · 타임라인 엔진과 AI Studio 단독 구현/2022.12 – 현재/Next.js 12 / React 18 / TypeScript / MUI 5 / Recoil / React Query v3 / SSE

01 / 03
투약과 이상사례를 한 축에 놓는 타임라인
사례 한 건을 규제 데이터 모델(E2B)에 맞춰 검토하는 화면입니다. 섹션은 위쪽 탭으로 옮기고, 의약품·MedDRA 버전·제출 상태처럼 어느 섹션에서든 필요한 값은 왼쪽 요약에 고정해 검토자가 맥락을 잃지 않게 했습니다. 타임라인은 차트 라이브러리 없이 SVG로 직접 그렸습니다 — 투약 기간과 이상사례가 겹치는 구간을 표로 읽지 않고 눈으로 보게 하려는 목적이고, 아직 끝나지 않은 사례는 막대 끝을 화살표로 열어 두어 구분합니다. 사례 번호·환자·의약품명은 모두 지어낸 값입니다.
해결한 문제
- 의약품 이상사례와 투약 기간 사이의 인과관계를 시계열로 보여줘야 했습니다. 외부 차트 라이브러리는 번들만 무겁고, 구간이 여러 겹 겹칠 때 레이아웃 계산이 깨졌습니다.
- 규제기관에 내는 서식은 화면에서 보기 좋은 것으로는 부족하고 종이에 정확히 찍혀야 합니다. 그런데 브라우저 인쇄는 화면과 규칙이 달라서, 머리말·꼬리말이 통째로 사라지거나 1px 미만 선이 지워지고 표가 페이지 경계에서 잘렸습니다.
내가 기여한 것
- 차트 의존성을 걷어내고 순수 SVG 타임라인(간트) 컴포넌트를 직접 만들었습니다. X축 도메인을 2-pass로 계산하고 선형 시간 스케일과 ResizeObserver를 붙여, 이벤트가 수백 건이어도 60fps를 유지합니다.
- AI Studio — 대화로 케이스를 만드는 화면을 단독 구현했습니다. EventSource는 헤더를 붙일 수 없어 fetch 스트리밍과 TextDecoderStream으로 SSE 파서를 직접 만들고, message_start·step·text_delta·block·pending_selection·preview 등 10종 이벤트를 UI 상태로 환원하는 스트리밍 훅(useAiChatStream)을 설계했습니다.
- 모델의 도구 출력을 텍스트로 흘리지 않고 타입별 React 컴포넌트로 매핑하는 렌더러를 만들었습니다. E2B XML·MedDRA 코딩표·타임라인·인과성 스코어카드는 화면에 그대로 그리고, 케이스 선택·액션 버튼은 눌러서 다시 대화로 돌려보냅니다. 형태가 깨진 블록 하나 때문에 답변 전체가 사라지지 않도록 걸러냅니다.
- 스트리밍 도중 오른쪽 패널에 ICSR 폼 초안이 채워집니다. 스냅샷마다 어떤 필드가 추가·수정됐는지 표시하고 버전을 오갈 수 있게 했으며, 확정한 초안은 성별·UCUM 단위·Outcome 등 E2B(R3) 코드 테이블로 변환해 케이스 생성 API로 넘깁니다.
- 사례를 규제기관 서식으로 내보내는 화면을 만들었습니다. 필드를 끌어 배치를 짜고 되돌릴 수 있도록 reducer와 이력을 두고, 두 가지 서식을 같은 데이터에서 그립니다. 머리말·꼬리말이 나오지 않던 원인은 서버가 아니라 우리 쪽 "@page { margin: 0 }" 이었습니다 — 여백이 0이면 브라우저가 그것을 그릴 자리가 없습니다. 페이지 번호도 브라우저가 주는 템플릿으로만 낼 수 있어 본문에 고정 위치로는 만들 수 없었습니다. 1px 미만 선이 인쇄에서 사라지는 문제와 표가 페이지 경계에서 잘리는 문제도 함께 잡았습니다.
- 개인정보 마스킹은 완성된 HTML의 입력 요소를 정규식으로 치환하고 있었는데, 인쇄 경로는 입력 요소를 아예 만들지 않아 통하지 않았습니다. 렌더 전에 값을 덮어쓰는 방식으로 옮겨 화면과 인쇄 양쪽에서 같게 동작하게 했습니다. 사례 목록 엑셀 내보내기에도 같은 마스킹 선택을 붙였습니다.
- E2B 데이터 모델을 따라 환자·제품·이상사례·보고자로 나뉜 사례 상세와, 수백 건을 다루는 사례 목록을 맡았습니다. 목록의 필터·정렬·페이지 상태를 URL과 묶어 링크 공유와 뒤로가기가 그대로 동작하고, 목록에서 Ctrl/Cmd+클릭으로 새 탭에 열 수 있습니다. 저장·활성화 전에 보고서 식별자 중복을 검사하고, 잠긴 사례·감사 추적·사용된 MedDRA 버전을 화면에 드러냈습니다.
- 대용량 안전성 XML 업로드와 규제기관 제출은 논블로킹 폴링으로 돌리고, 전역 스낵바의 이벤트 버블링을 격리해 사용자가 하던 작업이 끊기지 않게 했습니다. 제품·연도 기준 애널리틱스 화면은 보고서 화면과 같은 구조로 통일해 실 API에 연결했고, 시그널 탐지의 조합 상세 판독 화면도 다시 설계했습니다.
임팩트
−180KB
모듈 번들 · 차트 의존성 제거
−70%
입력 리드타임 · AI 초안 생성
60fps
이벤트 수백 건에서도 유지