docs: 데이터베이스 스키마 및 API 문서 추가
- 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>
This commit is contained in:
parent
0bf0772864
commit
116712aa24
13
README.md
13
README.md
@ -53,24 +53,33 @@
|
|||||||
## 데이터베이스 구조
|
## 데이터베이스 구조
|
||||||
|
|
||||||
### 핵심 테이블
|
### 핵심 테이블
|
||||||
|
- `herb_masters` - 약재 마스터 (성분코드 기준, 454개 표준 약재)
|
||||||
|
- `herb_items` - 약재 제품 (제조사별 개별 제품)
|
||||||
- `patients` - 환자 정보
|
- `patients` - 환자 정보
|
||||||
- `herb_items` - 약재 마스터 (보험코드 기준)
|
|
||||||
- `suppliers` - 도매상 정보
|
- `suppliers` - 도매상 정보
|
||||||
- `purchase_receipts` - 입고장 헤더
|
- `purchase_receipts` - 입고장 헤더
|
||||||
- `purchase_receipt_lines` - 입고장 상세
|
- `purchase_receipt_lines` - 입고장 상세
|
||||||
- `inventory_lots` - 로트별 재고
|
- `inventory_lots` - 로트별 재고
|
||||||
- `formulas` - 처방 마스터
|
- `formulas` - 처방 마스터
|
||||||
- `formula_ingredients` - 처방 구성 약재
|
- `formula_ingredients` - 처방 구성 약재 (ingredient_code 기반)
|
||||||
- `compounds` - 조제 작업
|
- `compounds` - 조제 작업
|
||||||
- `compound_consumptions` - 로트별 차감 내역
|
- `compound_consumptions` - 로트별 차감 내역
|
||||||
- `stock_ledger` - 재고 원장 (모든 변동 기록)
|
- `stock_ledger` - 재고 원장 (모든 변동 기록)
|
||||||
|
|
||||||
### 핵심 개념
|
### 핵심 개념
|
||||||
|
- **성분코드 (ingredient_code)**: 표준 약재 식별자
|
||||||
|
- **2단계 약재 체계**: 마스터(성분) → 제품(제조사별)
|
||||||
- **1제 = 20첩 = 30파우치** (기본값, 조정 가능)
|
- **1제 = 20첩 = 30파우치** (기본값, 조정 가능)
|
||||||
- **로트 관리**: 입고 시점별로 재고를 구분 관리
|
- **로트 관리**: 입고 시점별로 재고를 구분 관리
|
||||||
- **FIFO 차감**: 오래된 재고부터 우선 사용
|
- **FIFO 차감**: 오래된 재고부터 우선 사용
|
||||||
- **원가 추적**: 로트별 단가 기준 정확한 원가 계산
|
- **원가 추적**: 로트별 단가 기준 정확한 원가 계산
|
||||||
|
|
||||||
|
## 📚 문서
|
||||||
|
|
||||||
|
- [데이터베이스 스키마](docs/database_schema.md) - 전체 테이블 구조 상세 설명
|
||||||
|
- [ER 다이어그램](docs/database_erd.md) - 엔티티 관계도 및 데이터 플로우
|
||||||
|
- [API 문서](docs/api_documentation.md) - REST API 엔드포인트 상세 명세
|
||||||
|
|
||||||
## 설치 방법
|
## 설치 방법
|
||||||
|
|
||||||
### 1. 필수 요구사항
|
### 1. 필수 요구사항
|
||||||
|
|||||||
553
docs/api_documentation.md
Normal file
553
docs/api_documentation.md
Normal file
@ -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`: 서버 오류
|
||||||
252
docs/database_erd.md
Normal file
252
docs/database_erd.md
Normal file
@ -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` 자동 설정
|
||||||
398
docs/database_schema.md
Normal file
398
docs/database_schema.md
Normal file
@ -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개 기본 효능 태그
|
||||||
|
- 약재별 효능 분류 체계
|
||||||
Loading…
Reference in New Issue
Block a user