kdrug-inventory-system/docs/제품 3단계분류.md
시골약사 69be63d00d docs: 제품 3단계분류 문서 추가, DB 초기화/복원 스크립트
- 제품 3단계분류.md: 성분→제품→로트 분류 체계, AI display_name 채우기 절차
- reset_operational_data.py: 마스터 보존 + 운영 데이터 초기화
- restore_backup.py: 백업 선택 복원 스크립트

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 14:42:31 +00:00

7.0 KiB

제품 3단계 분류 체계

한약재는 성분 → 제품 → 로트 3단계로 식별된다. 같은 성분코드의 약재도 제조사, 형태, 산지, 등급에 따라 품질과 가격이 크게 다르다.


1. 3단계 구조

[1단계] 성분 (herb_masters)         — 약재의 본질
   └─ ingredient_code: 3002H1AHM   = "갈근"
       │
[2단계] 제품 (herb_items)           — 도매상별 상품
   └─ insurance_code: 062401050     = "휴먼갈근" (주식회사휴먼허브)
       │
[3단계] 로트 (inventory_lots)       — 입고 건별 실물
   └─ lot_id: 190                   = "갈근.각" (한국산, ₩17/g)

테이블 매핑

단계 테이블 PK 식별키 행수 예시
성분 herb_masters herb_id ingredient_code 454 갈근 (3002H1AHM)
제품 herb_items herb_item_id insurance_code ~30 휴먼갈근 (062401050)
로트 inventory_lots lot_id receipt_line_id ~30 갈근.각 (한국, ₩17)

herb_items 컬럼 역할

컬럼 실제 내용 예시
herb_name 제품명 (품명) "휴먼갈근"
insurance_code 보험코드 (=product_code) "062401050"
ingredient_code 성분코드 (herb_masters FK) "3002H1AHM"
specification 제조사명 "주식회사휴먼허브"

2. 로트 세부 분류 (display_name + lot_variants)

2-1. inventory_lots.display_name

엑셀 입고 시 NULL로 들어감. AI가 쇼핑몰/카탈로그 정보를 참고하여 사후에 채워넣는 값.

도매상 카탈로그의 실제 품명으로, 같은 제품(herb_items)이라도 로트마다 다를 수 있다:

herb_name (제품) display_name (로트) 차이점
휴먼건강 건강 페루산, ₩12/g
휴먼건강 건강.土 한국산(토종), ₩51/g
휴먼일당귀 일당귀(한국산) 한국산, ₩19/g
휴먼일당귀 일당귀.中(1kg) 중국산 중품, ₩13/g

2-2. lot_variants 테이블 (파싱 결과)

display_name을 구조화된 필드로 파싱한 결과를 저장:

컬럼 용도 파싱 예시
raw_name 원본 품명 "건강.土"
form 형태 각(角), 片(편), 절편, 통
processing 포제/가공 초(炒), 자(炙), 酒炙, 9증
selection_state 선별/원산 土(토종), 正, 中, 재배, 야생
grade 등급 1호, 특, 名品, 소(小)
age_years 연근 4, 6 (년근)

3. display_name 명명 패턴 (도매상 기준)

기본 구조

약재명.형태[등급](포장단위)
약재명.선별<유통경로>(포장단위)[비고]

실제 패턴 분석 (30개 로트)

display_name 약재 form processing selection grade
갈근.각 갈근 각(角) - - -
감초.1호[야생](1kg) 감초 - - 야생 1호
건강 건강 - - - -
건강.土 건강 - - 土(토종) -
길경.片[특] 길경 片(편) - -
세신.中 세신 - - 中(중품) -
백출.당[1kg] 백출 - - 당(當) -
작약주자.土[酒炙] 작약주자 - 酒炙 土(토종) -
숙지황(9증)(신흥.1kg)[완] 숙지황 - 9증 -
육계.YB 육계 - - YB -
진피.비열[非熱](1kg) 진피 - 非熱(비열) - -
창출[북창술.재배](1kg) 창출 - - 재배 -
천궁.일<토매지>(1kg) 천궁 - - 일(日) -
황기(직절.小)(1kg) 황기 직절 - -
용안육.名品(1kg) 용안육 - - - 名品
오미자<토매지>(1kg) 오미자 - - - -
전호[재배] 전호 - - 재배 -
지황.건[회](1kg) 지황 - 건(乾) 회(灰) -

구분자 규칙

구분자 의미 예시
. 주 속성 구분 건강.土 → 토종
[...] 부가 정보/등급 길경.片[특] → 특등
(...) 포장/가공/산지 대추(절편)(1kg)
<...> 유통경로 오미자<토매지>(1kg)

4. AI가 display_name / lot_variants를 채우는 절차

언제 실행하는가

  1. 엑셀 입고 완료 후 (inventory_lots.display_name = NULL)
  2. 도매상 쇼핑몰에서 해당 품목 정보를 AI에게 제공
  3. AI가 정보를 파싱하여 display_name + lot_variants 업데이트

Step 1: NULL인 로트 확인

SELECT il.lot_id, h.herb_name, h.insurance_code, il.origin_country,
       il.unit_price_per_g, il.quantity_received
FROM inventory_lots il
JOIN herb_items h ON il.herb_item_id = h.herb_item_id
WHERE il.display_name IS NULL AND il.is_depleted = 0;

Step 2: 쇼핑몰/카탈로그 정보 참고

사용자가 도매상 쇼핑몰에서 해당 제품의 상세 품명을 제공하면, AI가 가격, 단가, 원산지, 포장단위 등을 교차 참고하여 올바른 로트에 매칭.

참고 가능한 매칭 단서:

  • 보험코드 (insurance_code) — 제품 특정
  • 원산지 (origin_country) — 같은 제품의 로트 구분
  • 단가 (unit_price_per_g) — 등급/선별 구분 (土 > 일반, 한국산 > 중국산)
  • 수량 (quantity_received) — 포장 단위 매칭

Step 3: display_name 업데이트

UPDATE inventory_lots
SET display_name = '건강.土'
WHERE lot_id = 193;

Step 4: lot_variants 파싱 결과 저장

INSERT INTO lot_variants (lot_id, raw_name, form, processing, selection_state, grade, parsed_method)
VALUES (193, '건강.土', NULL, NULL, '土', NULL, 'ai_parsing');

Step 5: 검증

SELECT il.lot_id, il.display_name, h.herb_name, il.origin_country,
       lv.form, lv.processing, lv.selection_state, lv.grade
FROM inventory_lots il
JOIN herb_items h ON il.herb_item_id = h.herb_item_id
LEFT JOIN lot_variants lv ON il.lot_id = lv.lot_id
WHERE il.lot_id = 193;

5. 활용처

화면 사용 값 표시 예시
입고장 상세 display_name 갈근.각, 건강.土
재고 상세 모달 display_name + origin_country 건강.土 (한국)
조제 시 로트 선택 display_name + unit_price 건강.土 ₩51/g vs 건강 ₩12/g
재고 원장 display_name 입출고 이력에 로트 구분

6. 주의사항

  1. 엑셀 입고 로직은 수정하지 않는다display_name은 항상 NULL로 입고
  2. AI가 사후에 채운다 — 쇼핑몰 정보 기반, parsed_method = 'ai_parsing'
  3. 같은 herb_item_id에 여러 display_name 가능 — 로트마다 다른 실물이므로 정상
  4. lot_variants 파싱이 안 되어도 display_name만으로 구분 가능 — 파싱은 선택적

이 문서는 kdrug 시스템의 약재 3단계 분류 체계와 AI 기반 로트 분류 절차를 정의합니다. 최종 수정: 2026-02-18