From 7314c0075df625b49a9b1ccc6e93a6bc99b6caa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=9C=EA=B3=A8=EC=95=BD=EC=82=AC?= Date: Tue, 17 Feb 2026 03:26:37 +0000 Subject: [PATCH] =?UTF-8?q?docs:=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EA=B5=AC?= =?UTF-8?q?=EC=A1=B0=20=EB=B0=8F=20=ED=9D=90=EB=A6=84=20=EB=AC=B8=EC=84=9C?= =?UTF-8?q?=20=EC=99=84=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 전체 시스템 데이터 흐름 문서 추가 - 테이블 관계 및 JOIN 경로 명확화 - ingredient_code 중심 설계 반영 - claude.md 메인 문서 추가 - 한약재 정보 관리 시스템 설계 문서 개선 주요 내용: - 코드 체계 (성분코드 vs 보험코드) 설명 - 개선된 JOIN 구조 (5단계 → 3단계) - 효능 태그 시스템 리팩토링 반영 - 개발 가이드 및 주의사항 포함 --- claude.md | 241 ++++++++++++++++++ docs/데이터_구조_및_흐름.md | 367 +++++++++++++++++++++++++++ docs/한약재_정보_관리_시스템_설계.md | 10 +- 3 files changed, 613 insertions(+), 5 deletions(-) create mode 100644 claude.md create mode 100644 docs/데이터_구조_및_흐름.md diff --git a/claude.md b/claude.md new file mode 100644 index 0000000..bbaeb07 --- /dev/null +++ b/claude.md @@ -0,0 +1,241 @@ +# 한약 재고관리 시스템 (kdrug) + +## 프로젝트 개요 + +한의원에서 한약재 재고를 관리하고 처방 조제를 추적하는 통합 시스템입니다. + +### 주요 기능 +- 📦 **재고 관리**: 한약재 입고/출고/재고 추적 +- 💊 **처방 조제**: 표준 처방 및 가감방 조제 +- 🏥 **보험 청구**: 건강보험 급여 약재 코드 관리 +- 🔍 **효능 검색**: 약재 효능별 검색 및 분류 +- 📊 **통계 분석**: 재고 현황 및 소비 패턴 분석 + +## 기술 스택 + +- **Backend**: Python Flask +- **Database**: SQLite +- **Frontend**: Bootstrap 5 + jQuery +- **Excel**: pandas, openpyxl + +## 핵심 개념 + +### 코드 체계 +``` +성분코드 (ingredient_code) 보험코드 (insurance_code) +━━━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━━━ +"3400H1AHM" (인삼) "062400740" (휴먼감초) +- 454개 표준 약재 - 실제 청구/재고 단위 +- 한의학적 속성 기준 - 9자리 제품 코드 +``` + +### 테이블 관계 +``` +herb_items (재고) + ↓ insurance_code +herb_products (제품) + ↓ ingredient_code +herb_masters (마스터) + ↓ ingredient_code +herb_item_tags (효능) +``` + +## 프로젝트 구조 + +``` +kdrug/ +├── app.py # Flask 메인 애플리케이션 +├── database/ +│ ├── kdrug.db # SQLite 데이터베이스 +│ └── schema.sql # 스키마 정의 +├── static/ +│ ├── app.js # 프론트엔드 로직 +│ └── style.css # 스타일시트 +├── templates/ +│ └── index.html # SPA 템플릿 +├── docs/ +│ ├── 데이터_구조_및_흐름.md +│ ├── 조제_프로세스_및_커스텀_처방.md +│ └── 한약재_정보_관리_시스템_설계.md +└── migrations/ + └── add_herb_extended_info_tables.py +``` + +## 주요 API 엔드포인트 + +### 약재 관리 +- `GET /api/herbs` - 약재 목록 (효능 태그 포함) +- `GET /api/herbs/masters` - 전체 약재 마스터 (454개) +- `GET /api/herbs/{id}/extended` - 약재 상세 정보 +- `GET /api/herbs/{id}/tags` - 효능 태그 조회 +- `POST /api/herbs/{id}/tags` - 효능 태그 추가 + +### 재고 관리 +- `GET /api/inventory/summary` - 재고 현황 요약 +- `POST /api/purchase-receipts` - 입고 처리 +- `GET /api/herbs/{id}/available-lots` - 사용 가능한 로트 + +### 처방 조제 +- `GET /api/formulas` - 처방 목록 +- `GET /api/formulas/{id}/ingredients` - 처방 구성 +- `POST /api/compounds` - 조제 실행 +- `GET /api/patients/{id}/compounds` - 환자별 조제 이력 + +### 효능 검색 +- `GET /api/efficacy-tags` - 모든 효능 태그 +- `GET /api/herbs/search-by-efficacy` - 효능별 약재 검색 +- `POST /api/prescription-check` - 처방 안전성 검증 + +## 최근 개선사항 (2026-02-17) + +### 1. 효능 태그 시스템 리팩토링 ✅ +```sql +-- Before: 복잡한 5단계 JOIN +herb_items → products → masters → extended → tags + +-- After: 간단한 3단계 JOIN +herb_items → products → tags (ingredient_code 직접 사용) +``` + +### 2. 가감방 실시간 감지 ✅ +- 처방 수정 시 자동으로 "가감방" 배지 표시 +- `ingredient_code` 기준 비교로 정확도 향상 + +### 3. 복합 로트 지원 ✅ +- 한 약재에 여러 로트 사용 가능 +- 수동 로트 배분 UI 제공 +- FIFO 자동 배분 옵션 + +## 데이터베이스 설계 특징 + +### 정규화된 구조 +- 성분코드와 보험코드 분리 +- 재고는 로트 단위 관리 +- 처방 구성은 성분코드 기준 + +### 확장 가능한 설계 +- 효능 태그 시스템 (18개 기본 태그) +- 안전성 정보 테이블 +- 연구 문헌 관리 +- AI/API 업데이트 로그 + +### 성능 최적화 +- `ingredient_code` 인덱싱 +- 집계 쿼리용 서브쿼리 활용 +- GROUP_CONCAT으로 태그 조회 + +## 설치 및 실행 + +```bash +# 1. 의존성 설치 +pip install -r requirements.txt + +# 2. 데이터베이스 초기화 +python init_db.py + +# 3. 서버 실행 +python app.py + +# 4. 브라우저에서 접속 +http://localhost:5001 +``` + +## 개발 가이드 + +### 새 약재 추가 +1. `herb_masters`에 성분코드 확인 +2. `herb_products`에 보험코드 매핑 +3. `herb_items`에 재고 단위 생성 +4. 입고 처리로 `inventory_lots` 생성 + +### 효능 태그 추가 +```python +# ingredient_code로 직접 추가 (개선됨!) +INSERT INTO herb_item_tags (ingredient_code, tag_id, strength) +VALUES ('3400H1AHM', 1, 5) # 인삼에 보기(5) 추가 +``` + +### API 개발 원칙 +- `ingredient_code` 중심 JOIN +- `herb_products` 테이블 활용 +- COALESCE로 안전한 처리 +- 효능 태그는 선택적 로드 + +## 주의사항 + +### ID 체계 +- ⚠️ `herb_item_id` ≠ `herb_id` +- `herb_item_id`: 재고 관리 (1~31) +- `herb_id`: 단순 인덱스 (1~454) +- 실제 KEY: `ingredient_code` + +### 코드 매핑 +- 입력: 보험코드 (9자리) +- 중간: `herb_products` 매핑 +- 최종: `ingredient_code` 연결 + +### 재고 처리 +- FIFO 원칙 +- 로트별 추적 +- 복합 로트 지원 + +## 향후 계획 + +### Phase 2: AI 통합 +- 한의학연구원 API 연동 +- PubMed 문헌 자동 수집 +- ChatGPT 기반 정보 추출 + +### Phase 3: 임상 지원 +- DUR 시스템 구현 +- 처방 최적화 제안 +- 부작용 모니터링 + +### Phase 4: 분석 강화 +- 소비 패턴 분석 +- 재고 예측 모델 +- 비용 최적화 + +## 문제 해결 + +### 약재 드롭다운이 안 나올 때 +```python +# /api/herbs 엔드포인트 확인 +# herb_products 매핑 확인 +# ingredient_code 연결 확인 +``` + +### 효능 태그가 안 보일 때 +```python +# herb_item_tags 테이블 확인 +# ingredient_code 매핑 확인 +# JOIN 경로 확인 +``` + +### 가감방이 감지 안 될 때 +```python +# originalFormulaIngredients 전역 변수 확인 +# ingredient_code 비교 로직 확인 +# 약재 추가/삭제 이벤트 확인 +``` + +## 기여 가이드 + +1. 기존 시스템 이해 +2. 영향도 분석 +3. 테스트 작성 +4. 문서 업데이트 +5. PR 제출 + +## 라이선스 + +Private Project - All rights reserved + +## 문의 + +개발팀 연락처: [이메일/슬랙] + +--- + +*Last updated: 2026-02-17* +*Version: 1.0.0* \ No newline at end of file diff --git a/docs/데이터_구조_및_흐름.md b/docs/데이터_구조_및_흐름.md new file mode 100644 index 0000000..393100b --- /dev/null +++ b/docs/데이터_구조_및_흐름.md @@ -0,0 +1,367 @@ +# 한약 재고관리 시스템 데이터 구조 및 흐름 + +> 최종 수정: 2026-02-17 +> 작성자: 시스템 개발팀 + +## 📊 1. 전체 시스템 개요 + +### 1.1 시스템 목적 +- 한의원의 한약재 재고 관리 +- 처방 조제 및 소비 추적 +- 보험 청구를 위한 코드 관리 +- 효능 기반 약재 정보 관리 + +### 1.2 핵심 개념 +``` +┌─────────────────────────────────────────────┐ +│ 성분코드 (ingredient_code) │ +│ - 한약재의 본질적 정체성 │ +│ - 예: "3400H1AHM" = 인삼 │ +│ - 총 454개 표준 약재 │ +└─────────────────────────────────────────────┘ + ↓ +┌─────────────────────────────────────────────┐ +│ 보험코드 (insurance_code) │ +│ - 실제 청구/재고 관리 단위 │ +│ - 9자리 제품 코드 │ +│ - 예: "062400740" = 휴먼감초 │ +└─────────────────────────────────────────────┘ +``` + +## 🗂️ 2. 테이블 구조 상세 + +### 2.1 마스터 데이터 (Master Data) + +#### **herb_masters** - 성분코드 마스터 +```sql +CREATE TABLE herb_masters ( + ingredient_code VARCHAR(10) PRIMARY KEY, -- "3400H1AHM" + herb_name VARCHAR(100), -- "인삼" + herb_name_hanja VARCHAR(100), -- "人蔘" + herb_name_latin VARCHAR(200) -- "Ginseng Radix" +) +-- 역할: 454개 표준 한약재 정의 +-- 특징: 보험급여 약재 목록 +``` + +#### **herb_master_extended** - 확장 정보 +```sql +CREATE TABLE herb_master_extended ( + herb_id INTEGER PRIMARY KEY AUTOINCREMENT, -- 단순 인덱스 + ingredient_code VARCHAR(10) UNIQUE, -- herb_masters와 1:1 + property VARCHAR(50), -- 성(性): 온/한/평 + taste VARCHAR(100), -- 미(味): 감/고/신 + meridian_tropism TEXT, -- 귀경: 비,폐,심 + main_effects TEXT, -- 주요 효능 + dosage_range VARCHAR(50) -- 상용량: "3-9g" +) +-- 역할: 한의학적 속성 정보 저장 +-- 관계: ingredient_code로 herb_masters와 연결 +``` + +### 2.2 제품 및 재고 (Products & Inventory) + +#### **herb_products** - 제품 카탈로그 +```sql +CREATE TABLE herb_products ( + product_id INTEGER PRIMARY KEY, + ingredient_code VARCHAR(10), -- 성분코드 (FK) + product_code VARCHAR(9), -- 보험코드 9자리 + company_name VARCHAR(200), -- "휴먼허브" + product_name VARCHAR(200) -- "휴먼감초" +) +-- 역할: 성분코드 ↔ 보험코드 매핑 +-- 특징: 여러 회사가 같은 성분을 다른 코드로 판매 +``` + +#### **herb_items** - 재고 관리 단위 +```sql +CREATE TABLE herb_items ( + herb_item_id INTEGER PRIMARY KEY, + insurance_code VARCHAR(20), -- 보험코드 (9자리) + herb_name VARCHAR(100), + ingredient_code VARCHAR(10) -- 일부만 보유 (28/31) +) +-- 역할: 우리가 실제 보유한 약재 목록 +-- 현황: 총 31개 약재 보유 +``` + +#### **inventory_lots** - 로트별 재고 +```sql +CREATE TABLE inventory_lots ( + lot_id INTEGER PRIMARY KEY, + herb_item_id INTEGER, -- FK to herb_items + quantity_onhand REAL, -- 현재 재고량(g) + unit_price_per_g REAL, -- g당 단가 + origin_country TEXT, -- 원산지 + expiry_date DATE -- 유효기간 +) +-- 역할: 실제 재고 수량 관리 +-- 특징: FIFO 소비, 로트별 추적 +``` + +### 2.3 효능 관리 (Efficacy System) + +#### **herb_efficacy_tags** - 효능 태그 마스터 +```sql +CREATE TABLE herb_efficacy_tags ( + tag_id INTEGER PRIMARY KEY, + tag_name VARCHAR(50) UNIQUE, -- "보혈", "활혈", "청열" + tag_category VARCHAR(30), -- "보익", "거사", "조리" + description TEXT +) +-- 역할: 18개 표준 효능 태그 정의 +``` + +#### **herb_item_tags** - 약재-태그 매핑 ⭐ 개선됨! +```sql +CREATE TABLE herb_item_tags ( + item_tag_id INTEGER PRIMARY KEY, + ingredient_code VARCHAR(10), -- 성분코드 직접 사용! (개선) + tag_id INTEGER, + strength INTEGER DEFAULT 3, -- 효능 강도 (1-5) + UNIQUE(ingredient_code, tag_id) +) +-- 이전: herb_id 사용 (복잡한 JOIN 필요) +-- 현재: ingredient_code 직접 사용 (간단!) +``` + +### 2.4 처방 및 조제 (Prescriptions & Compounding) + +#### **formulas** - 처방 마스터 +```sql +CREATE TABLE formulas ( + formula_id INTEGER PRIMARY KEY, + formula_name VARCHAR(100), -- "십전대보탕" + formula_name_hanja VARCHAR(100), -- "十全大補湯" + je_count INTEGER -- 기준 제수 +) +``` + +#### **formula_ingredients** - 처방 구성 +```sql +CREATE TABLE formula_ingredients ( + formula_id INTEGER, + ingredient_code VARCHAR(10), -- 성분코드 사용 + grams_per_cheop REAL -- 첩당 용량 +) +``` + +#### **compounds** - 조제 기록 +```sql +CREATE TABLE compounds ( + compound_id INTEGER PRIMARY KEY, + patient_id INTEGER, + formula_id INTEGER, + is_custom BOOLEAN, -- 가감방 여부 + custom_details TEXT, -- 가감 내용 + total_cost REAL, + compound_date DATETIME +) +``` + +#### **compound_consumptions** - 소비 내역 +```sql +CREATE TABLE compound_consumptions ( + compound_id INTEGER, + herb_item_id INTEGER, + lot_id INTEGER, + quantity_used REAL, -- 사용량(g) + unit_cost_per_g REAL, + cost_amount REAL +) +-- 특징: 복합 로트 지원 (한 약재에 여러 로트 사용 가능) +``` + +## 🔄 3. 데이터 흐름 + +### 3.1 입고 프로세스 +``` +1. Excel 업로드 (한의사랑 카탈로그) + ↓ +2. herb_products 매칭 (보험코드 기준) + ↓ +3. purchase_receipts 생성 (입고 헤더) + ↓ +4. purchase_receipt_lines 생성 (입고 상세) + ↓ +5. inventory_lots 생성 (로트별 재고) + ↓ +6. stock_ledger 기록 (재고 원장) +``` + +### 3.2 조제 프로세스 +``` +1. 처방 선택 (formulas) + ↓ +2. 구성 약재 로드 (formula_ingredients) + ↓ +3. 재고 매핑 (herb_items + inventory_lots) + ↓ +4. 가감 여부 확인 (원방 vs 현재 구성 비교) + ↓ +5. 로트 선택 (자동 FIFO 또는 수동 배분) + ↓ +6. compounds 생성 (조제 기록) + ↓ +7. compound_consumptions 생성 (소비 내역) + ↓ +8. inventory_lots 차감 (재고 감소) + ↓ +9. stock_ledger 기록 (원장 업데이트) +``` + +### 3.3 효능 태그 조회 (개선된 JOIN) + +#### Before (복잡했던 구조): +```sql +-- 5단계 JOIN 필요 +FROM herb_items h +LEFT JOIN herb_products hp ON h.insurance_code = hp.product_code +LEFT JOIN herb_masters hm ON hp.ingredient_code = hm.ingredient_code +LEFT JOIN herb_master_extended hme ON hm.ingredient_code = hme.ingredient_code +LEFT JOIN herb_item_tags hit ON hme.herb_id = hit.herb_id -- herb_id 찾기 +LEFT JOIN herb_efficacy_tags het ON hit.tag_id = het.tag_id +``` + +#### After (개선된 구조): +```sql +-- 3단계 JOIN으로 단순화! +FROM herb_items h +LEFT JOIN herb_products hp ON h.insurance_code = hp.product_code +LEFT JOIN herb_item_tags hit ON COALESCE(h.ingredient_code, hp.ingredient_code) = hit.ingredient_code +LEFT JOIN herb_efficacy_tags het ON hit.tag_id = het.tag_id +``` + +## 🎯 4. 핵심 매핑 관계 + +### 4.1 코드 체계 매핑 +``` +보험코드(9자리) → 성분코드(10자리) +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +062400740 → 3007H1AHM (감초) +062403450 → 3105H1AHM (당귀) +A001300 → 3400H1AHM (인삼) + +* herb_products 테이블이 중개 역할 +``` + +### 4.2 재고 관계 +``` +herb_items (31개) + ↓ 1:N +inventory_lots (여러 로트) + ↓ 1:N +compound_consumptions (소비 기록) +``` + +### 4.3 처방 관계 +``` +formulas (처방) + ↓ 1:N +formula_ingredients (구성 약재) + ↓ ingredient_code +herb_masters (약재 마스터) +``` + +## 📈 5. 주요 통계 쿼리 + +### 5.1 재고 현황 요약 +```sql +-- 주성분코드 기준 보유율 +SELECT + COUNT(DISTINCT m.ingredient_code) as 전체_약재, + COUNT(DISTINCT CASE WHEN inv.total > 0 THEN m.ingredient_code END) as 보유_약재, + ROUND(COUNT(DISTINCT CASE WHEN inv.total > 0 THEN m.ingredient_code END) * 100.0 / + COUNT(DISTINCT m.ingredient_code), 1) as 보유율 +FROM herb_masters m +LEFT JOIN (재고 서브쿼리) inv ON m.ingredient_code = inv.ingredient_code +``` + +### 5.2 효능별 약재 검색 +```sql +-- 간단해진 쿼리! +SELECT DISTINCT h.*, GROUP_CONCAT(et.tag_name) +FROM herb_items h +LEFT JOIN herb_products hp ON h.insurance_code = hp.product_code +LEFT JOIN herb_item_tags hit ON COALESCE(h.ingredient_code, hp.ingredient_code) = hit.ingredient_code +LEFT JOIN herb_efficacy_tags et ON hit.tag_id = et.tag_id +WHERE et.tag_name IN ('보혈', '활혈') +GROUP BY h.herb_item_id +``` + +## 🚀 6. 최근 개선사항 (2026-02-17) + +### 6.1 효능 태그 시스템 리팩토링 +- **문제**: `herb_id`를 통한 복잡한 JOIN +- **해결**: `ingredient_code` 직접 사용 +- **효과**: JOIN 단계 5개 → 3개로 감소 + +### 6.2 가감방 감지 시스템 +- **구현**: 실시간 처방 변경 감지 +- **방식**: `ingredient_code` 기준 비교 +- **UI**: 가감방 배지 자동 표시 + +### 6.3 복합 로트 시스템 +- **기능**: 한 약재에 여러 로트 사용 가능 +- **UI**: 수동 로트 배분 모달 +- **검증**: 재고량 실시간 체크 + +## 📝 7. 주의사항 + +### 7.1 ID 체계 혼동 주의 +``` +⚠️ herb_item_id ≠ herb_id +- herb_item_id: herb_items의 PK (재고 관리) +- herb_id: herb_master_extended의 PK (단순 인덱스) +- 실제 KEY: ingredient_code (성분코드) +``` + +### 7.2 코드 매핑 순서 +``` +1. 보험코드로 입력받음 (9자리) +2. herb_products에서 ingredient_code 찾기 +3. ingredient_code로 모든 정보 연결 +``` + +### 7.3 재고 없는 약재 처리 +``` +- herb_items에 없어도 herb_masters에는 존재 +- 효능 정보는 ingredient_code 기준 +- UI에서 재고 0으로 표시 +``` + +## 🔧 8. 개발 가이드 + +### 8.1 새 약재 추가 시 +```python +# 1. herb_masters에 성분코드 확인 +# 2. herb_products에 보험코드 매핑 추가 +# 3. herb_items에 재고 단위 생성 +# 4. 입고 처리로 inventory_lots 생성 +``` + +### 8.2 효능 태그 추가 시 +```python +# 간단해진 방식! +INSERT INTO herb_item_tags (ingredient_code, tag_id, strength) +VALUES ('3400H1AHM', 1, 5) -- 인삼에 보기(5) 추가 +``` + +### 8.3 API 개발 시 +```python +# 항상 ingredient_code 중심으로 JOIN +# herb_products 테이블 활용 +# COALESCE로 안전하게 처리 +``` + +## 📚 9. 관련 문서 + +- [조제 프로세스 및 커스텀 처방](./조제_프로세스_및_커스텀_처방.md) +- [복합 로트 사용 분석](./복합_로트_사용_분석.md) +- [한약재 정보 관리 시스템 설계](./한약재_정보_관리_시스템_설계.md) + +--- + +*이 문서는 시스템의 핵심 데이터 구조와 흐름을 설명합니다.* +*질문이나 수정사항은 개발팀에 문의해주세요.* \ No newline at end of file diff --git a/docs/한약재_정보_관리_시스템_설계.md b/docs/한약재_정보_관리_시스템_설계.md index af947c3..d441815 100644 --- a/docs/한약재_정보_관리_시스템_설계.md +++ b/docs/한약재_정보_관리_시스템_설계.md @@ -79,7 +79,7 @@ CREATE TABLE herb_master_extended ( -- 2. 약재 연구 문헌 CREATE TABLE herb_research_papers ( paper_id INTEGER PRIMARY KEY, - herb_id INTEGER REFERENCES herb_master_extended(herb_id), + ingredient_code VARCHAR(10), -- 성분코드 직접 사용 (개선) title TEXT NOT NULL, authors TEXT, @@ -107,7 +107,7 @@ CREATE TABLE herb_research_papers ( -- 3. 약재 안전성 정보 CREATE TABLE herb_safety_info ( safety_id INTEGER PRIMARY KEY, - herb_id INTEGER REFERENCES herb_master_extended(herb_id), + ingredient_code VARCHAR(10), -- 성분코드 직접 사용 (개선) -- 독성 정보 toxicity_level VARCHAR(20), -- 독성 등급 @@ -138,9 +138,9 @@ CREATE TABLE herb_safety_info ( CREATE TABLE prescription_rules ( rule_id INTEGER PRIMARY KEY, - -- 배합 규칙 - herb1_id INTEGER, - herb2_id INTEGER, + -- 배합 규칙 (성분코드 사용으로 개선) + ingredient_code_1 VARCHAR(10), + ingredient_code_2 VARCHAR(10), relationship_type VARCHAR(50), -- 상수/상사/상외/상오/상쇄/상반/상살 description TEXT,