310 lines
9.4 KiB
Markdown
310 lines
9.4 KiB
Markdown
# 데이터베이스 구조 (2025-06-30 정리)
|
|
|
|
## 개요
|
|
|
|
양구청춘약국 시스템은 3개의 데이터베이스를 사용합니다:
|
|
|
|
| DB | 용도 | 위치 |
|
|
|----|------|------|
|
|
| **MSSQL (PM_DRUG)** | POS 제품/재고/판매 | localhost (팜IT3000) |
|
|
| **MSSQL (PM_PRES)** | 처방전/조제 | localhost (팜IT3000) |
|
|
| **PostgreSQL** | 동물약 상세 정보 (RAG) | 192.168.0.87:5432 |
|
|
| **SQLite** | 마일리지 시스템 | backend/db/mileage.db |
|
|
|
|
---
|
|
|
|
## MSSQL 테이블 구조 (PM_DRUG)
|
|
|
|
### 핵심 테이블 관계
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ CD_GOODS (제품 마스터) - 178,182개 │
|
|
│ └── DrugCode (PK): LB000003157 │
|
|
│ │ │
|
|
│ ┌─────────┴─────────────┬──────────────────────────┐ │
|
|
│ ▼ ▼ ▼ │
|
|
│ CD_SALEGOODS CD_ITEM_UNIT_MEMBER CD_BARCODE│
|
|
│ (대표 바코드) (바코드 N개) ★ (인체용) │
|
|
│ 3,053개 N:1 관계 306,565개│
|
|
└─────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
### CD_GOODS (제품 마스터)
|
|
|
|
팜IT3000 전체 제품 DB. 약국이 개별 등록한 제품은 `LB`, `S`로 시작.
|
|
|
|
| 컬럼 | 타입 | 설명 |
|
|
|------|------|------|
|
|
| DrugCode | nvarchar | PK. `LB000003157` (약국등록), `050000010` (표준) |
|
|
| GoodsName | nvarchar | 제품명 |
|
|
| Saleprice | decimal | 판매가 |
|
|
| BARCODE | nvarchar | (보통 비어있음 - CD_SALEGOODS 사용) |
|
|
| POS_BOON | nvarchar | 분류코드. `010103` = 동물약 |
|
|
| GoodsSelCode | nvarchar | `B` = 판매용 |
|
|
|
|
### CD_SALEGOODS (판매용 제품)
|
|
|
|
약국에서 실제 판매하는 제품. **대표 바코드 1개** 저장.
|
|
|
|
| 컬럼 | 타입 | 설명 |
|
|
|------|------|------|
|
|
| DrugCode | nvarchar | FK → CD_GOODS |
|
|
| GoodsName | nvarchar | 제품명 |
|
|
| BARCODE | nvarchar | **대표 바코드** (자체생성: `999000000xxxx`) |
|
|
| SplCode | nvarchar | 공급처 코드 |
|
|
| SplName | nvarchar | 공급처명 |
|
|
|
|
### CD_ITEM_UNIT_MEMBER (바코드 N개) ★
|
|
|
|
**한 제품에 여러 바코드** 저장. APC 코드는 여기에 저장됨!
|
|
|
|
| 컬럼 | 타입 | 설명 |
|
|
|------|------|------|
|
|
| DRUGCODE | nvarchar | FK → CD_GOODS.DrugCode |
|
|
| CD_CD_BARCODE | nvarchar | **바코드** (APC: `0230237810109`) |
|
|
| CD_CD_UNIT | nvarchar | 단위코드 (13, 015 등) |
|
|
| CD_MY_UNIT | decimal | 판매가 |
|
|
| CD_IN_UNIT | decimal | 입고가 |
|
|
| CHANGE_DATE | nvarchar | 변경일 (YYYYMMDD) |
|
|
| SN | bigint | 일련번호 |
|
|
|
|
### CD_BARCODE (인체용 표준)
|
|
|
|
식약처 인체용 의약품 표준 바코드. **동물약은 없음!**
|
|
|
|
| 컬럼 | 타입 | 설명 |
|
|
|------|------|------|
|
|
| DRUGCODE | nvarchar | 제품코드 |
|
|
| BARCODE | nvarchar | 표준 바코드 |
|
|
| BASECODE | nvarchar | 표준코드 |
|
|
| ETCNAME | nvarchar | 제품명 |
|
|
| CL_GUBUN | nvarchar | 구분 (전문의약품 등) |
|
|
|
|
---
|
|
|
|
## PostgreSQL 구조 (apdb_master)
|
|
|
|
동물약품 상세 정보. 농림축산검역본부 데이터 + LLM 가공.
|
|
|
|
### apc 테이블 (핵심)
|
|
|
|
| 컬럼 | 타입 | 설명 |
|
|
|------|------|------|
|
|
| apc | varchar | **PK**. `0230237810109` |
|
|
| product_name | varchar | 제품명 |
|
|
| company_name | varchar | 제조사 |
|
|
| main_ingredient | varchar | 주성분 |
|
|
| efficacy_effect | text | 효능/효과 (HTML) |
|
|
| dosage_instructions | text | 용법/용량 (HTML) |
|
|
| precautions | text | 주의사항 (HTML) |
|
|
| **llm_pharm** | jsonb | **LLM 가공 정보** ★ |
|
|
| image_url1 | varchar | 앞면 이미지 |
|
|
| image_url2 | varchar | 뒷면 이미지 |
|
|
| weight_min_kg | float | 최소 체중 |
|
|
| weight_max_kg | float | 최대 체중 |
|
|
|
|
### llm_pharm JSON 구조 (핵심!)
|
|
|
|
```json
|
|
{
|
|
"사용가능 동물": "개, 고양이",
|
|
"분류": "내부구충제",
|
|
"성분1": "메벤다졸",
|
|
"성분2": "프라지콴텔",
|
|
"체중/부위": "체중 5~9kg: 1정, 10~19kg: 2정...",
|
|
"기간/용법": "1일 1회, 1~2일간 경구투여",
|
|
"월령금기": "생후 1주 미만 사용 금지",
|
|
"반려인주의": "사람이 복용 시 즉시 의사의 조치 필요",
|
|
"앞이미지": "https://...",
|
|
"뒤이미지": "https://..."
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 바코드 체계
|
|
|
|
| 패턴 | 설명 | 예시 |
|
|
|------|------|------|
|
|
| `023xxxxxxxx` | **APC (동물약 표준)** | `0230237810109` |
|
|
| `999000000xxxx` | 약국 자체 생성 | `9990000001134` |
|
|
| `880xxxxxxxxx` | 일반 GS1 바코드 | `8809989000009` |
|
|
|
|
---
|
|
|
|
## 연결 예시
|
|
|
|
**안텔민킹(5kg이상) 조회:**
|
|
|
|
```sql
|
|
-- MSSQL: 바코드 조회
|
|
SELECT CD_CD_BARCODE
|
|
FROM CD_ITEM_UNIT_MEMBER
|
|
WHERE DRUGCODE = 'LB000003157'
|
|
AND CD_CD_BARCODE LIKE '023%';
|
|
-- → 0230237810109
|
|
|
|
-- PostgreSQL: 상세 정보 조회
|
|
SELECT llm_pharm->>'사용가능 동물', efficacy_effect
|
|
FROM apc
|
|
WHERE apc = '0230237810109';
|
|
-- → 개, 고양이
|
|
```
|
|
|
|
---
|
|
|
|
## 이미지 URL 규칙
|
|
|
|
```
|
|
https://ani.0bin.in/img/{APC}_F.jpg # 앞면
|
|
https://ani.0bin.in/img/{APC}_B.jpg # 뒷면
|
|
https://ani.0bin.in/img/{APC}_D.jpg # 상세
|
|
```
|
|
|
|
예: `https://ani.0bin.in/img/0230237810109_F.jpg`
|
|
|
|
---
|
|
|
|
## APC 매핑 현황 (2025-06-30)
|
|
|
|
### 매핑 완료 (8개)
|
|
|
|
| 제품 | APC | 이미지 | 비고 |
|
|
|------|-----|--------|------|
|
|
| 안텔민킹(5kg이상) | 0230237810109 | ✅ | |
|
|
| 안텔민뽀삐(5kg이하) | 0230237010107 | ✅ | |
|
|
| (판)복합개시딘 | 0231093520106 | ✅ | |
|
|
| 파라캅L(5kg이상) | 0230338510101 | ✅ | |
|
|
| 파라캅S(5kg이하) | 0230347110106 | ✅ | |
|
|
| 세레니아정16mg | 0231884610109 | ✅ | |
|
|
| 세레니아정24mg | 0231884620107 | ✅ | |
|
|
| 제스타제(10정) | 8809720800455 | ❌ | 바코드=APC |
|
|
|
|
### 바코드=APC 케이스
|
|
|
|
PostgreSQL에서 일부 제품은 APC 대신 **바코드**로 등록됨:
|
|
|
|
```
|
|
제스타제:
|
|
- 약국 바코드: 8809720800455
|
|
- PostgreSQL apc: 8809720800455 (동일!)
|
|
- RAG 데이터 있음 ✅
|
|
- 이미지 URL: ❌ (023으로 시작 안 함)
|
|
```
|
|
|
|
**시스템 처리 로직:**
|
|
1. CD_ITEM_UNIT_MEMBER에서 `023%` APC 검색
|
|
2. 없으면 기존 바코드를 APC로 사용
|
|
3. PostgreSQL에서 해당 코드로 RAG 조회
|
|
|
|
### 매핑 대기 (주요 펫팜 공급)
|
|
|
|
| 제품 | 상태 |
|
|
|------|------|
|
|
| 가드닐 L/M/S | PostgreSQL 용량별 APC 없음 |
|
|
| 다이로하트정 M/S/SS | 매칭 필요 |
|
|
| 리펠로 M/S | 부모 APC만 있음 |
|
|
| 셀라이트액 L/M/S/SS/XL | 매칭 필요 |
|
|
| 캐치원 SS/S/M/L/캣 | PostgreSQL에 없음 |
|
|
| 하트세이버 L/M/mini/S | 매칭 필요 |
|
|
| 하트웜솔루션 M/S | 매칭 필요 |
|
|
|
|
---
|
|
|
|
## 재고 시스템 (2025-06-30)
|
|
|
|
### 이중 재고 구조
|
|
|
|
| 위치 | 테이블 | 용도 | 조회 방식 |
|
|
|------|--------|------|-----------|
|
|
| **MSSQL (PM_DRUG)** | `IM_total` | 약국 재고 | `IM_QT_sale_debit` |
|
|
| **PostgreSQL** | `inventory` | 도매상 재고 | `SUM(quantity)` |
|
|
|
|
### 약국 재고 (MSSQL)
|
|
|
|
```sql
|
|
-- IM_total 테이블
|
|
SELECT DrugCode, IM_QT_sale_debit as stock
|
|
FROM IM_total
|
|
WHERE DrugCode = 'LB000003157';
|
|
-- → 8 (현재 약국 보유 수량)
|
|
```
|
|
|
|
### 도매상 재고 (PostgreSQL)
|
|
|
|
도매상 재고는 **입출고 이력**으로 관리됩니다.
|
|
|
|
```sql
|
|
-- inventory 테이블 (입출고 이력)
|
|
-- quantity: +입고(INBOUND), -출고(OUTBOUND)
|
|
|
|
SELECT A.apc, A.product_name, SUM(I.quantity) as wholesaler_stock
|
|
FROM inventory I
|
|
JOIN apc A ON I.apdb_id = A.idx
|
|
WHERE A.for_pets = true
|
|
GROUP BY A.apc, A.product_name
|
|
HAVING SUM(I.quantity) > 0;
|
|
|
|
-- 안텔민뽀삐: 38개
|
|
-- 복합개시딘: 6개
|
|
-- 세레니아16mg: 4개
|
|
```
|
|
|
|
### inventory 테이블 주요 컬럼
|
|
|
|
| 컬럼 | 타입 | 설명 |
|
|
|------|------|------|
|
|
| apdb_id | integer | apc.idx FK |
|
|
| quantity | integer | 수량 (+입고/-출고) |
|
|
| transaction_type | varchar | INBOUND/OUTBOUND |
|
|
| transaction_date | timestamp | 거래일시 |
|
|
| wholesaler_price | numeric | 도매가 |
|
|
| retail_price | numeric | 소매가 |
|
|
| expiration_date | date | 유효기간 |
|
|
|
|
### API 응답 예시
|
|
|
|
```json
|
|
{
|
|
"name": "안텔민뽀삐(5kg이하)",
|
|
"price": 5000,
|
|
"stock": 8, // 약국 재고
|
|
"wholesaler_stock": 38 // 도매상 재고
|
|
}
|
|
```
|
|
|
|
### 프론트엔드 표시
|
|
|
|
```
|
|
┌────────────────────────────────┐
|
|
│ 💊 안텔민뽀삐(5kg이하) │
|
|
│ ₩5,000 약국 8 / 도매 38 │
|
|
└────────────────────────────────┘
|
|
```
|
|
|
|
- **약국 재고 있음**: 초록색 `약국 8`
|
|
- **약국 품절**: 빨간색 `품절`
|
|
- **도매상 재고**: 파란색 `도매 38` (발주 가능)
|
|
|
|
---
|
|
|
|
## 향후 계획: 연관 제품 추천
|
|
|
|
약국에 없지만 도매상에 있는 제품 추천 로직:
|
|
|
|
1. **카테고리 기반**: 같은 efficacy_effect (심장사상충, 외부기생충 등)
|
|
2. **신제품**: PostgreSQL `created_at` 최신순
|
|
3. **인기 제품**: 도매상 출고량 기준 (`transaction_type = 'OUTBOUND'` 집계)
|
|
|
|
→ 클릭 시 발주 연결 (미구현)
|
|
|
|
---
|
|
|
|
## 관련 파일
|
|
|
|
- `backend/app.py`: `_get_animal_drugs()`, `_get_animal_drug_rag()`
|
|
- `backend/scripts/insert_apc_*.py`: APC INSERT 스크립트
|
|
- `backend/scripts/check_pgsql_stock_sum.py`: 도매상 재고 확인
|
|
- `docs/APC_MAPPING_PLAN.md`: APC 매핑 기획
|