버전: 2.0.0 최종 업데이트: 2025-11-30 대상: 시스템 관리자, 플랫폼 운영자, DevOps 엔지니어
AI Medical Platform은 진단 → 처방 → 구매 → 협업의 완전 자동화된 AI 기반 개인 맞춤형 건강 관리 생태계입니다.
핵심 기능: - 🤖 AI 진단 엔진 (GPT-4, Gemini, Grok 앙상블) - 💊 처방 추천 및 의사 승인 워크플로우 - 🛒 통합 커머스 (진단 후 원클릭 구매) - 💬 AI 건강 챗봇 (9개 언어 지원) - 🏥 비대면 상담 (WebRTC 화상 상담) - 📊 건강 데이터 관리 (FHIR R4 표준) - 🔗 IoT 연동 (Apple Watch, Fitbit, Samsung Health) - 📱 알림 시스템 (Push, SMS, 카카오톡) - 👨👩👧👦 가족 건강 관리
┌─────────────────────────────────────────────────────────────────────────────┐
│ 사용자 접속 계층 │
│ 브라우저 / 모바일 앱 / IoT 디바이스 / 파트너 시스템 │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ Nginx 리버스 프록시 (8080/8443) │
│ - SSL/TLS 종단 │
│ - 로드 밸런싱 │
│ - Rate Limiting │
│ - 정적 파일 캐싱 │
└─────────────────────────────────────────────────────────────────────────────┘
│
┌─────────────────────────┼─────────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────────┐ ┌───────────────────┐ ┌───────────────────┐
│ Web Frontend │ │ API Gateway │ │ MinIO (S3) │
│ (Next.js) │ │ (NestJS) │ │ 파일 저장소 │
│ 포트: 3000 │ │ 포트: 3001 │ │ 포트: 9000 │
│ │ │ │ │ │
│ - SSR/SSG │ │ - JWT 인증 │ │ - 의료 이미지 │
│ - React Query │ │ - Rate Limit │ │ - 문서 저장 │
│ - Tailwind CSS │ │ - 로깅/감사 │ │ - 백업 파일 │
└───────────────────┘ └───────────────────┘ └───────────────────┘
│
┌─────────────────┼─────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 마이크로서비스 │ │ 마이크로서비스 │ │ 마이크로서비스 │
│ - User │ │ - Diagnosis │ │ - Commerce │
│ - Health Data │ │ - Prescription│ │ - Partner │
│ - Telemedicine│ │ - AI Engine │ │ - Notification│
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
└─────────────────┼─────────────────┘
│
┌─────────────────────────┼─────────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────────┐ ┌───────────────────┐ ┌───────────────────┐
│ PostgreSQL 15 │ │ Redis 7 │ │ Mosquitto │
│ 포트: 5432 │ │ 포트: 6379 │ │ MQTT 브로커 │
│ │ │ │ │ 포트: 1883 │
│ - 메인 데이터 │ │ - 세션 관리 │ │ - IoT 데이터 │
│ - JSONB 활용 │ │ - API 캐싱 │ │ - 실시간 이벤트 │
│ - 트랜잭션 처리 │ │ - Rate Limit │ │ - 웨어러블 연동 │
└───────────────────┘ └───────────────────┘ └───────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ 모니터링 계층 │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Prometheus │ │ Grafana │ │ Alertmanager │ │ cAdvisor │ │
│ │ (9090) │ │ (3002) │ │ (9093) │ │ (8081) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Node Exporter│ │Postgres Exp. │ │ Redis Exp. │ │
│ │ (9100) │ │ (9187) │ │ (9121) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
| 구분 | 기술 | 버전 | 용도 |
|---|---|---|---|
| Backend | Node.js | 20.x LTS | 런타임 환경 |
| NestJS | 10.x | API 프레임워크 | |
| TypeScript | 5.x | 타입 안전성 | |
| Prisma | 5.x | ORM | |
| Frontend | Next.js | 14.x | React 프레임워크 |
| React | 18.x | UI 라이브러리 | |
| Tailwind CSS | 3.x | 스타일링 | |
| shadcn/ui | latest | UI 컴포넌트 | |
| Database | PostgreSQL | 15.x | 메인 DB |
| Redis | 7.x | 캐시/세션 | |
| TimescaleDB | 2.x | 시계열 데이터 | |
| AI/ML | OpenAI GPT-4 | - | 진단 엔진 |
| Google Gemini | - | 의료 지식 | |
| xAI Grok | - | 한국어 처리 | |
| LangChain | 0.1.x | AI 오케스트레이션 | |
| Infra | Docker | 24.x | 컨테이너화 |
| Nginx | 1.25.x | 리버스 프록시 | |
| Prometheus | 2.x | 메트릭 수집 | |
| Grafana | 10.x | 시각화 |
⚠️ 중요: 호스트 포트 3001은 다른 프로젝트(/opt/gunja)가 사용 중입니다. 절대 충돌하지 않도록 주의하세요.
| 서비스 | 컨테이너 내부 | 호스트 매핑 | 프로토콜 | 설명 |
|---|---|---|---|---|
| Nginx | 80, 443 | 8080, 8443 | HTTP/HTTPS | 메인 진입점 |
| Web | 3000 | 3000 | HTTP | Next.js 프론트엔드 |
| API Gateway | 3001 | 3011 | HTTP | REST API |
| PostgreSQL | 5432 | 5434 | TCP | 데이터베이스 |
| Redis | 6379 | 6381 | TCP | 캐시/세션 |
| MinIO API | 9000 | 9000 | HTTP | S3 호환 스토리지 |
| MinIO Console | 9001 | 9001 | HTTP | MinIO 관리 UI |
| Grafana | 3000 | 3002 | HTTP | 모니터링 대시보드 |
| Prometheus | 9090 | 9090 | HTTP | 메트릭 수집 |
| Alertmanager | 9093 | 9093 | HTTP | 알림 관리 |
| Node Exporter | 9100 | 9100 | HTTP | 시스템 메트릭 |
| Postgres Exporter | 9187 | 9187 | HTTP | DB 메트릭 |
| Redis Exporter | 9121 | 9121 | HTTP | 캐시 메트릭 |
| cAdvisor | 8080 | 8081 | HTTP | 컨테이너 메트릭 |
| Mosquitto MQTT | 1883 | 1883 | TCP | IoT 메시징 |
| Mosquitto WS | 9001 | 9002 | WebSocket | IoT WebSocket |
| 서비스 | URL | 계정 정보 | 용도 |
|---|---|---|---|
| 메인 웹사이트 | https://starium.site:8080 | - | 사용자 포털 |
| API 문서 | https://starium.site:8080/api/docs | - | Swagger UI |
| Grafana | http://139.180.204.158:3002 | admin / grafana_password_2025 | 모니터링 |
| MinIO Console | http://139.180.204.158:9001 | minioadmin / minioadmin2025 | 파일 관리 |
| Prometheus | http://139.180.204.158:9090 | - | 메트릭 쿼리 |
| Alertmanager | http://139.180.204.158:9093 | - | 알림 설정 |
관리자 계정:
이메일: admin@hospital.com
비밀번호: Admin1234!@#
역할: ADMIN
┌─────────────────────────────────────────────────────────────────────────────┐
│ 1. https://starium.site:8080 접속 │
│ 2. 관리자 계정으로 로그인 │
│ 3. 상단 네비게이션 → "관리자" 메뉴 클릭 │
│ 4. 대시보드 메인 화면 진입 │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ [로고] AI Medical Platform [검색] [알림🔔] [관리자 ▼] │
├─────────────────────────────────────────────────────────────────────────────┤
│ │ │
│ │ ┌─ 대시보드 ──────────────────────────────────────────────────────────┐ │
│ │ │ │ │
│ 사│ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │
│ 이│ │ │ 총 사용자 │ │ 오늘 진단 │ │ 대기 처방 │ │ 금일 매출 │ │ │
│ 드│ │ │ 12,345 │ │ 256 │ │ 42 │ │ ₩8.5M │ │ │
│ 바│ │ │ ▲ 12% │ │ ▲ 8% │ │ ▼ 3% │ │ ▲ 15% │ │ │
│ │ │ └────────────┘ └────────────┘ └────────────┘ └────────────┘ │ │
│ 메│ │ │ │
│ 뉴│ │ ┌─────────────────────────────┐ ┌─────────────────────────────┐ │ │
│ │ │ │ 주간 진단 트렌드 │ │ 시스템 상태 │ │ │
│ │ │ │ 📈 [차트 영역] │ │ API: ●정상 DB: ●정상 │ │ │
│ │ │ │ │ │ Redis: ●정상 AI: ●정상 │ │ │
│ │ │ └─────────────────────────────┘ └─────────────────────────────┘ │ │
│ │ │ │ │
│ │ │ ┌─────────────────────────────┐ ┌─────────────────────────────┐ │ │
│ │ │ │ 최근 처방 승인 대기 │ │ 긴급 알림 │ │ │
│ │ │ │ • 환자A - 비타민D (30분전) │ │ ⚠️ 저신뢰도 진단 3건 │ │ │
│ │ │ │ • 환자B - 오메가3 (1시간전) │ │ ⚠️ 의사 승인 필요 5건 │ │ │
│ │ │ │ • 환자C - 유산균 (2시간전) │ │ ✅ 시스템 정상 가동 중 │ │ │
│ │ │ └─────────────────────────────┘ └─────────────────────────────┘ │ │
│ │ └──────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
📊 대시보드
├── 개요
├── 실시간 현황
└── KPI 리포트
👥 사용자 관리
├── 전체 사용자
├── 환자 목록
├── 의사 관리
├── 파트너 관리
└── 승인 대기
🤖 AI 진단 관리
├── 진단 목록
├── 저신뢰도 진단
├── 진단 통계
└── AI 모델 설정
💊 처방 관리
├── 처방전 목록
├── 승인 대기
├── 약물 상호작용 경고
└── 처방 통계
🛒 상품/주문 관리
├── 상품 목록
├── 카테고리 관리
├── 주문 현황
├── 환불 요청
└── 재고 관리
🏥 비대면 상담
├── 예약 현황
├── 진료 스케줄
├── 화상 상담 모니터링
└── 의사 배정
📈 모니터링
├── 시스템 상태
├── API 성능
├── 에러 로그
└── 사용량 분석
⚙️ 설정
├── 시스템 설정
├── 알림 설정
├── 백업/복원
└── 보안 설정
| 지표 | 목표값 | 측정 주기 | 알림 임계값 |
|---|---|---|---|
| 일간 활성 사용자 (DAU) | 500+ | 실시간 | < 100 |
| AI 진단 정확도 | ≥ 70% | 일간 | < 60% |
| 평균 응답 시간 (P95) | < 200ms | 실시간 | > 500ms |
| 에러율 | < 0.1% | 실시간 | > 1% |
| 처방 승인율 | ≥ 85% | 일간 | < 70% |
| 주문 전환율 | ≥ 25% | 일간 | < 15% |
| 시스템 가용률 | 99.9% | 월간 | < 99% |
┌─────────────────────────────────────────────────────────────────────────────┐
│ 사용자 역할 계층 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ SUPER_ADMIN (최고 관리자) │ │
│ │ - 모든 기능 접근 │ │
│ │ - 관리자 계정 생성/삭제 │ │
│ │ - 시스템 설정 변경 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ ADMIN (관리자) │ │
│ │ - 사용자 관리 │ │
│ │ - 상품/주문 관리 │ │
│ │ - 진단/처방 모니터링 │ │
│ │ - 리포트 조회 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌───────────────────────────┐ ┌───────────────────────────┐ │
│ │ DOCTOR (의사) │ │ PARTNER (파트너) │ │
│ │ - 처방 승인/거부 │ │ - 상품 등록/수정 │ │
│ │ - 환자 진료 │ │ - 주문 조회 │ │
│ │ - 의료 기록 조회 │ │ - API 키 관리 │ │
│ │ - 비대면 상담 │ │ - 정산 조회 │ │
│ └───────────────────────────┘ └───────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ PATIENT (환자) │ │
│ │ - 자신의 데이터 조회/수정 │ │
│ │ - AI 진단 요청 │ │
│ │ - 상품 구매 │ │
│ │ - 가족 건강 관리 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
경로: 관리자 대시보드 → 사용자 관리 → 전체 사용자
필터 옵션:
| 필터 | 옵션 | 설명 |
|---|---|---|
| 역할 | PATIENT, DOCTOR, PARTNER, ADMIN | 사용자 유형별 |
| 상태 | ACTIVE, SUSPENDED, DELETED | 계정 상태별 |
| 가입 기간 | 오늘, 최근 7일, 최근 30일, 커스텀 | 가입일 기준 |
| 인증 상태 | 이메일 인증, 휴대폰 인증, 2FA 활성화 | 인증 수준별 |
| 활동 상태 | 활성 (30일 이내), 휴면 (30일 이상) | 최근 로그인 기준 |
검색 옵션: - 이메일 주소 검색 - 이름 검색 - 전화번호 검색 - 사용자 ID 검색
┌─────────────────────────────────────────────────────────────────────────────┐
│ 사용자 상세 정보 [수정] [정지] [삭제]│
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─ 기본 정보 ────────────────────────────────────────────────────────────┐ │
│ │ 사용자 ID: usr_abc123def456 │ │
│ │ 이름: 홍길동 │ │
│ │ 이메일: hong@email.com ✓ (인증됨) │ │
│ │ 전화번호: 010-1234-5678 ✓ (인증됨) │ │
│ │ 생년월일: 1985-03-15 │ │
│ │ 성별: 남성 │ │
│ │ 가입일: 2025-01-15 14:30:00 │ │
│ │ 최근 로그인: 2025-11-30 09:15:00 │ │
│ │ 2FA: 활성화 ✓ │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ 활동 내역 ────────────────────────────────────────────────────────────┐ │
│ │ 총 로그인: 245회 │ │
│ │ AI 진단 횟수: 32회 │ │
│ │ 주문 횟수: 15회 │ │
│ │ 총 주문 금액: ₩1,250,000 │ │
│ │ 마지막 진단: 2025-11-28 (피로감, 수면장애) │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ IoT 연동 ─────────────────────────────────────────────────────────────┐ │
│ │ Apple Watch Series 9: 연결됨 ✓ (마지막 동기화: 1시간 전) │ │
│ │ 스마트 혈압계: 연결됨 ✓ │ │
│ │ 스마트 체중계: 미연결 │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ 가족 구성원 ──────────────────────────────────────────────────────────┐ │
│ │ • 김영희 (배우자) - 관리 권한 부여됨 │ │
│ │ • 홍철수 (자녀) - 관리 권한 부여됨 │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
정지 사유: - 부적절한 행위 (스팸, 악성 리뷰) - 결제 문제 (사기 의심, 차지백) - 이용약관 위반 - 사용자 요청
절차:
1. 사용자 상세 페이지 접속
2. [정지] 버튼 클릭
3. 정지 정보 입력:
- 정지 사유 선택/입력
- 정지 기간: 7일 / 30일 / 90일 / 영구
- 알림 발송 여부
4. [확인] 클릭
5. 사용자에게 이메일 알림 자동 발송
정지 해제:
1. 정지된 사용자 목록에서 선택
2. [정지 해제] 버튼 클릭
3. 해제 사유 입력
4. [확인] 클릭
승인 프로세스:
┌───────────────┐ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ 신규 가입 │ ──▶ │ 서류 제출 │ ──▶ │ 관리자 검토 │ ──▶ │ 승인/거부 │
│ │ │ │ │ │ │ │
│ • 기본 정보 │ │ • 의사 면허증 │ │ • 면허 유효성 │ │ • 승인 시 │
│ • 이메일 인증 │ │ • 전문의 자격 │ │ • 소속 확인 │ │ 권한 부여 │
│ │ │ • 소속 증명 │ │ • 서류 진위 │ │ • 거부 시 │
│ │ │ │ │ │ │ 사유 통보 │
└───────────────┘ └───────────────┘ └───────────────┘ └───────────────┘
검토 항목:
| 항목 | 확인 내용 | 필수 여부 |
|---|---|---|
| 의사 면허 | 면허 번호, 유효기간, 발급 기관 | 필수 |
| 전문의 자격 | 전문 분야, 자격 번호 | 선택 |
| 소속 기관 | 병원명, 주소, 연락처 | 필수 |
| 본인 확인 | 신분증 사진, 면허증 사진 일치 | 필수 |
파트너 유형:
| 유형 | 설명 | API 접근 범위 |
|---|---|---|
| HOSPITAL | 병원/의원 | 환자 데이터 (동의 시), 처방 |
| PHARMACY | 약국 | 처방전 조회, 조제 확인 |
| PHARMACEUTICAL | 제약사 | 상품 관리, 주문 |
| IOT_MANUFACTURER | IoT 제조사 | 디바이스 연동, 데이터 수집 |
API 키 관리:
1. 파트너 상세 페이지 접속
2. [API 관리] 탭 선택
3. [새 API 키 발급] 클릭
4. 키 이름, 권한 범위, 유효 기간 설정
5. [발급] 클릭
6. API 키 복사 (한 번만 표시됨)
⚠️ 주의: API 키는 발급 시 한 번만 표시됩니다.
분실 시 새로 발급해야 합니다.
┌─────────────────────────────────────────────────────────────────────────────┐
│ AI 진단 워크플로우 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ │
│ │ 사용자 입력 │ │
│ │ (증상/데이터)│ │
│ └──────┬──────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 데이터 전처리 계층 │ │
│ │ • 증상 정규화 • 건강 데이터 통합 • IoT 데이터 분석 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ AI 앙상블 진단 엔진 │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ GPT-4 │ │ Gemini │ │ Grok │ │ │
│ │ │ (50% 가중) │ │ (30% 가중) │ │ (20% 가중) │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ • 진단 로직 │ │ • 의료 지식 │ │ • 한국어 │ │ │
│ │ │ • 패턴 인식 │ │ • 검색 증강 │ │ • 문맥 이해 │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 검증 및 안전 계층 │ │
│ │ • 신뢰도 계산 (0.0 ~ 1.0) │ │
│ │ • 약물 상호작용 체크 │ │
│ │ • 알레르기 교차 검증 │ │
│ │ • 긴급도 분류 (NORMAL / URGENT / CRITICAL) │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ 신뢰도 < 0.7? ──Yes──▶ 저신뢰도 플래그 + 의사 재검토 요청 │ │
│ │ │ │ │
│ │ No │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ 처방 추천 생성 │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ 의사 승인 │ │
│ │ (필수 단계) │ │
│ └─────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
경로: 관리자 대시보드 → AI 진단 관리 → 진단 목록
진단 상태:
| 상태 | 설명 | 액션 |
|---|---|---|
| PENDING | AI 분석 진행 중 | 대기 |
| COMPLETED | 분석 완료 | 결과 검토 |
| LOW_CONFIDENCE | 저신뢰도 (< 0.7) | 의사 재검토 요청 |
| REVIEWED | 의사 검토 완료 | 처방 진행 |
| CANCELLED | 취소됨 | - |
진단 상세 화면:
┌─────────────────────────────────────────────────────────────────────────────┐
│ 진단 상세 #DX-2025-001234 [검토] [재진단] │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─ 환자 정보 ────────────────────────────────────────────────────────────┐ │
│ │ 이름: 홍길동 (남, 39세) │ │
│ │ 기저질환: 고혈압, 당뇨 │ │
│ │ 알레르기: 페니실린 │ │
│ │ 현재 복용 중: 아스피린, 메트포르민 │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ 입력 증상 ────────────────────────────────────────────────────────────┐ │
│ │ • 만성 피로감 (3개월 이상) │ │
│ │ • 수면 장애 (불면, 중간 기상) │ │
│ │ • 근육통 │ │
│ │ • 두통 (간헐적) │ │
│ │ • 집중력 저하 │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ IoT 데이터 (최근 7일) ─────────────────────────────────────────────────┐ │
│ │ 평균 수면: 5.2시간 (권장: 7-8시간) ⚠️ │ │
│ │ 평균 심박: 78 bpm (정상) │ │
│ │ 활동량: 3,500 걸음/일 (권장: 8,000) ⚠️ │ │
│ │ 스트레스 지수: 72 (높음) ⚠️ │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ AI 분석 결과 ─────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────────────────────────┐ │ │
│ │ │ 주요 진단: 만성피로증후군 (신뢰도: 0.82) │ │ │
│ │ ├─────────────────────────────────────────────────────────────────┤ │ │
│ │ │ GPT-4 진단: 만성피로증후군 (0.85) │ │ │
│ │ │ Gemini 진단: 만성피로증후군 (0.78) │ │ │
│ │ │ Grok 진단: 스트레스성 피로 (0.81) │ │ │
│ │ └─────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ 부가 분석: │ │
│ │ • 수면 부족이 주요 원인으로 추정 │ │
│ │ • 스트레스 관리 필요 │ │
│ │ • 비타민 D 결핍 가능성 (일조량 부족 패턴) │ │
│ │ │ │
│ │ 긴급도: NORMAL │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ 추천 처방 ────────────────────────────────────────────────────────────┐ │
│ │ 1. 종합 비타민 (비타민 D 3000IU 포함) │ │
│ │ 2. 마그네슘 400mg │ │
│ │ 3. 오메가-3 1000mg │ │
│ │ 4. 수면 개선 보조제 (멜라토닌 3mg) │ │
│ │ │ │
│ │ ⚠️ 약물 상호작용: 없음 │ │
│ │ ⚠️ 알레르기 성분: 없음 │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
저신뢰도 기준: 신뢰도 < 0.7
처리 절차:
1. 저신뢰도 진단 목록 확인
경로: AI 진단 관리 → 저신뢰도 진단
2. 진단 내용 검토
- AI 분석 결과 확인
- 입력 데이터 품질 확인
- 증상 추가 입력 필요 여부 판단
3. 조치 선택:
┌─────────────────────────────────────────────────┐
│ [의사 재검토 요청] [추가 정보 요청] [진단 취소] │
└─────────────────────────────────────────────────┘
4-A. 의사 재검토 요청 시:
- 담당 의사 지정
- 검토 요청 사유 입력
- 의사에게 알림 발송
4-B. 추가 정보 요청 시:
- 환자에게 추가 증상 입력 요청
- 건강검진 결과 업로드 요청
- 병원 방문 권고
4-C. 진단 취소 시:
- 취소 사유 입력
- 환자에게 알림 발송
처방전 상태 흐름:
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ DRAFT │ ──▶ │ PENDING │ ──▶ │APPROVED │ ──▶ │PURCHASED│
│ (초안) │ │(검토대기)│ │ (승인) │ │ (구매) │
└─────────┘ └────┬────┘ └─────────┘ └─────────┘
│
│ 거부
▼
┌─────────┐
│REJECTED │
│ (거부) │
└─────────┘
│ 만료 (30일)
▼
┌─────────┐
│ EXPIRED │
│ (만료) │
└─────────┘
약물 상호작용 경고 레벨:
| 레벨 | 색상 | 설명 | 조치 |
|---|---|---|---|
| INFO | 🟢 녹색 | 참고 정보 | 정보 확인 후 승인 가능 |
| WARNING | 🟡 황색 | 주의 필요 | 환자에게 주의사항 안내 후 승인 |
| DANGER | 🔴 적색 | 위험 | 해당 상품 제외 또는 대체 필요 |
| CRITICAL | ⚫ 검정 | 심각한 위험 | 즉시 의사 상담 필요 |
건강기능식품
├── 비타민/미네랄
│ ├── 종합 비타민
│ ├── 비타민 D
│ ├── 비타민 C
│ ├── 비타민 B군
│ ├── 철분
│ ├── 칼슘/마그네슘
│ └── 아연
├── 오메가3/오일
│ ├── 오메가-3
│ ├── 크릴 오일
│ └── 식물성 오메가
├── 유산균/소화
│ ├── 프로바이오틱스
│ ├── 프리바이오틱스
│ └── 소화 효소
├── 관절/뼈
│ ├── 글루코사민
│ ├── MSM
│ └── 콘드로이틴
├── 면역/항산화
│ ├── 프로폴리스
│ ├── 홍삼/인삼
│ └── 비타민 E
└── 기타
├── 수면 개선
├── 스트레스 관리
└── 에너지 부스터
의료 기기
├── 체성분 분석기
├── 혈압계
├── 혈당계
└── 체온계
IoT 웨어러블
├── 스마트워치
├── 피트니스 트래커
└── 수면 모니터
경로: 관리자 대시보드 → 상품 관리 → 신규 상품 등록
필수 입력 항목:
| 필드 | 설명 | 예시 |
|---|---|---|
| 상품명 | 상품 이름 | “프리미엄 오메가-3 1000mg” |
| 카테고리 | 분류 선택 | 오메가3/오일 |
| 상품 유형 | SUPPLEMENT / DEVICE / WEARABLE | SUPPLEMENT |
| 가격 | 판매 가격 (원) | 35000 |
| 재고 수량 | 현재 재고 | 500 |
| 제조사/파트너 | 파트너 선택 | (주)건강제약 |
성분 정보 (JSONB):
{
"ingredients": [
{
"name": "EPA",
"amount": 500,
"unit": "mg"
},
{
"name": "DHA",
"amount": 300,
"unit": "mg"
}
],
"warnings": ["임산부 섭취 전 의사 상담"],
"storage": "직사광선을 피해 서늘한 곳에 보관",
"expirationMonths": 24
}이미지 업로드: - 메인 이미지: 1개 (필수, 1:1 비율 권장) - 상세 이미지: 최대 5개 - 지원 형식: JPG, PNG, WebP - 최대 크기: 5MB/개
┌─────────────────────────────────────────────────────────────────────────────┐
│ 주문 처리 흐름 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ │
│ │ 주문 생성 │ ← 환자가 처방 승인 후 장바구니에서 주문 │
│ │ (PENDING) │ │
│ └────┬─────┘ │
│ │ │
│ ▼ │
│ ┌──────────┐ │
│ │ 결제 처리 │ ← 토스페이먼츠 / 카카오페이 / 네이버페이 │
│ │ (PAID) │ │
│ └────┬─────┘ │
│ │ │
│ ├─────────────────────────────────────┐ │
│ │ 결제 실패 │ 결제 성공 │
│ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ │
│ │ 결제 실패 │ │ 처리 중 │ ← 재고 확인 & 출고 준비 │
│ │ (FAILED) │ │(PROCESSING)│ │
│ └──────────┘ └────┬─────┘ │
│ │ │
│ ▼ │
│ ┌──────────┐ │
│ │ 배송 중 │ ← 송장 번호 입력 │
│ │ (SHIPPED) │ 택배사 연동 │
│ └────┬─────┘ │
│ │ │
│ ▼ │
│ ┌──────────┐ │
│ │ 배송 완료 │ ← 배송 완료 확인 │
│ │(DELIVERED)│ 리뷰 요청 알림 │
│ └──────────┘ │
│ │
│ 취소/환불 플로우: │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 취소 요청 │ ──▶ │ 취소 처리 │ ──▶ │ 환불 완료 │ │
│ │(CANCELLING)│ │(CANCELLED)│ │(REFUNDED)│ │
│ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
환불 정책:
| 구분 | 기간 | 환불율 | 조건 |
|---|---|---|---|
| 단순 변심 | 배송 완료 후 7일 이내 | 100% (배송비 차감) | 미개봉 |
| 제품 불량 | 배송 완료 후 30일 이내 | 100% | 증빙 사진 필요 |
| 배송 지연 | 주문 후 7일 초과 | 100% | 자동 취소 가능 |
환불 처리 단계:
1. 환불 요청 확인
- 경로: 주문 관리 → 환불 요청
- 요청 사유 확인
- 증빙 자료 확인 (사진 등)
2. 환불 승인/거부 결정
┌────────────────────────────────────────┐
│ 환불 요청 #REF-2025-001234 │
│ │
│ 주문 번호: ORD-2025-005678 │
│ 상품: 프리미엄 오메가-3 x 2 │
│ 결제 금액: ₩70,000 │
│ 환불 사유: 제품 불량 (캡슐 변색) │
│ 증빙 사진: [이미지 2장] │
│ │
│ [승인] [부분 승인] [거부] │
└────────────────────────────────────────┘
3. 환불 실행
- 승인 시 결제 게이트웨이 자동 환불 처리
- 카드 결제: 3-5 영업일 소요
- 계좌이체: 1-2 영업일 소요
4. 재고 복구
- 반품 수령 후 상태 확인
- 양호 시 재고 복구
- 불량 시 폐기 처리
┌─────────────────────────────────────────────────────────────────────────────┐
│ 비대면 상담 예약 흐름 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ 환자 의사 관리자 │
│ │ │ │ │
│ │ 1. 예약 요청 │ │ │
│ │────────────────────────────────▶│ │ │
│ │ │ │ │
│ │ │ 2. 예약 확인 │ │
│ │ │ (미배정 시) │ │
│ │ │──────────────────────▶│ │
│ │ │ │ │
│ │ │ │ 3. 의사 배정│
│ │ │◀──────────────────────│ │
│ │ │ │ │
│ │ 4. 예약 확정 알림 │ │ │
│ │◀────────────────────────────────│ │ │
│ │ │ │ │
│ │ 5. 진료 시간에 화상 상담 │ │ │
│ │◀──────────────────────────────▶│ │ │
│ │ │ │ │
│ │ 6. 진료 완료 & 처방 │ │ │
│ │◀────────────────────────────────│ │ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
| 상태 | 설명 | 가능한 액션 |
|---|---|---|
| PENDING | 예약 요청됨, 의사 미배정 | 의사 배정, 취소 |
| CONFIRMED | 의사 배정 완료, 확정 | 일정 변경, 취소 |
| IN_PROGRESS | 진료 진행 중 | 모니터링 |
| COMPLETED | 진료 완료 | 처방 확인 |
| CANCELLED | 취소됨 | - |
| NO_SHOW | 환자 불참 | 재예약 요청 |
경로: 비대면 상담 → 의사 배정
자동 배정 로직:
1. 전문 분야 매칭
- 환자 증상 → 관련 전문 분야 추출
- 해당 분야 의사 필터링
2. 가용 시간 확인
- 요청된 예약 시간에 가능한 의사
- 의사별 스케줄 확인
3. 업무량 분산
- 당일 예약 수 기준 분산
- 주간 진료 시간 균형
4. 우선순위 적용
- 긴급 진료: 즉시 배정
- 재진: 기존 담당의 우선
- 신규: 가용 의사 중 배정
수동 배정:
1. 미배정 예약 목록에서 선택
2. 가용 의사 목록 확인
3. 의사 선택 후 [배정] 클릭
4. 환자/의사에게 알림 발송
WebRTC 기반 화상 상담:
┌─────────────────────────────────────────────────────────────────────────────┐
│ 화상 상담 현황 [새로고침] │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─ 진행 중인 진료 (3건) ─────────────────────────────────────────────────┐ │
│ │ │ │
│ │ ┌────────────────────────────────────────────────────────────────┐ │ │
│ │ │ #TM-001 김의사 ↔ 이환자 시작: 10:05 경과: 15분 ●연결양호 │ │ │
│ │ │ 증상: 두통, 어지러움 [상세보기] │ │ │
│ │ └────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌────────────────────────────────────────────────────────────────┐ │ │
│ │ │ #TM-002 박의사 ↔ 최환자 시작: 10:10 경과: 10분 ●연결양호 │ │ │
│ │ │ 증상: 피부 발진 [상세보기] │ │ │
│ │ └────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌────────────────────────────────────────────────────────────────┐ │ │
│ │ │ #TM-003 정의사 ↔ 한환자 시작: 10:15 경과: 5분 ⚠️연결불안정 │ │ │
│ │ │ 증상: 소화불량 [상세보기] │ │ │
│ │ └────────────────────────────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ 대기 중 (5건) ────────────────────────────────────────────────────────┐ │
│ │ #TM-004 10:30 강환자 (예약) 담당: 미배정 [배정하기] │ │
│ │ #TM-005 10:45 윤환자 (예약) 담당: 김의사 [대기중] │ │
│ │ ... │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
접속 정보: - URL: http://139.180.204.158:3002 - 사용자명: admin - 비밀번호: grafana_password_2025
주요 대시보드:
┌─────────────────────────────────────────────────────────────────────────────┐
│ System Overview Last 1h ▼ 🔄 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ CPU 사용률 │ │ 메모리 사용 │ │ 디스크 사용 │ │ 네트워크 I/O │ │
│ │ 45.2% │ │ 68.5% │ │ 52.3% │ │ 125 Mbps │ │
│ │ [███░░] │ │ [████░] │ │ [███░░] │ │ ↑80 ↓45 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ┌─ CPU 사용률 추이 ──────────────────────────────────────────────────────┐ │
│ │ 100%| │ │
│ │ 80%| │ │
│ │ 60%| ╭──╮ ╭────╮ │ │
│ │ 40%|──────╯ ╰────╯ ╰──────────────────────── │ │
│ │ 20%| │ │
│ │ 0%|_________________________________________________________ │ │
│ │ 09:00 09:15 09:30 09:45 10:00 10:15 10:30 │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ 컨테이너 상태 ─────────────────────────────────────────────────────────┐ │
│ │ hospital_web ● Running CPU: 12% Mem: 256MB │ │
│ │ hospital_api_gateway ● Running CPU: 25% Mem: 512MB │ │
│ │ hospital_postgres ● Running CPU: 8% Mem: 1.2GB │ │
│ │ hospital_redis ● Running CPU: 2% Mem: 128MB │ │
│ │ hospital_nginx ● Running CPU: 3% Mem: 64MB │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ API Performance Last 1h ▼ 🔄 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 총 요청 수 │ │ 평균 응답 │ │ P95 응답 │ │ 에러율 │ │
│ │ 125,432 │ │ 85ms │ │ 180ms │ │ 0.02% │ │
│ │ ▲ 15% │ │ ▼ 12% │ │ ▼ 8% │ │ ▼ 50% │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ┌─ 엔드포인트별 응답 시간 (Top 10) ──────────────────────────────────────┐ │
│ │ Endpoint Avg P95 P99 Count │ │
│ │ POST /api/v1/diagnosis/analyze 250ms 450ms 800ms 1,234 │ │
│ │ GET /api/v1/products 45ms 85ms 120ms 15,678 │ │
│ │ POST /api/v1/auth/login 80ms 150ms 200ms 3,456 │ │
│ │ GET /api/v1/health-data 65ms 120ms 180ms 8,901 │ │
│ │ ... │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ 상태 코드 분포 ───────────────────────────────────────────────────────┐ │
│ │ 200 OK ████████████████████████████████████████ 92.5% │ │
│ │ 201 Created █████ 5.2% │ │
│ │ 400 Bad Request ██ 1.8% │ │
│ │ 401 Unauthorized█ 0.3% │ │
│ │ 500 Error ░ 0.2% │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
주요 메트릭 쿼리:
| 용도 | PromQL 쿼리 |
|---|---|
| API 요청률 | rate(http_requests_total[5m]) |
| 평균 응답 시간 | rate(http_request_duration_seconds_sum[5m]) / rate(http_request_duration_seconds_count[5m]) |
| 에러율 | sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) |
| AI 진단 요청 | rate(diagnosis_requests_total[5m]) |
| DB 연결 수 | pg_stat_activity_count |
| Redis 메모리 | redis_memory_used_bytes |
| 컨테이너 CPU | rate(container_cpu_usage_seconds_total[5m]) |
기본 알림 규칙:
# alerts.yml
groups:
- name: api_alerts
rules:
# API 응답 시간 초과
- alert: APIHighLatency
expr: histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m])) > 0.5
for: 5m
labels:
severity: warning
annotations:
summary: "API 응답 시간 초과"
description: "P95 응답 시간이 500ms를 초과했습니다."
# 에러율 상승
- alert: HighErrorRate
expr: sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) > 0.01
for: 5m
labels:
severity: critical
annotations:
summary: "높은 에러율 감지"
description: "에러율이 1%를 초과했습니다."
- name: infrastructure_alerts
rules:
# 디스크 사용량
- alert: HighDiskUsage
expr: (node_filesystem_size_bytes - node_filesystem_free_bytes) / node_filesystem_size_bytes > 0.8
for: 5m
labels:
severity: warning
annotations:
summary: "디스크 사용량 80% 초과"
# 메모리 사용량
- alert: HighMemoryUsage
expr: (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes > 0.85
for: 5m
labels:
severity: warning
annotations:
summary: "메모리 사용량 85% 초과"
# 컨테이너 다운
- alert: ContainerDown
expr: absent(container_last_seen{name=~"hospital_.*"}) == 1
for: 1m
labels:
severity: critical
annotations:
summary: "컨테이너 다운"
description: "Hospital 컨테이너가 응답하지 않습니다."알림 채널 설정:
# alertmanager.yml
global:
smtp_smarthost: 'smtp.gmail.com:587'
smtp_from: 'alert@hospital.com'
smtp_auth_username: 'alert@hospital.com'
smtp_auth_password: '${SMTP_PASSWORD}'
route:
group_by: ['alertname']
group_wait: 30s
group_interval: 5m
repeat_interval: 1h
receiver: 'admin-email'
routes:
- match:
severity: critical
receiver: 'admin-sms'
receivers:
- name: 'admin-email'
email_configs:
- to: 'admin@hospital.com'
- name: 'admin-sms'
webhook_configs:
- url: 'http://sms-gateway/send'파일 위치:
/opt/hospital/.env.production
환경 변수 카테고리:
# PostgreSQL
DATABASE_URL=postgresql://postgres:hospital_dev_password_2025@hospital_postgres:5432/medical_platform
# Redis
REDIS_URL=redis://hospital_redis:6379
REDIS_PASSWORD=# OpenAI
OPENAI_API_KEY=sk-...
OPENAI_MODEL=gpt-4-turbo-preview
# Google Gemini
GEMINI_API_KEY=...
GEMINI_MODEL=gemini-pro
# xAI Grok
GROK_API_KEY=...# JWT
JWT_SECRET=your-super-secret-key-minimum-32-characters
JWT_EXPIRES_IN=1d
JWT_REFRESH_EXPIRES_IN=7d
# OAuth (소셜 로그인)
GOOGLE_CLIENT_ID=...
GOOGLE_CLIENT_SECRET=...
KAKAO_CLIENT_ID=...
KAKAO_CLIENT_SECRET=...# AES-256 암호화
ENCRYPTION_KEY=32-character-encryption-key-here
ENCRYPTION_IV=16-char-iv-here!# 결제
TOSS_CLIENT_KEY=...
TOSS_SECRET_KEY=...
# 알림
FIREBASE_PROJECT_ID=...
FIREBASE_PRIVATE_KEY=...
KAKAO_ALIMTALK_KEY=...
SMS_API_KEY=...환경 변수 변경 후:
# 컨테이너 재시작 필요
docker-compose -f docker-compose.production.yml restart
# 또는 특정 서비스만
docker-compose -f docker-compose.production.yml restart hospital_api_gateway스케줄: 매일 02:00 AM (KST)
백업 스크립트:
/opt/hospital/scripts/backup/daily-backup.sh
#!/bin/bash
# daily-backup.sh
BACKUP_DIR="/opt/hospital/backups"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_NAME="hospital_backup_${DATE}"
# 1. PostgreSQL 백업
echo "PostgreSQL 백업 시작..."
docker exec hospital_postgres pg_dump -U postgres medical_platform | gzip > "${BACKUP_DIR}/${BACKUP_NAME}_postgres.sql.gz"
# 2. Redis 백업
echo "Redis 백업 시작..."
docker exec hospital_redis redis-cli BGSAVE
sleep 5
docker cp hospital_redis:/data/dump.rdb "${BACKUP_DIR}/${BACKUP_NAME}_redis.rdb"
# 3. MinIO 파일 백업
echo "MinIO 파일 백업 시작..."
docker run --rm -v minio_data:/data -v ${BACKUP_DIR}:/backup alpine tar czf "/backup/${BACKUP_NAME}_minio.tar.gz" /data
# 4. 설정 파일 백업
echo "설정 파일 백업 시작..."
tar czf "${BACKUP_DIR}/${BACKUP_NAME}_config.tar.gz" \
/opt/hospital/.env.production \
/opt/hospital/infrastructure/nginx \
/opt/hospital/docker-compose.production.yml
# 5. 전체 아카이브
echo "전체 아카이브 생성..."
tar czf "${BACKUP_DIR}/${BACKUP_NAME}.tar.gz" \
"${BACKUP_DIR}/${BACKUP_NAME}_postgres.sql.gz" \
"${BACKUP_DIR}/${BACKUP_NAME}_redis.rdb" \
"${BACKUP_DIR}/${BACKUP_NAME}_minio.tar.gz" \
"${BACKUP_DIR}/${BACKUP_NAME}_config.tar.gz"
# 6. 개별 파일 삭제
rm -f "${BACKUP_DIR}/${BACKUP_NAME}_postgres.sql.gz"
rm -f "${BACKUP_DIR}/${BACKUP_NAME}_redis.rdb"
rm -f "${BACKUP_DIR}/${BACKUP_NAME}_minio.tar.gz"
rm -f "${BACKUP_DIR}/${BACKUP_NAME}_config.tar.gz"
# 7. 오래된 백업 삭제 (30일 이상)
find "${BACKUP_DIR}" -name "hospital_backup_*.tar.gz" -mtime +30 -delete
echo "백업 완료: ${BACKUP_NAME}.tar.gz"# 즉시 백업 실행
cd /opt/hospital
npm run backup
# 또는
bash scripts/backup/daily-backup.sh# 복원 스크립트 실행
cd /opt/hospital
bash scripts/backup/restore-backup.sh /opt/hospital/backups/hospital_backup_20251130_020000.tar.gz복원 절차:
1. 서비스 중지
docker-compose -f docker-compose.production.yml down
2. 백업 파일 압축 해제
tar xzf hospital_backup_20251130_020000.tar.gz
3. PostgreSQL 복원
gunzip -c hospital_backup_20251130_020000_postgres.sql.gz | \
docker exec -i hospital_postgres psql -U postgres medical_platform
4. Redis 복원
docker cp hospital_backup_20251130_020000_redis.rdb hospital_redis:/data/dump.rdb
docker restart hospital_redis
5. MinIO 복원
docker run --rm -v minio_data:/data -v ${BACKUP_DIR}:/backup alpine \
tar xzf /backup/hospital_backup_20251130_020000_minio.tar.gz -C /
6. 서비스 재시작
docker-compose -f docker-compose.production.yml up -d
7. 데이터 무결성 확인
curl http://localhost:8080/api/v1/health
# 전체 컨테이너 상태
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep hospital
# 상세 상태
docker-compose -f docker-compose.production.yml ps
# 리소스 사용량
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}" | grep hospital# 전체 재시작
docker-compose -f docker-compose.production.yml restart
# 특정 서비스만
docker-compose -f docker-compose.production.yml restart hospital_api_gateway
docker-compose -f docker-compose.production.yml restart hospital_web
docker-compose -f docker-compose.production.yml restart hospital_postgres
# 완전 재생성 (설정 변경 시)
docker-compose -f docker-compose.production.yml up -d --force-recreate hospital_api_gateway# 전체 로그 (실시간)
docker-compose -f docker-compose.production.yml logs -f
# 특정 서비스 로그
docker-compose -f docker-compose.production.yml logs -f hospital_api_gateway
# 최근 N줄만
docker-compose -f docker-compose.production.yml logs --tail=100 hospital_web
# 시간 범위 지정
docker-compose -f docker-compose.production.yml logs --since="2025-11-30T00:00:00" hospital_api_gateway
# 에러 로그만 필터링
docker-compose -f docker-compose.production.yml logs hospital_api_gateway 2>&1 | grep -i error# API Gateway 컨테이너 진입
docker exec -it hospital_api_gateway sh
# PostgreSQL 접속
docker exec -it hospital_postgres psql -U postgres medical_platform
# Redis 접속
docker exec -it hospital_redis redis-cli┌─────────────────────────────────────────────────────────────────────────────┐
│ 데이터 보호 아키텍처 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─ 전송 계층 보안 ───────────────────────────────────────────────────────┐ │
│ │ • HTTPS/TLS 1.3 필수 │ │
│ │ • HSTS (HTTP Strict Transport Security) 활성화 │ │
│ │ • 인증서: Let's Encrypt 자동 갱신 │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─ 애플리케이션 계층 보안 ───────────────────────────────────────────────┐ │
│ │ • JWT 토큰 인증 (RS256) │ │
│ │ • Rate Limiting (100 req/min) │ │
│ │ • CORS 정책 적용 │ │
│ │ • XSS/CSRF 보호 │ │
│ │ • SQL Injection 방지 (Prisma ORM) │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─ 데이터 계층 보안 ─────────────────────────────────────────────────────┐ │
│ │ • 민감 데이터 AES-256 암호화 │ │
│ │ • 비밀번호 bcrypt 해싱 (salt rounds: 10) │ │
│ │ • 개인정보 비식별화 (k-anonymity >= 5) │ │
│ │ • 데이터베이스 암호화 (TDE) │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─ 감사 및 모니터링 ─────────────────────────────────────────────────────┐ │
│ │ • 모든 API 호출 로깅 │ │
│ │ • 민감 데이터 접근 감사 추적 │ │
│ │ • 이상 탐지 (Anomaly Detection) │ │
│ │ • 실시간 알림 │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
| 리소스 | ADMIN | DOCTOR | PATIENT | PARTNER |
|---|---|---|---|---|
| 사용자 관리 | CRUD | R (본인) | R (본인) | R (본인) |
| 전체 사용자 목록 | R | - | - | - |
| AI 진단 | CRUD | R | R (본인) | - |
| 처방전 | CRUD | CRU | R (본인) | R (관련) |
| 처방 승인 | ✓ | ✓ | - | - |
| 상품 | CRUD | R | R | CRU (본인) |
| 주문 | CRUD | R (관련) | CRUD (본인) | R (관련) |
| 건강 데이터 | R | R (관련) | CRUD (본인) | - |
| 시스템 설정 | CRUD | - | - | - |
| 모니터링 | R | - | - | - |
| API 키 | CRUD | - | - | R (본인) |
| 항목 | 상태 | 구현 내용 |
|---|---|---|
| 개인정보 수집 동의 | ✅ | 회원가입 시 필수 동의 |
| 목적 명시 | ✅ | 개인정보 처리방침 명시 |
| 최소 수집 원칙 | ✅ | 필수 정보만 수집 |
| 제3자 제공 동의 | ✅ | 별도 동의 절차 |
| 파기 절차 | ✅ | 탈퇴 시 30일 후 삭제 |
| 열람/정정/삭제권 | ✅ | 마이페이지에서 가능 |
| 항목 | 상태 | 구현 내용 |
|---|---|---|
| AI 진단 면책 고지 | ✅ | “참고용이며 의사 판단 필요” 명시 |
| 의사 승인 워크플로우 | ✅ | 모든 처방에 의사 승인 필수 |
| 의료 광고 규제 | ✅ | 과대 광고 금지 |
| 영역 | 항목 | 상태 |
|---|---|---|
| 관리체계 | 정보보호 정책 | ✅ |
| 조직 구성 | ⏳ | |
| 위험 관리 | ✅ | |
| 보호대책 | 접근통제 | ✅ |
| 암호화 | ✅ | |
| 물리적 보안 | ⏳ | |
| 운영 보안 | ✅ | |
| 개인정보 | 수집/이용 동의 | ✅ |
| 제3자 제공 | ✅ | |
| 파기 | ✅ |
┌─────────────────────────────────────────────────────────────────────────────┐
│ 데이터베이스 ERD (핵심 테이블) │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ users │ │ diagnoses │ │prescriptions│ │
│ ├─────────────┤ ├─────────────┤ ├─────────────┤ │
│ │ id (PK) │──┐ │ id (PK) │ │ id (PK) │ │
│ │ email │ │ │ user_id(FK) │◀──┐ │ diagnosis_id│◀──────┐ │
│ │ password │ │ │ symptoms │ │ │ doctor_id │ │ │
│ │ role │ │ │ result │ │ │ status │ │ │
│ │ created_at │ │ │ confidence │ │ │ items[] │ │ │
│ └─────────────┘ │ │ model_ver │ │ │ approved_at │ │ │
│ │ │ └─────────────┘ │ └─────────────┘ │ │
│ │ │ │ │ │ │ │
│ │ └───────────┼──────────┘ │ │ │
│ │ │ │ │ │
│ ▼ │ │ │ │
│ ┌─────────────┐ │ │ │ │
│ │user_profiles│ │ │ │ │
│ ├─────────────┤ │ │ │ │
│ │ user_id(FK) │◀─────────────┘ │ │ │
│ │ name │ │ │ │
│ │ birth_date │ │ │ │
│ │ gender │ │ │ │
│ │ phone │ │ │ │
│ └─────────────┘ │ │ │
│ │ │ │ │
│ │ ┌─────────────┐ │ │ │
│ │ │ orders │ │ │ │
│ │ ├─────────────┤ │ │ │
│ └────────▶│ user_id(FK) │ │ │ │
│ │ total_amount│ │ │ │
│ │ status │ │ │ │
│ │ created_at │ │ │ │
│ └─────────────┘ │ │ │
│ │ │ │ │
│ ▼ │ │ │
│ ┌─────────────┐ ┌─────────────┐ │ │
│ │ order_items │ │ products │───────┘ │
│ ├─────────────┤ ├─────────────┤ │
│ │ order_id(FK)│ │ id (PK) │ │
│ │ product_id │──────────▶│ name │ │
│ │ quantity │ │ category │ │
│ │ price │ │ price │ │
│ └─────────────┘ │ ingredients │ │
│ └─────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
| 테이블 | 설명 | 주요 컬럼 |
|---|---|---|
| users | 사용자 기본 정보 | id, email, password_hash, role, status |
| user_profiles | 사용자 상세 정보 | user_id, name, birth_date, gender, phone |
| diagnoses | AI 진단 결과 | user_id, symptoms, result, confidence, urgency |
| prescriptions | 처방전 | diagnosis_id, doctor_id, status, items |
| products | 상품 정보 | name, category, price, ingredients, stock |
| orders | 주문 | user_id, total_amount, status, shipping_info |
| order_items | 주문 상품 | order_id, product_id, quantity, price |
| health_records | 건강 기록 | user_id, type, data, measured_at |
| iot_data | IoT 수집 데이터 | user_id, device_id, data, timestamp |
| telemedicine_appointments | 비대면 예약 | patient_id, doctor_id, scheduled_at, status |
| partners | 파트너 정보 | name, type, api_key, commission_rate |
# PostgreSQL 접속
docker exec -it hospital_postgres psql -U postgres medical_platform
# 또는 호스트에서
PGPASSWORD='hospital_dev_password_2025' psql -h localhost -p 5434 -U postgres -d medical_platform-- 테이블 목록 확인
\dt
-- 테이블 구조 확인
\d users
-- 사용자 통계
SELECT role, COUNT(*) as count
FROM users
GROUP BY role;
-- 오늘의 진단 수
SELECT COUNT(*)
FROM diagnoses
WHERE DATE(created_at) = CURRENT_DATE;
-- 저신뢰도 진단 목록
SELECT id, user_id, confidence, created_at
FROM diagnoses
WHERE confidence < 0.7
ORDER BY created_at DESC
LIMIT 20;
-- 주문 현황
SELECT status, COUNT(*), SUM(total_amount) as total
FROM orders
WHERE DATE(created_at) >= CURRENT_DATE - INTERVAL '7 days'
GROUP BY status;
-- 슬로우 쿼리 확인
SELECT query, calls, total_time, mean_time
FROM pg_stat_statements
ORDER BY mean_time DESC
LIMIT 10;# 마이그레이션 생성 및 적용
cd /opt/hospital
DATABASE_URL="postgresql://postgres:hospital_dev_password_2025@localhost:5434/medical_platform" \
npx prisma migrate dev --name migration_name
# 프로덕션 마이그레이션 적용
DATABASE_URL="postgresql://postgres:hospital_dev_password_2025@localhost:5434/medical_platform" \
npx prisma migrate deploy
# Prisma Studio (GUI)
npx prisma studio인덱스 권장 사항:
-- 자주 조회되는 컬럼에 인덱스
CREATE INDEX idx_diagnoses_user_id ON diagnoses(user_id);
CREATE INDEX idx_diagnoses_created_at ON diagnoses(created_at);
CREATE INDEX idx_diagnoses_confidence ON diagnoses(confidence);
CREATE INDEX idx_orders_user_id ON orders(user_id);
CREATE INDEX idx_orders_status ON orders(status);
CREATE INDEX idx_orders_created_at ON orders(created_at);
CREATE INDEX idx_health_records_user_id ON health_records(user_id);
CREATE INDEX idx_health_records_type ON health_records(type);
-- 복합 인덱스
CREATE INDEX idx_prescriptions_status_created
ON prescriptions(status, created_at);쿼리 최적화 팁: - EXPLAIN ANALYZE로 쿼리 계획 확인 - 불필요한 JOIN 제거 - SELECT * 대신 필요한 컬럼만 조회 - LIMIT 사용으로 결과 제한 - 배치 처리로 대량 데이터 처리
Swagger UI: https://starium.site:8080/api/docs
┌─────────────────────────────────────────────────────────────────────────────┐
│ AI Medical Platform API - Swagger UI │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Base URL: https://starium.site:8080/api/v1 │
│ │
│ ┌─ Auth ─────────────────────────────────────────────────────────────────┐ │
│ │ POST /auth/register 사용자 회원가입 │ │
│ │ POST /auth/login 로그인 │ │
│ │ POST /auth/refresh 토큰 갱신 │ │
│ │ POST /auth/logout 로그아웃 │ │
│ │ POST /auth/verify-email 이메일 인증 │ │
│ │ POST /auth/forgot-password 비밀번호 찾기 │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ Users ────────────────────────────────────────────────────────────────┐ │
│ │ GET /users/me 내 정보 조회 │ │
│ │ PUT /users/me 내 정보 수정 │ │
│ │ GET /users/{id} 사용자 조회 (Admin) │ │
│ │ GET /users 사용자 목록 (Admin) │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ Diagnosis ────────────────────────────────────────────────────────────┐ │
│ │ POST /diagnosis/analyze AI 진단 요청 │ │
│ │ GET /diagnosis/{id} 진단 결과 조회 │ │
│ │ GET /diagnosis/history 진단 이력 │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ Prescription ─────────────────────────────────────────────────────────┐ │
│ │ GET /prescription/{id} 처방전 조회 │ │
│ │ POST /prescription/{id}/approve 처방 승인 (Doctor) │ │
│ │ POST /prescription/recommend 처방 추천 생성 │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ Products ─────────────────────────────────────────────────────────────┐ │
│ │ GET /products 상품 목록 │ │
│ │ GET /products/{id} 상품 상세 │ │
│ │ POST /products 상품 등록 (Admin/Partner) │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ... (더 많은 엔드포인트) │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
성공 응답:
{
"success": true,
"data": {
"id": "usr_abc123",
"email": "user@example.com",
"role": "PATIENT"
},
"meta": {
"timestamp": "2025-11-30T10:30:00Z",
"requestId": "req_xyz789"
}
}페이지네이션 응답:
{
"success": true,
"data": [...],
"pagination": {
"page": 1,
"limit": 20,
"total": 150,
"totalPages": 8
}
}에러 응답:
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "입력값이 올바르지 않습니다.",
"details": [
{
"field": "email",
"message": "유효한 이메일 형식이 아닙니다."
}
]
},
"meta": {
"timestamp": "2025-11-30T10:30:00Z",
"requestId": "req_xyz789"
}
}| 코드 | HTTP 상태 | 설명 |
|---|---|---|
| AUTH_INVALID_CREDENTIALS | 401 | 잘못된 인증 정보 |
| AUTH_TOKEN_EXPIRED | 401 | 토큰 만료 |
| AUTH_UNAUTHORIZED | 403 | 권한 없음 |
| VALIDATION_ERROR | 400 | 입력값 검증 실패 |
| RESOURCE_NOT_FOUND | 404 | 리소스 없음 |
| DIAGNOSIS_AI_MODEL_UNAVAILABLE | 503 | AI 모델 이용 불가 |
| DIAGNOSIS_LOW_CONFIDENCE | 422 | 낮은 신뢰도 |
| PRESCRIPTION_ALREADY_APPROVED | 409 | 이미 승인된 처방 |
| ORDER_PAYMENT_FAILED | 402 | 결제 실패 |
| RATE_LIMIT_EXCEEDED | 429 | 요청 한도 초과 |
| SYSTEM_DATABASE_ERROR | 500 | DB 오류 |
| SYSTEM_INTERNAL_ERROR | 500 | 내부 오류 |
| 엔드포인트 | 제한 | 윈도우 |
|---|---|---|
| 인증 관련 | 10회 | 1분 |
| AI 진단 | 5회 | 1분 |
| 일반 API | 100회 | 1분 |
| 파트너 API | 1000회 | 1분 |
Rate Limit 응답 헤더:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1701340800
증상: https://starium.site:8080 접속 불가
진단 단계:
# 1. 컨테이너 상태 확인
docker ps | grep hospital
# 2. Nginx 상태 확인
docker logs hospital_nginx --tail=50
# 3. 네트워크 확인
curl -I http://localhost:8080
# 4. 방화벽 확인
ufw status해결 방법:
# Nginx 재시작
docker-compose -f docker-compose.production.yml restart hospital_nginx
# 또는 전체 재시작
docker-compose -f docker-compose.production.yml restart증상: SYSTEM_DATABASE_ERROR, 연결
타임아웃
진단 단계:
# 1. PostgreSQL 컨테이너 상태
docker ps | grep hospital_postgres
# 2. 로그 확인
docker logs hospital_postgres --tail=100
# 3. 연결 테스트
docker exec -it hospital_postgres pg_isready -U postgres
# 4. 연결 수 확인
docker exec -it hospital_postgres psql -U postgres -c "SELECT count(*) FROM pg_stat_activity;"해결 방법:
# 컨테이너 재시작
docker-compose -f docker-compose.production.yml restart hospital_postgres
# 연결 수 초과 시 - 유휴 연결 정리
docker exec -it hospital_postgres psql -U postgres -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE state = 'idle' AND query_start < now() - interval '10 minutes';"증상: DIAGNOSIS_AI_MODEL_UNAVAILABLE,
진단 요청 실패
진단 단계:
# 1. API 키 확인
grep OPENAI_API_KEY /opt/hospital/.env.production
grep GEMINI_API_KEY /opt/hospital/.env.production
# 2. 외부 API 연결 테스트
curl -I https://api.openai.com/v1/models
# 3. API 사용량 확인 (OpenAI 대시보드)
# https://platform.openai.com/usage해결 방법: - API 키 유효성 확인 - 사용량 한도 확인 및 증설 - 폴백 모델 활성화 (Gemini/Grok)
증상: 세션 유지 안 됨, 캐싱 동작 안 함
진단 단계:
# 1. Redis 상태 확인
docker exec -it hospital_redis redis-cli ping
# 응답: PONG
# 2. 메모리 확인
docker exec -it hospital_redis redis-cli info memory
# 3. 키 수 확인
docker exec -it hospital_redis redis-cli dbsize해결 방법:
# Redis 재시작
docker-compose -f docker-compose.production.yml restart hospital_redis
# 메모리 부족 시 - 캐시 정리
docker exec -it hospital_redis redis-cli FLUSHDB진단:
# 1. Grafana에서 응답 시간 확인
# http://139.180.204.158:3002
# 2. 슬로우 쿼리 확인
docker exec -it hospital_postgres psql -U postgres -c "SELECT query, calls, mean_time FROM pg_stat_statements ORDER BY mean_time DESC LIMIT 10;"
# 3. API Gateway 리소스 확인
docker stats hospital_api_gateway해결 방법: - 슬로우 쿼리 최적화 (인덱스 추가) - Redis 캐싱 활성화 - API Gateway 스케일 아웃
증상: OOM Killer, 컨테이너 재시작
진단:
# 메모리 사용량 확인
docker stats --no-stream
# OOM 로그 확인
dmesg | grep -i "out of memory"해결 방법:
# docker-compose.production.yml 수정
services:
hospital_api_gateway:
deploy:
resources:
limits:
memory: 2G
reservations:
memory: 1G긴급 대응 절차:
1. 서비스 상태 확인
docker-compose -f docker-compose.production.yml ps
2. 전체 재시작
docker-compose -f docker-compose.production.yml restart
3. 로그 수집
docker-compose -f docker-compose.production.yml logs --since="10m" > emergency_logs.txt
4. 관리자 통보
- 이메일: admin@hospital.com
- 긴급 연락처 호출
5. 원인 분석
- Grafana 대시보드 확인
- 로그 분석
- 최근 변경사항 확인
6. 복구
- 필요 시 백업에서 복원
- 데이터 무결성 확인
긴급 대응 절차:
1. 즉시 조치
- 의심 계정 정지
- API 키 비활성화
- VPN/방화벽 강화
2. 증거 수집
- 접근 로그 보존
- 감사 로그 백업
- 스크린샷 저장
3. 영향 범위 파악
- 접근된 데이터 확인
- 영향받은 사용자 식별
4. 통보
- 경영진 보고
- 법무팀 연락
- 필요 시 관계 기관 신고
5. 사후 조치
- 영향받은 사용자 통지
- 비밀번호 재설정 요청
- 보안 패치 적용
- 재발 방지 대책 수립
| 시간 | 항목 | 담당 | 확인 |
|---|---|---|---|
| 09:00 | 시스템 상태 확인 (Grafana) | 운영팀 | ☐ |
| 09:00 | 에러 로그 확인 | 운영팀 | ☐ |
| 09:00 | 대기 중인 처방 확인 | 운영팀 | ☐ |
| 12:00 | 주문 처리 현황 확인 | 운영팀 | ☐ |
| 18:00 | 일일 통계 확인 | 운영팀 | ☐ |
| 18:00 | 백업 상태 확인 | 운영팀 | ☐ |
| 항목 | 담당 | 확인 |
|---|---|---|
| 보안 패치 확인 | 보안팀 | ☐ |
| 디스크 사용량 확인 | 운영팀 | ☐ |
| 데이터베이스 성능 분석 | DBA | ☐ |
| AI 진단 정확도 리뷰 | AI팀 | ☐ |
| 사용자 피드백 분석 | 기획팀 | ☐ |
| 항목 | 담당 | 확인 |
|---|---|---|
| 전체 백업 테스트 | 운영팀 | ☐ |
| 재해 복구 훈련 | 운영팀 | ☐ |
| 보안 취약점 스캔 | 보안팀 | ☐ |
| 인증서 만료 확인 | 운영팀 | ☐ |
| 용량 계획 검토 | 인프라팀 | ☐ |
| KPI 리뷰 | 경영팀 | ☐ |
# === Docker 관리 ===
# 컨테이너 상태
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep hospital
# 전체 재시작
docker-compose -f docker-compose.production.yml restart
# 로그 확인
docker-compose -f docker-compose.production.yml logs -f --tail=100
# === 데이터베이스 ===
# PostgreSQL 접속
docker exec -it hospital_postgres psql -U postgres medical_platform
# Redis 접속
docker exec -it hospital_redis redis-cli
# === 백업 ===
# 수동 백업
bash /opt/hospital/scripts/backup/daily-backup.sh
# === 모니터링 ===
# 리소스 사용량
docker stats
# 포트 확인
ss -tlnp | grep LISTEN| 파일/디렉토리 | 경로 | 설명 |
|---|---|---|
| 환경 변수 | /opt/hospital/.env.production | 프로덕션 설정 |
| Docker Compose | /opt/hospital/docker-compose.production.yml | 컨테이너 설정 |
| Nginx 설정 | /opt/hospital/infrastructure/nginx/ | 웹서버 설정 |
| 백업 디렉토리 | /opt/hospital/backups/ | 백업 파일 |
| 로그 디렉토리 | /var/log/hospital/ | 애플리케이션 로그 |
| Prisma 스키마 | /opt/hospital/packages/database/prisma/schema.prisma | DB 스키마 |
| 담당 | 연락처 | 역할 |
|---|---|---|
| 시스템 관리자 | admin@hospital.com | 전체 시스템 관리 |
| 보안 담당 | security@hospital.com | 보안 이슈 |
| DBA | dba@hospital.com | 데이터베이스 |
| AI팀 | ai@hospital.com | AI 진단 관련 |
| 버전 | 날짜 | 변경 내용 |
|---|---|---|
| 2.0.0 | 2025-11-30 | 전면 개편, 상세 내용 추가 |
| 1.0.0 | 2025-11-29 | 초기 버전 |
이 매뉴얼은 시스템 업데이트에 따라 지속적으로 갱신됩니다.
최신 버전: /opt/hospital/docs/manuals/관리자_매뉴얼.md
© 2025 AI Medical Platform. All Rights Reserved.