- 프론트엔드: 조제 시 실시간 커스텀 처방 감지 - 처방 선택 시 원래 구성 약재 저장 - 약재 추가/삭제/변경 시 즉시 감지 - 가감방 뱃지 및 변경 내용 표시 - 백엔드: 커스텀 처방 자동 감지 및 저장 - compounds 테이블에 커스텀 관련 필드 추가 - 조제 시 원 처방과 비교하여 변경사항 자동 감지 - 커스텀 처방 정보 저장 (추가/제거/변경된 약재) - 환자 조제 내역에 커스텀 처방 표시 - 가감방 뱃지 표시 - 변경 내용 상세 표시 - DB 마이그레이션 스크립트 추가 - is_custom, custom_summary, custom_type 필드 추가 - compound_ingredients에 modification_type, original_grams 필드 추가 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
310 lines
9.0 KiB
Markdown
310 lines
9.0 KiB
Markdown
# 조제 프로세스 및 커스텀 처방 관리
|
|
|
|
## 목차
|
|
1. [조제 프로세스 흐름](#1-조제-프로세스-흐름)
|
|
2. [데이터베이스 구조](#2-데이터베이스-구조)
|
|
3. [커스텀 처방 처리](#3-커스텀-처방-처리)
|
|
4. [구현 제안사항](#4-구현-제안사항)
|
|
|
|
---
|
|
|
|
## 1. 조제 프로세스 흐름
|
|
|
|
### 1.1 전체 흐름도
|
|
```
|
|
[처방 선택] → [구성 약재 자동 로드] → [약재 커스터마이징] → [재고 확인] → [조제 실행] → [기록 저장]
|
|
↓ ↓ ↓ ↓ ↓ ↓
|
|
십전대보탕 formula_ingredients 약재 추가/삭제/수정 inventory_lots 재고 차감 compounds
|
|
확인 stock_ledger compound_ingredients
|
|
```
|
|
|
|
### 1.2 단계별 상세 프로세스
|
|
|
|
#### Step 1: 처방 선택
|
|
- **테이블**: `formulas`
|
|
- **주요 필드**:
|
|
- `formula_id`: 처방 ID
|
|
- `formula_name`: 처방명 (예: "십전대보탕")
|
|
- `base_cheop_per_je`: 1제당 기본 첩수 (보통 20첩)
|
|
|
|
#### Step 2: 구성 약재 자동 로드
|
|
- **테이블**: `formula_ingredients`
|
|
- **동작**: 선택한 처방의 기본 구성 약재를 자동으로 불러옴
|
|
- **예시**: 십전대보탕 선택 시 인삼, 백출, 복령, 감초 등 10가지 약재 자동 로드
|
|
|
|
#### Step 3: 약재 커스터마이징
|
|
- **가능한 작업**:
|
|
- ✅ 약재 추가 (예: 구기자 3g 추가)
|
|
- ✅ 약재 삭제 (특정 약재 제외)
|
|
- ✅ 용량 수정 (기본 5g → 7g으로 변경)
|
|
|
|
#### Step 4: 재고 확인 및 선택
|
|
- **테이블**: `inventory_lots`
|
|
- **display_name 표시**: 각 약재의 정확한 variant 확인
|
|
- 예: "건강" → "건강.土[한국산]" vs "건강[페루산]"
|
|
- **원산지 선택**: 자동(FIFO) 또는 수동 선택
|
|
|
|
#### Step 5: 조제 실행 및 재고 차감
|
|
- **FIFO 방식**: 오래된 로트부터 우선 소비
|
|
- **재고 부족 체크**: 부족 시 경고 표시
|
|
- **로트별 차감**: `compound_consumptions`에 상세 기록
|
|
|
|
#### Step 6: 조제 기록 저장
|
|
- **compounds 테이블**: 조제 마스터 정보
|
|
- **compound_ingredients 테이블**: 실제 사용된 약재 구성
|
|
- **compound_consumptions 테이블**: 로트별 차감 내역
|
|
|
|
---
|
|
|
|
## 2. 데이터베이스 구조
|
|
|
|
### 2.1 처방 관련 테이블
|
|
|
|
```sql
|
|
-- 처방 마스터 (기본 처방)
|
|
formulas
|
|
├── formula_id (PK)
|
|
├── formula_name -- "십전대보탕"
|
|
└── base_cheop_per_je -- 20첩
|
|
|
|
-- 처방 기본 구성
|
|
formula_ingredients
|
|
├── formula_id (FK)
|
|
├── herb_item_id (FK)
|
|
└── grams_per_cheop -- 1첩당 용량
|
|
|
|
-- 실제 조제 기록
|
|
compounds
|
|
├── compound_id (PK)
|
|
├── patient_id (FK) -- 환자
|
|
├── formula_id (FK) -- 원 처방 참조
|
|
├── compound_date -- 조제일
|
|
├── cheop_total -- 총 첩수
|
|
└── notes -- "구기자 3g 추가" 등 커스텀 내역
|
|
|
|
-- 실제 사용 약재 (커스텀 포함)
|
|
compound_ingredients
|
|
├── compound_id (FK)
|
|
├── herb_item_id (FK)
|
|
└── grams_per_cheop -- 실제 사용 용량
|
|
```
|
|
|
|
### 2.2 재고 관련 테이블
|
|
|
|
```sql
|
|
-- 재고 로트
|
|
inventory_lots
|
|
├── lot_id (PK)
|
|
├── herb_item_id (FK)
|
|
├── display_name -- "갈근.각", "건강.土" 등
|
|
├── quantity_onhand -- 현재 재고량
|
|
└── unit_price_per_g -- g당 단가
|
|
|
|
-- 로트 변형 정보
|
|
lot_variants
|
|
├── lot_id (FK)
|
|
├── raw_name -- 상세 제품명
|
|
├── form -- 형태 (각, 片, 土)
|
|
├── processing -- 가공법 (9증, 酒炙)
|
|
└── grade -- 등급 (特, 中, 小)
|
|
```
|
|
|
|
---
|
|
|
|
## 3. 커스텀 처방 처리
|
|
|
|
### 3.1 현재 시스템의 처리 방식
|
|
|
|
현재 시스템은 이미 커스텀 처방을 처리할 수 있는 구조를 가지고 있습니다:
|
|
|
|
1. **formula_ingredients**: 처방의 기본 구성 (변경되지 않음)
|
|
2. **compound_ingredients**: 실제 조제 시 사용된 구성 (커스텀 반영)
|
|
|
|
### 3.2 커스텀 처방 식별 방법
|
|
|
|
#### 방법 1: 비교를 통한 자동 감지
|
|
```python
|
|
def is_custom_prescription(compound_id):
|
|
"""조제가 원 처방과 다른지 확인"""
|
|
|
|
# 1. compound의 formula_id 확인
|
|
original_formula = get_formula_ingredients(formula_id)
|
|
|
|
# 2. 실제 사용된 약재 확인
|
|
actual_ingredients = get_compound_ingredients(compound_id)
|
|
|
|
# 3. 비교
|
|
if original_formula != actual_ingredients:
|
|
return True, get_differences()
|
|
|
|
return False, None
|
|
```
|
|
|
|
#### 방법 2: 플래그 추가 (권장)
|
|
```sql
|
|
-- compounds 테이블에 컬럼 추가
|
|
ALTER TABLE compounds ADD COLUMN is_custom BOOLEAN DEFAULT 0;
|
|
ALTER TABLE compounds ADD COLUMN custom_notes TEXT;
|
|
```
|
|
|
|
### 3.3 화면 표시 제안
|
|
|
|
#### 조제 내역 표시 예시
|
|
|
|
**원 처방 그대로 조제한 경우:**
|
|
```
|
|
조제일: 2024-02-17
|
|
처방: 십전대보탕
|
|
첩수: 20첩
|
|
```
|
|
|
|
**커스텀 조제한 경우:**
|
|
```
|
|
조제일: 2024-02-17
|
|
처방: 십전대보탕 (가감방) ⚠️
|
|
첩수: 20첩
|
|
추가: 구기자 3g
|
|
제외: 감초
|
|
변경: 인삼 5g → 7g
|
|
```
|
|
|
|
---
|
|
|
|
## 4. 구현 제안사항
|
|
|
|
### 4.1 데이터베이스 개선
|
|
|
|
```sql
|
|
-- 1. compounds 테이블에 커스텀 플래그 추가
|
|
ALTER TABLE compounds ADD COLUMN is_custom BOOLEAN DEFAULT 0;
|
|
ALTER TABLE compounds ADD COLUMN custom_type TEXT; -- 'added', 'removed', 'modified', 'mixed'
|
|
ALTER TABLE compounds ADD COLUMN custom_summary TEXT; -- "구기자 3g 추가"
|
|
|
|
-- 2. compound_ingredients에 변경 타입 추가
|
|
ALTER TABLE compound_ingredients ADD COLUMN modification_type TEXT; -- 'original', 'added', 'modified'
|
|
ALTER TABLE compound_ingredients ADD COLUMN original_grams REAL; -- 원래 용량 (수정된 경우)
|
|
```
|
|
|
|
### 4.2 API 개선 제안
|
|
|
|
```python
|
|
@app.route('/api/compounds', methods=['POST'])
|
|
def create_compound():
|
|
"""조제 실행 - 커스텀 처방 감지 포함"""
|
|
|
|
data = request.json
|
|
formula_id = data.get('formula_id')
|
|
ingredients = data.get('ingredients')
|
|
|
|
# 원 처방과 비교
|
|
original = get_formula_ingredients(formula_id)
|
|
is_custom, differences = compare_ingredients(original, ingredients)
|
|
|
|
if is_custom:
|
|
# 커스텀 정보 저장
|
|
custom_summary = generate_custom_summary(differences)
|
|
# compounds 테이블에 is_custom=1, custom_summary 저장
|
|
```
|
|
|
|
### 4.3 UI 개선 제안
|
|
|
|
#### 조제 화면
|
|
```javascript
|
|
// 커스텀 여부 실시간 표시
|
|
function checkCustomization() {
|
|
const original = getOriginalFormula();
|
|
const current = getCurrentIngredients();
|
|
|
|
if (hasChanges(original, current)) {
|
|
$('#customBadge').show().html('가감방');
|
|
$('#customDetails').html(getChangesSummary());
|
|
}
|
|
}
|
|
```
|
|
|
|
#### 환자 처방 내역 화면
|
|
```javascript
|
|
// 커스텀 처방 구분 표시
|
|
function displayPrescriptionHistory(patient_id) {
|
|
// 처방 내역 표시 시
|
|
if (compound.is_custom) {
|
|
html += `<span class="badge bg-warning">가감</span>`;
|
|
html += `<small class="text-muted">${compound.custom_summary}</small>`;
|
|
}
|
|
}
|
|
```
|
|
|
|
### 4.4 보고서 개선
|
|
|
|
환자 처방 내역서에 커스텀 정보 포함:
|
|
```
|
|
===========================================
|
|
환자명: 홍길동
|
|
기간: 2024-01-01 ~ 2024-02-17
|
|
===========================================
|
|
|
|
1. 2024-01-15: 십전대보탕 (20첩)
|
|
- 표준 처방
|
|
|
|
2. 2024-02-01: 십전대보탕 가감방 (20첩)
|
|
- 추가: 구기자 3g/첩
|
|
- 제외: 감초
|
|
- 용량변경: 인삼 5g → 7g/첩
|
|
|
|
3. 2024-02-17: 쌍화탕 (15첩)
|
|
- 표준 처방
|
|
```
|
|
|
|
---
|
|
|
|
## 5. 현재 시스템 활용 방안
|
|
|
|
현재 구조에서도 충분히 커스텀 처방을 관리할 수 있습니다:
|
|
|
|
1. **조제 시**: `compound_ingredients`에 실제 사용 약재 저장
|
|
2. **조회 시**: `formula_ingredients`와 비교하여 커스텀 여부 판단
|
|
3. **표시**: 차이점을 계산하여 화면에 표시
|
|
|
|
### 예시 쿼리
|
|
|
|
```sql
|
|
-- 커스텀 처방 찾기
|
|
SELECT
|
|
c.compound_id,
|
|
c.formula_id,
|
|
f.formula_name,
|
|
CASE
|
|
WHEN ci_count != fi_count THEN '가감방'
|
|
ELSE '표준방'
|
|
END as prescription_type
|
|
FROM compounds c
|
|
JOIN formulas f ON c.formula_id = f.formula_id
|
|
JOIN (
|
|
-- 실제 사용 약재 수
|
|
SELECT compound_id, COUNT(*) as ci_count
|
|
FROM compound_ingredients
|
|
GROUP BY compound_id
|
|
) ci ON c.compound_id = ci.compound_id
|
|
LEFT JOIN (
|
|
-- 원 처방 약재 수
|
|
SELECT formula_id, COUNT(*) as fi_count
|
|
FROM formula_ingredients
|
|
GROUP BY formula_id
|
|
) fi ON c.formula_id = fi.formula_id;
|
|
```
|
|
|
|
---
|
|
|
|
## 6. 결론
|
|
|
|
현재 시스템은 이미 커스텀 처방을 저장할 수 있는 구조를 갖추고 있습니다:
|
|
- `formula_ingredients`: 원 처방 (불변)
|
|
- `compound_ingredients`: 실제 조제 (커스텀 가능)
|
|
|
|
추가 개선사항:
|
|
1. `compounds` 테이블에 `is_custom` 플래그 추가
|
|
2. 커스텀 내역을 요약하여 `custom_summary`에 저장
|
|
3. UI에서 가감방 표시 및 상세 내역 표시
|
|
4. 환자 처방 내역에 커스텀 정보 포함
|
|
|
|
이렇게 하면 "십전대보탕 + 구기자 3g"을 정확히 기록하고 추적할 수 있습니다. |