From 116712aa247a64274d804ab3652d29ae22cdeaa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=9C=EA=B3=A8=EC=95=BD=EC=82=AC?= Date: Sun, 15 Feb 2026 19:07:34 +0000 Subject: [PATCH] =?UTF-8?q?docs:=20=EB=8D=B0=EC=9D=B4=ED=84=B0=EB=B2=A0?= =?UTF-8?q?=EC=9D=B4=EC=8A=A4=20=EC=8A=A4=ED=82=A4=EB=A7=88=20=EB=B0=8F=20?= =?UTF-8?q?API=20=EB=AC=B8=EC=84=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - database_schema.md: 전체 테이블 구조 상세 설명 - 27개 테이블의 컬럼 정의 및 설명 - 테이블 간 관계 설명 - 주요 비즈니스 규칙 문서화 - database_erd.md: ER 다이어그램 및 데이터 플로우 - Mermaid 다이어그램으로 시각화 - 재고 흐름도, 처방-조제 흐름 설명 - 인덱스 전략 및 데이터 무결성 규칙 - api_documentation.md: REST API 상세 명세 - 약재, 처방, 조제, 재고, 환자 관리 API - 요청/응답 형식 예시 - 에러 처리 방식 - README 업데이트: 문서 링크 추가 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- README.md | 13 +- docs/api_documentation.md | 553 ++++++++++++++++++++++++++++++++++++++ docs/database_erd.md | 252 +++++++++++++++++ docs/database_schema.md | 398 +++++++++++++++++++++++++++ 4 files changed, 1214 insertions(+), 2 deletions(-) create mode 100644 docs/api_documentation.md create mode 100644 docs/database_erd.md create mode 100644 docs/database_schema.md diff --git a/README.md b/README.md index 08cf156..5701673 100644 --- a/README.md +++ b/README.md @@ -53,24 +53,33 @@ ## 데이터베이스 구조 ### 핵심 테이블 +- `herb_masters` - 약재 마스터 (성분코드 기준, 454개 표준 약재) +- `herb_items` - 약재 제품 (제조사별 개별 제품) - `patients` - 환자 정보 -- `herb_items` - 약재 마스터 (보험코드 기준) - `suppliers` - 도매상 정보 - `purchase_receipts` - 입고장 헤더 - `purchase_receipt_lines` - 입고장 상세 - `inventory_lots` - 로트별 재고 - `formulas` - 처방 마스터 -- `formula_ingredients` - 처방 구성 약재 +- `formula_ingredients` - 처방 구성 약재 (ingredient_code 기반) - `compounds` - 조제 작업 - `compound_consumptions` - 로트별 차감 내역 - `stock_ledger` - 재고 원장 (모든 변동 기록) ### 핵심 개념 +- **성분코드 (ingredient_code)**: 표준 약재 식별자 +- **2단계 약재 체계**: 마스터(성분) → 제품(제조사별) - **1제 = 20첩 = 30파우치** (기본값, 조정 가능) - **로트 관리**: 입고 시점별로 재고를 구분 관리 - **FIFO 차감**: 오래된 재고부터 우선 사용 - **원가 추적**: 로트별 단가 기준 정확한 원가 계산 +## 📚 문서 + +- [데이터베이스 스키마](docs/database_schema.md) - 전체 테이블 구조 상세 설명 +- [ER 다이어그램](docs/database_erd.md) - 엔티티 관계도 및 데이터 플로우 +- [API 문서](docs/api_documentation.md) - REST API 엔드포인트 상세 명세 + ## 설치 방법 ### 1. 필수 요구사항 diff --git a/docs/api_documentation.md b/docs/api_documentation.md new file mode 100644 index 0000000..5ded31d --- /dev/null +++ b/docs/api_documentation.md @@ -0,0 +1,553 @@ +# 한의원 약재 관리 시스템 API 문서 + +## 목차 +1. [약재 관리 API](#약재-관리-api) +2. [처방 관리 API](#처방-관리-api) +3. [조제 관리 API](#조제-관리-api) +4. [재고 관리 API](#재고-관리-api) +5. [환자 관리 API](#환자-관리-api) +6. [구매/입고 API](#구매입고-api) +7. [재고 조정 API](#재고-조정-api) + +## 약재 관리 API + +### GET /api/herbs +약재 제품 목록 조회 + +**Response:** +```json +{ + "success": true, + "data": [ + { + "herb_item_id": 1, + "insurance_code": "A001300", + "herb_name": "인삼", + "stock_quantity": 1500.0, + "efficacy_tags": ["보기", "생진"] + } + ] +} +``` + +### GET /api/herbs/masters +마스터 약재 목록 조회 (454개 표준 약재) + +**Response:** +```json +{ + "success": true, + "data": [ + { + "ingredient_code": "3400H1AHM", + "herb_name": "인삼", + "herb_name_hanja": "人蔘", + "herb_name_latin": "Ginseng Radix", + "stock_quantity": 7000.0, + "has_stock": 1, + "lot_count": 3, + "product_count": 2, + "company_count": 2, + "efficacy_tags": ["보기", "생진"] + } + ] +} +``` + +### GET /api/herbs/by-ingredient/{ingredient_code} +특정 성분코드의 제품 목록 조회 + +**Parameters:** +- `ingredient_code`: 성분코드 (예: 3400H1AHM) + +**Response:** +```json +{ + "success": true, + "data": [ + { + "herb_item_id": 38, + "insurance_code": "060600420", + "herb_name": "인삼", + "product_name": "신흥인삼", + "company_name": "신흥", + "specification": "(주)신흥제약", + "stock_quantity": 7000.0, + "lot_count": 2, + "avg_price": 17.5 + } + ] +} +``` + +### GET /api/herbs/{herb_item_id}/available-lots +조제용 가용 로트 목록 (원산지별 그룹화) + +**Parameters:** +- `herb_item_id`: 제품 ID + +**Response:** +```json +{ + "success": true, + "data": { + "herb_name": "인삼", + "insurance_code": "060600420", + "origins": [ + { + "origin_country": "한국", + "total_quantity": 3000.0, + "min_price": 20.0, + "max_price": 25.0, + "lot_count": 2, + "lots": [ + { + "lot_id": 1, + "quantity_onhand": 1500.0, + "unit_price_per_g": 20.0, + "received_date": "2024-01-15" + } + ] + } + ], + "total_quantity": 7000.0 + } +} +``` + +## 처방 관리 API + +### GET /api/formulas +처방 목록 조회 + +**Response:** +```json +{ + "success": true, + "data": [ + { + "formula_id": 1, + "formula_code": "F001", + "formula_name": "쌍화탕", + "formula_type": "탕제", + "base_cheop": 20, + "base_pouches": 60 + } + ] +} +``` + +### POST /api/formulas +처방 등록 + +**Request Body:** +```json +{ + "formula_code": "F002", + "formula_name": "십전대보탕", + "formula_type": "탕제", + "base_cheop": 20, + "base_pouches": 60, + "description": "기혈 보충", + "ingredients": [ + { + "ingredient_code": "3400H1AHM", + "grams_per_cheop": 6.0, + "notes": "" + } + ] +} +``` + +### GET /api/formulas/{formula_id}/ingredients +처방 구성 약재 조회 (ingredient_code 기반) + +**Response:** +```json +{ + "success": true, + "data": [ + { + "ingredient_code": "3400H1AHM", + "herb_name": "인삼", + "grams_per_cheop": 6.0, + "total_available_stock": 7000.0, + "available_products": [ + { + "herb_item_id": 38, + "herb_name": "신흥인삼", + "specification": "(주)신흥제약", + "stock": 7000.0 + } + ] + } + ] +} +``` + +## 조제 관리 API + +### POST /api/compounds +조제 실행 + +**Request Body:** +```json +{ + "patient_id": 1, + "formula_id": 1, + "je_count": 1, + "cheop_total": 20, + "pouch_total": 60, + "ingredients": [ + { + "herb_item_id": 38, + "grams_per_cheop": 6.0, + "origin": "auto" + } + ] +} +``` + +**Response:** +```json +{ + "success": true, + "compound_id": 123, + "message": "조제가 완료되었습니다", + "summary": { + "total_cost": 15000, + "consumptions": [ + { + "herb_name": "인삼", + "total_used": 120.0, + "lots_used": [ + { + "lot_id": 1, + "origin": "한국", + "quantity": 120.0, + "unit_price": 20.0 + } + ] + } + ] + } +} +``` + +### GET /api/compounds/recent +최근 조제 내역 + +**Query Parameters:** +- `limit`: 조회 건수 (기본값: 10) +- `patient_id`: 환자 ID (선택) + +**Response:** +```json +{ + "success": true, + "data": [ + { + "compound_id": 123, + "compound_date": "2024-01-20", + "patient_name": "홍길동", + "formula_name": "쌍화탕", + "cheop_total": 20, + "pouch_total": 60, + "cost_total": 15000, + "status": "completed" + } + ] +} +``` + +## 재고 관리 API + +### GET /api/inventory/summary +재고 현황 요약 + +**Response:** +```json +{ + "success": true, + "data": { + "total_items": 87, + "items_with_stock": 75, + "total_value": 2500000, + "by_origin": { + "한국": { + "item_count": 30, + "total_quantity": 15000, + "total_value": 1200000 + }, + "중국": { + "item_count": 45, + "total_quantity": 25000, + "total_value": 1300000 + } + } + } +} +``` + +### GET /api/inventory/low-stock +재고 부족 약재 조회 + +**Query Parameters:** +- `threshold`: 재고 기준량 (기본값: 100g) + +**Response:** +```json +{ + "success": true, + "data": [ + { + "herb_item_id": 5, + "herb_name": "당귀", + "current_stock": 50.0, + "threshold": 100.0, + "last_purchase_date": "2024-01-01" + } + ] +} +``` + +### GET /api/stock-ledger +재고 원장 조회 + +**Query Parameters:** +- `herb_item_id`: 제품 ID (선택) +- `start_date`: 시작일 (선택) +- `end_date`: 종료일 (선택) +- `event_type`: IN/OUT/ADJUST (선택) + +**Response:** +```json +{ + "success": true, + "data": [ + { + "ledger_id": 1, + "event_time": "2024-01-20 14:30:00", + "event_type": "OUT", + "herb_name": "인삼", + "lot_id": 1, + "quantity_delta": -120.0, + "reference_table": "compound_consumptions", + "reference_id": 456 + } + ] +} +``` + +## 환자 관리 API + +### GET /api/patients +환자 목록 조회 + +**Query Parameters:** +- `search`: 검색어 (이름, 전화번호) +- `is_active`: 활성 여부 + +**Response:** +```json +{ + "success": true, + "data": [ + { + "patient_id": 1, + "name": "홍길동", + "phone": "010-1234-5678", + "gender": "M", + "birth_date": "1980-01-01", + "last_visit": "2024-01-20" + } + ] +} +``` + +### POST /api/patients +환자 등록 + +**Request Body:** +```json +{ + "name": "홍길동", + "phone": "010-1234-5678", + "jumin_no": "800101-1******", + "gender": "M", + "birth_date": "1980-01-01", + "address": "서울시 강남구", + "notes": "" +} +``` + +### GET /api/patients/{patient_id}/prescriptions +환자 처방 이력 + +**Response:** +```json +{ + "success": true, + "data": [ + { + "compound_id": 123, + "compound_date": "2024-01-20", + "formula_name": "쌍화탕", + "cheop_total": 20, + "pouch_total": 60, + "cost_total": 15000, + "ingredients": [ + { + "herb_name": "인삼", + "product_name": "신흥인삼", + "grams_per_cheop": 6.0, + "total_grams": 120.0, + "origin_country": "한국" + } + ] + } + ] +} +``` + +## 구매/입고 API + +### POST /api/purchases/upload +거래명세표 업로드 + +**Form Data:** +- `file`: 엑셀 파일 +- `supplier_id`: 공급처 ID + +**Response:** +```json +{ + "success": true, + "receipt_id": 789, + "summary": { + "total_items": 25, + "total_amount": 500000, + "items_processed": 25, + "items_failed": 0 + } +} +``` + +### POST /api/purchases/receipts +구매 영수증 등록 + +**Request Body:** +```json +{ + "supplier_id": 1, + "receipt_date": "2024-01-20", + "receipt_no": "R2024012001", + "vat_included": true, + "vat_rate": 10.0, + "total_amount": 550000, + "lines": [ + { + "herb_item_id": 38, + "origin_country": "한국", + "quantity_g": 1000, + "unit_price_per_g": 20.0, + "line_total": 20000 + } + ] +} +``` + +## 재고 조정 API + +### POST /api/stock-adjustments +재고 보정 + +**Request Body:** +```json +{ + "adjustment_date": "2024-01-20", + "adjustment_type": "correction", + "notes": "실사 보정", + "details": [ + { + "herb_item_id": 38, + "lot_id": 1, + "quantity_after": 1480.0, + "reason": "실사 차이" + } + ] +} +``` + +### GET /api/stock-adjustments +재고 보정 내역 조회 + +**Query Parameters:** +- `start_date`: 시작일 +- `end_date`: 종료일 +- `herb_item_id`: 제품 ID (선택) + +**Response:** +```json +{ + "success": true, + "data": [ + { + "adjustment_id": 1, + "adjustment_date": "2024-01-20", + "adjustment_no": "ADJ20240120001", + "adjustment_type": "correction", + "total_items": 5, + "created_by": "admin" + } + ] +} +``` + +## 통계 API + +### GET /api/stats/herb-usage +약재 사용 통계 + +**Query Parameters:** +- `period`: daily/weekly/monthly +- `start_date`: 시작일 +- `end_date`: 종료일 + +**Response:** +```json +{ + "success": true, + "data": { + "period": "2024-01", + "top_used": [ + { + "herb_name": "인삼", + "total_quantity": 5000.0, + "usage_count": 25, + "total_cost": 100000 + } + ], + "total_compounds": 150, + "total_cost": 3000000 + } +} +``` + +## 에러 응답 + +모든 API는 다음과 같은 에러 응답 형식을 따릅니다: + +```json +{ + "success": false, + "error": "에러 메시지", + "code": "ERROR_CODE" +} +``` + +### HTTP 상태 코드 +- `200 OK`: 성공 +- `400 Bad Request`: 잘못된 요청 +- `404 Not Found`: 리소스를 찾을 수 없음 +- `500 Internal Server Error`: 서버 오류 \ No newline at end of file diff --git a/docs/database_erd.md b/docs/database_erd.md new file mode 100644 index 0000000..adc5eaf --- /dev/null +++ b/docs/database_erd.md @@ -0,0 +1,252 @@ +# 한의원 약재 관리 시스템 ER 다이어그램 + +## 핵심 엔티티 관계도 + +```mermaid +erDiagram + HERB_MASTERS ||--o{ HERB_ITEMS : "has" + HERB_MASTERS ||--o{ FORMULA_INGREDIENTS : "used_in" + HERB_ITEMS ||--o{ INVENTORY_LOTS : "has" + HERB_ITEMS ||--o{ COMPOUND_INGREDIENTS : "used_in" + HERB_ITEMS ||--o{ HERB_ITEM_TAGS : "has" + HERB_EFFICACY_TAGS ||--o{ HERB_ITEM_TAGS : "assigned_to" + + FORMULAS ||--o{ FORMULA_INGREDIENTS : "contains" + FORMULAS ||--o{ COMPOUNDS : "used_for" + + PATIENTS ||--o{ COMPOUNDS : "receives" + PATIENTS ||--o{ PATIENT_SURVEYS : "completes" + + COMPOUNDS ||--o{ COMPOUND_INGREDIENTS : "contains" + COMPOUND_INGREDIENTS ||--o{ COMPOUND_CONSUMPTIONS : "consumes" + + INVENTORY_LOTS ||--o{ COMPOUND_CONSUMPTIONS : "consumed_by" + INVENTORY_LOTS }o--|| SUPPLIERS : "supplied_by" + INVENTORY_LOTS }o--|| PURCHASE_RECEIPT_LINES : "received_from" + + SUPPLIERS ||--o{ PURCHASE_RECEIPTS : "provides" + PURCHASE_RECEIPTS ||--o{ PURCHASE_RECEIPT_LINES : "contains" + + STOCK_ADJUSTMENTS ||--o{ STOCK_ADJUSTMENT_DETAILS : "contains" + STOCK_LEDGER }o--|| HERB_ITEMS : "tracks" + STOCK_LEDGER }o--|| INVENTORY_LOTS : "tracks" + + HERB_MASTERS { + string ingredient_code PK + string herb_name + string herb_name_hanja + string herb_name_latin + text description + boolean is_active + } + + HERB_ITEMS { + int herb_item_id PK + string ingredient_code FK + string insurance_code + string herb_name + string specification + boolean is_active + } + + INVENTORY_LOTS { + int lot_id PK + int herb_item_id FK + int supplier_id FK + date received_date + string origin_country + decimal unit_price_per_g + decimal quantity_onhand + date expiry_date + boolean is_depleted + } + + FORMULAS { + int formula_id PK + string formula_code + string formula_name + string formula_type + int base_cheop + int base_pouches + boolean is_active + } + + FORMULA_INGREDIENTS { + int ingredient_id PK + int formula_id FK + string ingredient_code FK + decimal grams_per_cheop + int sort_order + } + + COMPOUNDS { + int compound_id PK + int patient_id FK + int formula_id FK + date compound_date + decimal cheop_total + decimal pouch_total + decimal cost_total + string status + } + + PATIENTS { + int patient_id PK + string name + string phone + string gender + date birth_date + boolean is_active + } +``` + +## 재고 흐름도 + +```mermaid +flowchart TB + subgraph 입고 + S[공급처/Suppliers] + PR[구매영수증/Purchase Receipts] + PRL[구매영수증라인/Purchase Receipt Lines] + S --> PR + PR --> PRL + end + + subgraph 재고 + HM[약재마스터/Herb Masters] + HI[약재제품/Herb Items] + IL[재고로트/Inventory Lots] + SL[재고원장/Stock Ledger] + + HM --> HI + HI --> IL + PRL --> IL + IL -.-> SL + end + + subgraph 조제/출고 + F[처방/Formulas] + FI[처방구성/Formula Ingredients] + C[조제/Compounds] + CI[조제구성/Compound Ingredients] + CC[조제소비/Compound Consumptions] + + F --> FI + FI -.->|ingredient_code| HM + F --> C + C --> CI + CI --> CC + CC --> IL + end + + subgraph 재고조정 + SA[재고조정/Stock Adjustments] + SAD[조정상세/Adjustment Details] + + SA --> SAD + SAD --> IL + end + + IL --> SL + CC --> SL + SAD --> SL + + classDef master fill:#e1f5fe + classDef transaction fill:#fff3e0 + classDef inventory fill:#f3e5f5 + classDef ledger fill:#e8f5e9 + + class HM,HI,F master + class PR,PRL,C,CI,CC transaction + class IL inventory + class SL,SA,SAD ledger +``` + +## 데이터 플로우 + +### 1. 약재 마스터 데이터 흐름 +``` +herb_masters (성분코드) + ↓ +herb_items (제품별 재고 단위) + ↓ +inventory_lots (로트별 실재고) +``` + +### 2. 처방 → 조제 흐름 +``` +formulas (처방 마스터) + ↓ +formula_ingredients (ingredient_code 기반) + ↓ +compounds (실제 조제) + ↓ +compound_ingredients (제품 선택) + ↓ +compound_consumptions (로트별 소비) +``` + +### 3. 구매 → 재고 흐름 +``` +suppliers (공급처) + ↓ +purchase_receipts (영수증) + ↓ +purchase_receipt_lines (라인) + ↓ +inventory_lots (재고 생성) + ↓ +stock_ledger (원장 기록) +``` + +## 주요 비즈니스 규칙 + +### 재고 관리 +1. **FIFO (선입선출)**: 오래된 로트부터 자동 소비 +2. **로트 추적**: 모든 재고는 lot_id로 추적 +3. **원산지 관리**: 로트별 origin_country 관리 +4. **가격 추적**: 로트별 unit_price_per_g 관리 + +### 처방 관리 +1. **성분코드 기반**: formula_ingredients는 ingredient_code 사용 +2. **유연한 제품 선택**: 동일 성분의 다른 제품 선택 가능 +3. **2단계 선택**: 약재(마스터) → 제품 → 로트 + +### 조제 관리 +1. **처방 조제**: 등록된 처방 사용 +2. **직접 조제**: 처방 없이 직접 구성 +3. **가감 가능**: 처방 기본 구성에서 추가/제거 가능 + +### 원가 계산 +``` +조제 원가 = Σ(사용량 × 로트별 단가) +``` + +## 인덱스 전략 + +### 주요 인덱스 +- `herb_items.ingredient_code`: 성분코드 조회 +- `inventory_lots.herb_item_id, is_depleted`: 가용 재고 조회 +- `inventory_lots.origin_country`: 원산지별 재고 조회 +- `formula_ingredients.formula_id`: 처방 구성 조회 +- `compounds.patient_id, compound_date`: 환자 조제 이력 +- `stock_ledger.herb_item_id, event_time`: 재고 변동 이력 + +## 데이터 무결성 + +### 외래키 제약 +- `herb_items.ingredient_code` → `herb_masters.ingredient_code` +- `formula_ingredients.ingredient_code` → `herb_masters.ingredient_code` +- `inventory_lots.herb_item_id` → `herb_items.herb_item_id` +- `compound_ingredients.herb_item_id` → `herb_items.herb_item_id` +- `compound_consumptions.lot_id` → `inventory_lots.lot_id` + +### 체크 제약 +- `inventory_lots.quantity_onhand >= 0` +- `compound_consumptions.quantity_used > 0` +- `purchase_receipt_lines.quantity_g > 0` +- `formula_ingredients.grams_per_cheop > 0` + +### 트리거 +- 재고 변동 시 `stock_ledger` 자동 기록 +- `inventory_lots.quantity_onhand = 0` 시 `is_depleted = 1` 자동 설정 \ No newline at end of file diff --git a/docs/database_schema.md b/docs/database_schema.md new file mode 100644 index 0000000..d787c11 --- /dev/null +++ b/docs/database_schema.md @@ -0,0 +1,398 @@ +# 한의원 약재 관리 시스템 데이터베이스 스키마 + +## 목차 +1. [핵심 마스터 테이블](#핵심-마스터-테이블) +2. [재고 관리 테이블](#재고-관리-테이블) +3. [조제 관리 테이블](#조제-관리-테이블) +4. [구매/입고 관리 테이블](#구매입고-관리-테이블) +5. [환자 관리 테이블](#환자-관리-테이블) +6. [재고 조정 테이블](#재고-조정-테이블) +7. [설문 관리 테이블](#설문-관리-테이블) + +## 핵심 마스터 테이블 + +### herb_masters (약재 마스터) +통합 약재 마스터 정보. 성분코드(ingredient_code) 기준 관리. + +| 컬럼명 | 타입 | 설명 | +|--------|------|------| +| ingredient_code | VARCHAR(10) PK | 성분코드 (예: 3400H1AHM) | +| herb_name | VARCHAR(100) | 한글명 (예: 인삼) | +| herb_name_hanja | VARCHAR(100) | 한자명 (예: 人蔘) | +| herb_name_latin | VARCHAR(200) | 라틴명 | +| description | TEXT | 설명 | +| is_active | BOOLEAN | 사용 여부 | +| created_at | TIMESTAMP | 생성일시 | +| updated_at | TIMESTAMP | 수정일시 | + +### herb_items (약재 제품) +실제 재고 관리 단위. 제조사별 개별 제품. + +| 컬럼명 | 타입 | 설명 | +|--------|------|------| +| herb_item_id | INTEGER PK | 제품 ID | +| ingredient_code | VARCHAR(10) FK | 성분코드 (herb_masters 참조) | +| insurance_code | TEXT | 보험코드 | +| herb_name | TEXT | 제품명 (예: 신흥인삼) | +| specification | TEXT | 규격/제조사 (예: (주)신흥제약) | +| default_unit | TEXT | 기본 단위 | +| is_active | INTEGER | 사용 여부 | +| created_at | DATETIME | 생성일시 | +| updated_at | DATETIME | 수정일시 | + +### herb_products (표준 약재 제품 목록) +건강보험 표준 약재 제품 목록. + +| 컬럼명 | 타입 | 설명 | +|--------|------|------| +| product_id | INTEGER PK | 제품 ID | +| ingredient_code | VARCHAR(10) FK | 성분코드 | +| product_code | VARCHAR(9) | 제품코드 | +| company_name | VARCHAR(200) | 제조사명 | +| product_name | VARCHAR(200) | 제품명 | +| standard_code | VARCHAR(20) | 표준코드 | +| representative_code | VARCHAR(20) | 대표코드 | +| package_size | VARCHAR(20) | 포장 크기 | +| package_unit | VARCHAR(20) | 포장 단위 | +| valid_from | DATE | 유효 시작일 | +| valid_to | DATE | 유효 종료일 | +| is_active | BOOLEAN | 사용 여부 | + +### formulas (처방 마스터) +등록된 처방 정보. + +| 컬럼명 | 타입 | 설명 | +|--------|------|------| +| formula_id | INTEGER PK | 처방 ID | +| formula_code | TEXT | 처방코드 | +| formula_name | TEXT | 처방명 (예: 쌍화탕) | +| formula_type | TEXT | 처방 유형 | +| base_cheop | INTEGER | 기본 첩수 | +| base_pouches | INTEGER | 기본 포수 | +| description | TEXT | 설명 | +| is_active | INTEGER | 사용 여부 | +| created_by | TEXT | 생성자 | +| created_at | DATETIME | 생성일시 | +| updated_at | DATETIME | 수정일시 | + +### formula_ingredients (처방 구성) +처방별 구성 약재. **ingredient_code 기반**. + +| 컬럼명 | 타입 | 설명 | +|--------|------|------| +| ingredient_id | INTEGER PK | 구성 ID | +| formula_id | INTEGER FK | 처방 ID | +| ingredient_code | TEXT | 성분코드 (herb_masters 참조) | +| grams_per_cheop | REAL | 1첩당 용량(g) | +| notes | TEXT | 비고 | +| sort_order | INTEGER | 정렬 순서 | +| created_at | DATETIME | 생성일시 | + +## 재고 관리 테이블 + +### inventory_lots (재고 로트) +로트별 재고 관리. + +| 컬럼명 | 타입 | 설명 | +|--------|------|------| +| lot_id | INTEGER PK | 로트 ID | +| herb_item_id | INTEGER FK | 제품 ID | +| supplier_id | INTEGER FK | 공급처 ID | +| receipt_line_id | INTEGER FK | 입고 라인 ID | +| received_date | DATE | 입고일 | +| origin_country | TEXT | 원산지 (예: 중국, 한국) | +| unit_price_per_g | REAL | g당 단가 | +| quantity_received | REAL | 입고량(g) | +| quantity_onhand | REAL | 현재고량(g) | +| expiry_date | DATE | 유효기간 | +| lot_number | TEXT | 로트번호 | +| is_depleted | INTEGER | 소진 여부 | +| created_at | DATETIME | 생성일시 | +| updated_at | DATETIME | 수정일시 | + +### stock_ledger (재고 원장) +모든 재고 변동 이력 관리. + +| 컬럼명 | 타입 | 설명 | +|--------|------|------| +| ledger_id | INTEGER PK | 원장 ID | +| event_time | DATETIME | 이벤트 시간 | +| event_type | TEXT | 이벤트 유형 (IN/OUT/ADJUST) | +| herb_item_id | INTEGER FK | 제품 ID | +| lot_id | INTEGER FK | 로트 ID | +| quantity_delta | REAL | 수량 변동 (+/-) | +| unit_cost_per_g | REAL | g당 단가 | +| reference_table | TEXT | 참조 테이블명 | +| reference_id | INTEGER | 참조 ID | +| notes | TEXT | 비고 | +| created_by | TEXT | 생성자 | +| created_at | DATETIME | 생성일시 | + +## 조제 관리 테이블 + +### compounds (조제 내역) +환자별 조제 내역. + +| 컬럼명 | 타입 | 설명 | +|--------|------|------| +| compound_id | INTEGER PK | 조제 ID | +| patient_id | INTEGER FK | 환자 ID | +| formula_id | INTEGER FK | 처방 ID (NULL 가능 - 직접조제) | +| compound_date | DATE | 조제일 | +| je_count | REAL | 제수 | +| cheop_total | REAL | 총 첩수 | +| pouch_total | REAL | 총 포수 | +| cost_total | REAL | 원가 합계 | +| sell_price_total | REAL | 판매가 합계 | +| prescription_no | TEXT | 처방전 번호 | +| status | TEXT | 상태 | +| notes | TEXT | 비고 | +| created_by | TEXT | 생성자 | +| created_at | DATETIME | 생성일시 | +| updated_at | DATETIME | 수정일시 | + +### compound_ingredients (조제 구성 약재) +조제별 사용 약재 구성. + +| 컬럼명 | 타입 | 설명 | +|--------|------|------| +| compound_ingredient_id | INTEGER PK | 구성 ID | +| compound_id | INTEGER FK | 조제 ID | +| herb_item_id | INTEGER FK | 제품 ID | +| grams_per_cheop | REAL | 1첩당 용량(g) | +| total_grams | REAL | 총 용량(g) | +| notes | TEXT | 비고 | +| created_at | DATETIME | 생성일시 | + +### compound_consumptions (조제 소비 내역) +조제 시 실제 소비한 재고 로트별 내역. + +| 컬럼명 | 타입 | 설명 | +|--------|------|------| +| consumption_id | INTEGER PK | 소비 ID | +| compound_id | INTEGER FK | 조제 ID | +| herb_item_id | INTEGER FK | 제품 ID | +| lot_id | INTEGER FK | 로트 ID | +| quantity_used | REAL | 사용량(g) | +| unit_cost_per_g | REAL | g당 단가 | +| cost_amount | REAL | 원가 금액 | +| created_at | DATETIME | 생성일시 | + +## 구매/입고 관리 테이블 + +### suppliers (공급처) +약재 공급처 정보. + +| 컬럼명 | 타입 | 설명 | +|--------|------|------| +| supplier_id | INTEGER PK | 공급처 ID | +| name | TEXT | 공급처명 | +| business_no | TEXT | 사업자번호 | +| contact_person | TEXT | 담당자 | +| phone | TEXT | 전화번호 | +| address | TEXT | 주소 | +| is_active | INTEGER | 사용 여부 | +| created_at | DATETIME | 생성일시 | +| updated_at | DATETIME | 수정일시 | + +### purchase_receipts (구매 영수증) +구매/입고 영수증 헤더. + +| 컬럼명 | 타입 | 설명 | +|--------|------|------| +| receipt_id | INTEGER PK | 영수증 ID | +| supplier_id | INTEGER FK | 공급처 ID | +| receipt_date | DATE | 거래일 | +| receipt_no | TEXT | 영수증 번호 | +| vat_included | INTEGER | VAT 포함 여부 | +| vat_rate | REAL | VAT 비율 | +| total_amount | REAL | 총 금액 | +| source_file | TEXT | 원본 파일 | +| notes | TEXT | 비고 | +| created_at | DATETIME | 생성일시 | +| updated_at | DATETIME | 수정일시 | + +### purchase_receipt_lines (구매 영수증 라인) +구매/입고 영수증 상세 라인. + +| 컬럼명 | 타입 | 설명 | +|--------|------|------| +| line_id | INTEGER PK | 라인 ID | +| receipt_id | INTEGER FK | 영수증 ID | +| herb_item_id | INTEGER FK | 제품 ID | +| origin_country | TEXT | 원산지 | +| quantity_g | REAL | 수량(g) | +| unit_price_per_g | REAL | g당 단가 | +| line_total | REAL | 라인 합계 | +| expiry_date | DATE | 유효기간 | +| lot_number | TEXT | 로트번호 | +| created_at | DATETIME | 생성일시 | + +## 환자 관리 테이블 + +### patients (환자) +환자 기본 정보. + +| 컬럼명 | 타입 | 설명 | +|--------|------|------| +| patient_id | INTEGER PK | 환자 ID | +| name | TEXT | 환자명 | +| phone | TEXT | 전화번호 | +| jumin_no | TEXT | 주민번호 | +| gender | TEXT | 성별 | +| birth_date | DATE | 생년월일 | +| address | TEXT | 주소 | +| notes | TEXT | 비고 | +| is_active | INTEGER | 사용 여부 | +| created_at | DATETIME | 생성일시 | +| updated_at | DATETIME | 수정일시 | + +## 재고 조정 테이블 + +### stock_adjustments (재고 조정) +재고 보정 헤더. + +| 컬럼명 | 타입 | 설명 | +|--------|------|------| +| adjustment_id | INTEGER PK | 조정 ID | +| adjustment_date | DATE | 조정일 | +| adjustment_no | TEXT | 조정 번호 | +| adjustment_type | TEXT | 조정 유형 | +| notes | TEXT | 비고 | +| created_by | TEXT | 생성자 | +| created_at | DATETIME | 생성일시 | +| updated_at | DATETIME | 수정일시 | + +### stock_adjustment_details (재고 조정 상세) +재고 보정 상세 내역. + +| 컬럼명 | 타입 | 설명 | +|--------|------|------| +| detail_id | INTEGER PK | 상세 ID | +| adjustment_id | INTEGER FK | 조정 ID | +| herb_item_id | INTEGER FK | 제품 ID | +| lot_id | INTEGER FK | 로트 ID | +| quantity_before | REAL | 조정 전 수량 | +| quantity_after | REAL | 조정 후 수량 | +| quantity_delta | REAL | 조정량 | +| reason | TEXT | 사유 | +| created_at | DATETIME | 생성일시 | + +## 효능 태그 테이블 + +### herb_efficacy_tags (효능 태그) +약재 효능 마스터. + +| 컬럼명 | 타입 | 설명 | +|--------|------|------| +| tag_id | INTEGER PK | 태그 ID | +| tag_name | VARCHAR(50) | 태그명 (예: 보혈, 활혈) | +| tag_category | VARCHAR(50) | 카테고리 | +| description | TEXT | 설명 | +| created_at | TIMESTAMP | 생성일시 | + +### herb_item_tags (약재-태그 연결) +약재와 효능 태그 다대다 관계. + +| 컬럼명 | 타입 | 설명 | +|--------|------|------| +| herb_item_id | INTEGER FK | 제품 ID | +| tag_id | INTEGER FK | 태그 ID | + +## 설문 관리 테이블 + +### survey_templates (설문 템플릿) +설문 질문 템플릿. + +| 컬럼명 | 타입 | 설명 | +|--------|------|------| +| template_id | INTEGER PK | 템플릿 ID | +| category | TEXT | 카테고리 | +| category_name | TEXT | 카테고리명 | +| question_code | TEXT | 질문 코드 | +| question_text | TEXT | 질문 내용 | +| question_subtext | TEXT | 보조 설명 | +| input_type | TEXT | 입력 타입 | +| options | TEXT | 선택 옵션 | +| is_required | INTEGER | 필수 여부 | +| sort_order | INTEGER | 정렬 순서 | +| is_active | INTEGER | 사용 여부 | +| created_at | DATETIME | 생성일시 | + +### patient_surveys (환자 설문) +환자별 설문 내역. + +| 컬럼명 | 타입 | 설명 | +|--------|------|------| +| survey_id | INTEGER PK | 설문 ID | +| patient_id | INTEGER FK | 환자 ID | +| survey_token | TEXT | 설문 토큰 | +| survey_date | DATE | 설문일 | +| status | TEXT | 상태 | +| created_at | DATETIME | 생성일시 | +| completed_at | DATETIME | 완료일시 | +| reviewed_at | DATETIME | 검토일시 | +| reviewed_by | TEXT | 검토자 | +| notes | TEXT | 비고 | + +### survey_responses (설문 응답) +설문 응답 내역. + +| 컬럼명 | 타입 | 설명 | +|--------|------|------| +| response_id | INTEGER PK | 응답 ID | +| survey_id | INTEGER FK | 설문 ID | +| category | TEXT | 카테고리 | +| question_code | TEXT | 질문 코드 | +| question_text | TEXT | 질문 내용 | +| answer_value | TEXT | 응답 값 | +| answer_type | TEXT | 응답 타입 | +| created_at | DATETIME | 생성일시 | +| updated_at | DATETIME | 수정일시 | + +### survey_progress (설문 진행 상태) +설문 카테고리별 진행 상태. + +| 컬럼명 | 타입 | 설명 | +|--------|------|------| +| progress_id | INTEGER PK | 진행 ID | +| survey_id | INTEGER FK | 설문 ID | +| category | TEXT | 카테고리 | +| total_questions | INTEGER | 전체 질문 수 | +| answered_questions | INTEGER | 응답 질문 수 | +| is_completed | INTEGER | 완료 여부 | +| last_updated | DATETIME | 최종 수정일시 | + +## 주요 관계 + +1. **약재 계층 구조** + - `herb_masters` (마스터) ← `herb_items` (제품) ← `inventory_lots` (로트) + - ingredient_code로 연결 + +2. **처방-조제 관계** + - `formulas` → `formula_ingredients` (ingredient_code 기반) + - `compounds` → `compound_ingredients` → `compound_consumptions` + +3. **재고 추적** + - 입고: `purchase_receipts` → `purchase_receipt_lines` → `inventory_lots` + - 출고: `compound_consumptions` → `inventory_lots` + - 이력: 모든 변동은 `stock_ledger`에 기록 + +4. **가격 정책** + - FIFO (선입선출) 기준 + - lot별 unit_price_per_g 관리 + +## 마이그레이션 이력 + +### 2024년 주요 변경사항 +1. `formula_ingredients` 테이블: `herb_item_id` → `ingredient_code` 변경 + - 특정 제품이 아닌 성분코드 기준 처방 구성 + - 조제 시 동일 성분의 다른 제품 선택 가능 + +2. `herb_masters` 테이블 추가 + - 454개 표준 약재 마스터 데이터 + - ingredient_code 기준 통합 관리 + +3. `herb_efficacy_tags` 시스템 추가 + - 18개 기본 효능 태그 + - 약재별 효능 분류 체계 \ No newline at end of file