kdrug-inventory-system/docs/조제_프로세스_및_커스텀_처방.md
시골약사 1441c01fb4 feat: 실시간 커스텀 처방(가감방) 감지 시스템 구현
- 프론트엔드: 조제 시 실시간 커스텀 처방 감지
  - 처방 선택 시 원래 구성 약재 저장
  - 약재 추가/삭제/변경 시 즉시 감지
  - 가감방 뱃지 및 변경 내용 표시

- 백엔드: 커스텀 처방 자동 감지 및 저장
  - 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>
2026-02-17 01:28:44 +00:00

9.0 KiB

조제 프로세스 및 커스텀 처방 관리

목차

  1. 조제 프로세스 흐름
  2. 데이터베이스 구조
  3. 커스텀 처방 처리
  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 처방 관련 테이블

-- 처방 마스터 (기본 처방)
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 재고 관련 테이블

-- 재고 로트
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: 비교를 통한 자동 감지

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: 플래그 추가 (권장)

-- 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 데이터베이스 개선

-- 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 개선 제안

@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 개선 제안

조제 화면

// 커스텀 여부 실시간 표시
function checkCustomization() {
    const original = getOriginalFormula();
    const current = getCurrentIngredients();

    if (hasChanges(original, current)) {
        $('#customBadge').show().html('가감방');
        $('#customDetails').html(getChangesSummary());
    }
}

환자 처방 내역 화면

// 커스텀 처방 구분 표시
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. 표시: 차이점을 계산하여 화면에 표시

예시 쿼리

-- 커스텀 처방 찾기
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"을 정확히 기록하고 추적할 수 있습니다.