MediPortal(웹 프로토타입) → 이지스 전자차트(C#/.NET + PostgreSQL) 이식 자문 · 외래진료실 신규기능
개발팀과의 소통을 위해, 메디포털(웹)에서 먼저 구축·검증한 기능이 어떻게 만들어졌는지와 이지스 본체(C#/.NET, PostgreSQL)에서는 어떻게 구축되어야 하는지를 정리합니다. 웹 프로토타입은 기능·UX·프롬프트·데이터 계약의 레퍼런스 구현이며, 본체 이식 시 데이터 계층·LLM 호출·저장·인쇄·UI만 네이티브로 교체하면 됩니다. 이 문서는 AI 로드맵의 구축내역과 동기 유지합니다.
| 계층 | MediPortal (웹 프로토타입) | 이지스 전자차트 (C#/.NET + PostgreSQL) 이식 |
|---|---|---|
| UI 셸 | HTML 드로어/모달 + CSS 8테마, clinic-view.html에 <script> 주입 | WinForms/WPF UserControl·Form·Panel(도킹). 기존 진료 화면에 탭/사이드패널로 임베드 |
| 운영DB 접근 | 원내 eghis-db-agent(127.0.0.1 REST, 읽기전용·토큰)로 PostgreSQL 조회 → 행 한도(~500)·청크 필요 | Npgsql 직접 연결(같은 프로세스·LAN). 행 한도 없음 → 청크/폴백 로직 불필요. 파라미터라이즈드 쿼리·커넥션풀 |
| LLM 호출 | 공용 Gemini 프록시(Netlify Function) DrPortalAI.aiComplete() / 비전은 gemini-proxy inlineData. 키는 서버 보관 | 서버사이드 프록시 서비스 경유(클라이언트에 키 미노출). 토큰 단위·선불 크레딧 과금(가격 결정안 27p). 모델: 저가 flash급(다듬이)~정확 sonnet급(소견서). 사내 eghisEmrAi 사이드카 재사용 가능 |
| 로컬/영속 저장 | 브라우저 sql.js(단일 mediportal.sqlite) 또는 localStorage 폴백 | 기능 상태는 PostgreSQL 신규 테이블(권장) 또는 원내 로컬 SQLite. 이력·감사로그 동일 스키마 |
| 인쇄 | window.open 팝업 문서 + window.print()(타 모듈 @media print 충돌 격리) | PrintDocument / ReportViewer(RDLC) 또는 기존 이지스 서식엔진. 동일 레이아웃 재현 |
| 개인정보·안전 | 외부 LLM엔 식별정보 제외 임상문장 위주. 사실·수치·약명 보존 프롬프트 제약. 무검수 저장 금지 | 동일 원칙 + 사내 프록시로 전송범위 로깅·마스킹. 의무기록은 의사 확정 단계 강제 |
| 데이터 계층 추상화 | 모듈이 window.CV.summaryData()·CV._rec·CV.q() 어댑터로 접근 | 동일 인터페이스를 Repository/Service로 구현 → UI·로직 재사용, 쿼리만 교체 |
⭐ 이식 핵심: 웹 프로토타입의 ①프롬프트 ②판정·계산 로직 ③입출력 데이터 계약 ④UX 흐름은 그대로 이식하고, 데이터 접근(Npgsql)·LLM 프록시·저장·인쇄·UI 컨트롤만 네이티브로 교체합니다.
증상(F1)·환자메모·특이사항 텍스트를 목적별 문체 정리·맞춤법·번역하고, 재진 SOAP 정리·재진 증상 템플릿(가증상, 투약일수 계산 포함)을 생성. 웹 파일: cv-polish.js(외래진료실 통합), ai-polish.html(standalone 데모).
| 항목 | 테이블·컬럼 | 용도 |
|---|---|---|
| 증상(S) | h2opd_ptnt_symp.symp_txt (recept_no) | 문체 정리·SOAP S·템플릿 기준 |
| 환자메모/특이사항 | hz_mst_ptnt.ptnt_memo / opd_memo | 상담·특이사항 반영 |
| 바이탈·검사(O) | h1vitalsign(코드별 값·측정일) | SOAP O, 당일 계측·추이(직전 대비 ↑↓) |
| 상병(A) | 진료 상병(주/부/배제) | SOAP A(추정·의심·배제) |
| 처방(P)·투약일수 | h2opd_doct_ord(ord_cd·days_of_medication·dayqty) | SOAP P, 남은 약/복약공백 계산 |
과거 방문(desc) 증상 텍스트를 템플릿으로 재사용하되, 직전 방문 처방 중 최장 일수 약제 기준으로 오늘까지 경과일을 계산해 남은 약/복약공백을 결정론적으로 산출(AI가 아닌 코드 계산):
// 의사코드 (웹 medSupply → C# 이식 동일) prev = 오늘 이전 최근 방문 중 (days_of_medication 최대) 처방 elapsed = today - prev.visitDate if (elapsed <= prev.maxDays) 남은약 = prev.maxDays - elapsed // 추정 남은 일분 else 복약공백 = elapsed - prev.maxDays // 약 소진 후 미복용 일수
/ 슬래시 메뉴DrPortalAI.aiComplete(gemini-flash). 사실·수치·약명 불변 제약/+번호+Enter입출력 계약: { rawText, mode(tidy|spell|translate|soap|visit), tone|lang } → { resultText }. SOAP·visit 모드는 추가로 { vitals, dx, rx, pastSymp, medSupply } 컨텍스트 필요.
마운자로·위고비·삭센다 약제별 감량 예측·비교, 차수/개월 곡선, 실측 성취도, 환자 유형별 효능(당뇨병·수면무호흡·기타), InBody AI 분석, 실손 소견서·체중관리 계획서. 웹 파일: glp1-weight.js.
ACCRUAL[0..6], 예측 = 기저체중 × (1 − 최종감량률% × 누적비율(month)).h1vitalsign weight/height/bmiglp1_state(ptnt_no, json)aiComplete + 조건 게이트(마운자로·BMI≥25·당뇨/OSA·급여본인부담)h0_mst_drug.component) 감지 → 버튼/메뉴h1vitalsign Npgsql 직접glp1_plan / glp1_measure PostgreSQL 테이블(환자·차수·실측)입출력 계약: { base, height, bmi, target, drug, dose, pop, custom[], measures[] } → { 예측표, 곡선, 비교표, 달성률 }. 소견서: { 진단·HbA1c·기존치료·급여여부 } → { 서술부 초안 }.
투여이력(6개월±28일·1년2회/골절3년6회)·골밀도 검사주기·BMD 결과지 AI 판독 → 급여 판정(중심골 평균 T-score ≤ -2.5)·청구메모·특정내역(JX999) 검증·근거 고시. 웹 파일: prolia-monitor.js.
| 단계 | 내용 |
|---|---|
| 투여이력·검사 | 방문+처방(h2opd_doct_ord)에서 프롤리아(성분 629001BIJ)·BMD 오더 수집. 성분코드 매칭은 h0_mst_drug.component(계산코드/처방코드→성분) |
| BMD 판독 | 결과지 이미지 → Gemini 비전(inlineData)로 요추 L1~L4·대퇴 Neck/Total T-score 추출 → 수동 보정 |
| 급여 판정 | 요추 배제부위 제외 평균·대퇴 최저 → 최저값 ≤ -2.5 = 골다공증(급여). 공개심의(평균 판단·최저 임의선택 불가) 반영 |
| 특정내역 검증 | 명세서 JX999(h2opd_specode)의 골밀도 검사일 최신성(12개월 초과=삭감주의) 판독 |
prolia_monitor(state json)gk_noti(DRG_0005/7/8) 로드. 특정내역 날짜점검은 골키퍼 gk_note_rule(NOTE_STALE)로도 심사prolia_monitor PostgreSQL 테이블입출력 계약: { ptnt, 투여이력[], BMD검사[], TS{L1..L4,Neck,Total,qct}, dxFx } → { 판정, 다음회차·검사도래, 청구메모, JX999판독 }.
summaryData/_rec 계약과 1:1) ③ 기능 상태 PostgreSQL 스키마.본 문서는 AI 로드맵의 기능별 기술정의서(정의·UX·구현·입출력·모델·리스크·Phase2)와 상호 참조됩니다. 신규/변경 시 양쪽을 함께 갱신합니다.