- 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 <noreply@anthropic.com>
252 lines
6.4 KiB
Markdown
252 lines
6.4 KiB
Markdown
# 한의원 약재 관리 시스템 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` 자동 설정 |