feat: 애니팜 투약지도서 API 및 마스터 데이터 업데이트

- anipharm_api.py: 동물약 PDF 생성 API 추가
- data/master/*.json: 16종 마스터 데이터 업데이트
- templates: medication_guide_v2, 로고 추가
- docs: AI 매핑 아키텍처, API 스펙 문서
- .gitignore: _dev_scripts/, *.db 제외 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
청춘약국
2026-04-06 18:07:12 +09:00
parent 8a18b530bd
commit dab2ecae44
27 changed files with 3880 additions and 391 deletions

6
.gitignore vendored
View File

@@ -16,3 +16,9 @@ output/
# IDE
.vscode/
.idea/
# 런타임 DB
*.db
# 개발/디버깅 스크립트
_dev_scripts/

379
anipharm_api.py Normal file
View File

@@ -0,0 +1,379 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
애니팜 투약지도서 API
- 동물약 PDF 생성 API
- 포트: 7002
"""
from flask import Flask, request, jsonify, send_file, render_template_string
from flask_cors import CORS
import os
import tempfile
import uuid
import sqlite3
from datetime import datetime
from animal_med.renderer_v2 import AnimalMedRendererV2
app = Flask(__name__)
CORS(app)
# 렌더러 인스턴스 (싱글톤)
renderer = AnimalMedRendererV2()
# 출력 디렉토리
OUTPUT_DIR = os.path.join(os.path.dirname(__file__), 'output')
os.makedirs(OUTPUT_DIR, exist_ok=True)
# ─────────────────────────────────────────────────────────────
# SQLite 접속 로그 DB
# ─────────────────────────────────────────────────────────────
LOGS_DB = os.path.join(os.path.dirname(__file__), 'lecture_logs.db')
def init_logs_db():
"""접속 로그 DB 초기화"""
conn = sqlite3.connect(LOGS_DB)
c = conn.cursor()
c.execute('''
CREATE TABLE IF NOT EXISTS lecture_views (
id INTEGER PRIMARY KEY AUTOINCREMENT,
lecture_id INTEGER NOT NULL,
ip_address TEXT,
user_agent TEXT,
referer TEXT,
viewed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
c.execute('CREATE INDEX IF NOT EXISTS idx_lecture_id ON lecture_views(lecture_id)')
c.execute('CREATE INDEX IF NOT EXISTS idx_viewed_at ON lecture_views(viewed_at)')
conn.commit()
conn.close()
def log_lecture_view(lecture_id, ip, user_agent, referer):
"""강의 조회 로깅"""
try:
conn = sqlite3.connect(LOGS_DB)
c = conn.cursor()
c.execute('''
INSERT INTO lecture_views (lecture_id, ip_address, user_agent, referer)
VALUES (?, ?, ?, ?)
''', (lecture_id, ip, user_agent[:500] if user_agent else None, referer[:500] if referer else None))
conn.commit()
conn.close()
except Exception as e:
print(f"[LOG ERROR] {e}")
# DB 초기화
init_logs_db()
@app.route('/health', methods=['GET'])
def health():
"""헬스체크"""
return jsonify({
'status': 'ok',
'service': 'anipharm-api',
'timestamp': datetime.now().isoformat()
})
@app.route('/api/products', methods=['GET'])
def list_products():
"""등록된 약품 목록 조회"""
products = renderer.list_drugs()
return jsonify({
'success': True,
'count': len(products),
'products': products
})
@app.route('/api/guide/pdf', methods=['POST'])
def generate_pdf():
"""
투약지도서 PDF 생성
Request Body:
{
"product_ids": ["nexgard_spectra", "heartsaver", ...],
"patient_name": "김남곤",
"pet_name": "뽀삐",
"pet_species": "푸들",
"pet_age": "3세",
"pharmacy_name": "청춘약국 동물약 전문상담", // optional
"pharmacy_tel": "033-481-0384" // optional
}
Response: PDF 파일 (application/pdf)
"""
try:
data = request.get_json()
if not data:
return jsonify({'success': False, 'error': 'No JSON data'}), 400
product_ids = data.get('product_ids', [])
if not product_ids:
return jsonify({'success': False, 'error': 'product_ids required'}), 400
# 파일명 생성
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
filename = f"guide_{timestamp}_{uuid.uuid4().hex[:8]}.pdf"
output_path = os.path.join(OUTPUT_DIR, filename)
# PDF 생성
result = renderer.render_to_pdf(
product_ids=product_ids,
output_path=output_path,
patient_name=data.get('patient_name', '보호자'),
pet_name=data.get('pet_name', '반려동물'),
pet_species=data.get('pet_species', ''),
pet_age=data.get('pet_age', ''),
pharmacy_name=data.get('pharmacy_name', '청춘약국 동물약 전문상담'),
pharmacy_tel=data.get('pharmacy_tel', '033-481-0384')
)
if result['success']:
return send_file(
output_path,
mimetype='application/pdf',
as_attachment=True,
download_name=f"투약지도서_{timestamp}.pdf"
)
else:
return jsonify({
'success': False,
'error': result.get('error', 'Unknown error')
}), 500
except Exception as e:
return jsonify({
'success': False,
'error': str(e)
}), 500
@app.route('/api/guide/preview', methods=['POST'])
def preview_guide():
"""
투약지도서 미리보기 (메타데이터만 반환)
Request Body: generate_pdf와 동일
Response: JSON (약품 정보 + 예상 페이지 수)
"""
try:
data = request.get_json()
if not data:
return jsonify({'success': False, 'error': 'No JSON data'}), 400
product_ids = data.get('product_ids', [])
if not product_ids:
return jsonify({'success': False, 'error': 'product_ids required'}), 400
# 약품 정보 조회
drugs = []
for pid in product_ids:
drug = renderer.get_drug(pid)
if drug:
drugs.append({
'id': pid,
'name': drug.get('name'),
'category': drug.get('category'),
'has_image': bool(drug.get('image_url') or drug.get('apc_code'))
})
# 페이지 수 계산 (4개/페이지)
page_count = (len(drugs) + 3) // 4
return jsonify({
'success': True,
'drug_count': len(drugs),
'page_count': page_count,
'drugs': drugs
})
except Exception as e:
return jsonify({
'success': False,
'error': str(e)
}), 500
# ─────────────────────────────────────────────────────────────
# 동물약 강의 콘텐츠 라우트
# ─────────────────────────────────────────────────────────────
LECTURES_DIR = os.path.join(os.path.dirname(__file__), 'static', 'lectures')
os.makedirs(LECTURES_DIR, exist_ok=True)
@app.route('/lecture/<int:lecture_id>')
def serve_lecture(lecture_id):
"""동물약 강의 콘텐츠 서빙 (카카오톡 og 태그 포함) + 접속 로깅"""
from flask import send_from_directory
# 접속 로깅
ip = request.headers.get('X-Forwarded-For', request.remote_addr)
user_agent = request.headers.get('User-Agent', '')
referer = request.headers.get('Referer', '')
log_lecture_view(lecture_id, ip, user_agent, referer)
filename = f'lecture_{lecture_id:02d}.html'
return send_from_directory(LECTURES_DIR, filename)
# ─────────────────────────────────────────────────────────────
# 관리자 페이지 - 강의 접속 통계
# ─────────────────────────────────────────────────────────────
ADMIN_HTML = '''
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>📊 강의 접속 통계 - 애니팜</title>
<style>
* { box-sizing: border-box; }
body { font-family: 'Pretendard', -apple-system, sans-serif; background: #f5f7fa; margin: 0; padding: 20px; }
.container { max-width: 1000px; margin: 0 auto; }
h1 { color: #008BD5; margin-bottom: 30px; }
.card { background: white; border-radius: 12px; padding: 24px; margin-bottom: 20px; box-shadow: 0 2px 8px rgba(0,0,0,0.08); }
.card h2 { margin-top: 0; color: #333; font-size: 1.2em; border-bottom: 2px solid #008BD5; padding-bottom: 10px; }
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; margin-bottom: 20px; }
.stat-box { background: linear-gradient(135deg, #008BD5, #00a8e8); color: white; padding: 20px; border-radius: 10px; text-align: center; }
.stat-box .number { font-size: 2.5em; font-weight: bold; }
.stat-box .label { font-size: 0.9em; opacity: 0.9; }
table { width: 100%; border-collapse: collapse; }
th, td { padding: 12px; text-align: left; border-bottom: 1px solid #eee; }
th { background: #f8f9fa; color: #666; font-weight: 600; }
tr:hover { background: #f8f9fa; }
.ip { font-family: monospace; color: #666; font-size: 0.9em; }
.time { color: #888; font-size: 0.85em; }
.ua { color: #999; font-size: 0.75em; max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.badge { display: inline-block; padding: 4px 10px; border-radius: 20px; font-size: 0.8em; font-weight: 600; }
.badge-lecture { background: #e3f2fd; color: #1976d2; }
.refresh-btn { background: #008BD5; color: white; border: none; padding: 10px 20px; border-radius: 8px; cursor: pointer; font-size: 1em; }
.refresh-btn:hover { background: #0077b6; }
</style>
</head>
<body>
<div class="container">
<h1>📊 강의 접속 통계</h1>
<div class="stat-grid">
<div class="stat-box">
<div class="number">{{ total_views }}</div>
<div class="label">총 조회수</div>
</div>
<div class="stat-box">
<div class="number">{{ today_views }}</div>
<div class="label">오늘 조회수</div>
</div>
<div class="stat-box">
<div class="number">{{ unique_ips }}</div>
<div class="label">순 방문자 (IP)</div>
</div>
</div>
<div class="card">
<h2>📈 강의별 조회수</h2>
<table>
<thead>
<tr><th>강의</th><th>조회수</th><th>최근 조회</th></tr>
</thead>
<tbody>
{% for row in lecture_stats %}
<tr>
<td><span class="badge badge-lecture">Lecture {{ row[0] }}</span></td>
<td><strong>{{ row[1] }}</strong>회</td>
<td class="time">{{ row[2] }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="card">
<h2>🕐 최근 접속 로그 (50건)</h2>
<table>
<thead>
<tr><th>시간</th><th>강의</th><th>IP</th><th>Referer</th></tr>
</thead>
<tbody>
{% for row in recent_logs %}
<tr>
<td class="time">{{ row[0] }}</td>
<td><span class="badge badge-lecture">Lecture {{ row[1] }}</span></td>
<td class="ip">{{ row[2] }}</td>
<td class="ua">{{ row[3] or '-' }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<button class="refresh-btn" onclick="location.reload()">🔄 새로고침</button>
</div>
</body>
</html>
'''
@app.route('/admin/lectures')
def admin_lectures():
"""강의 접속 통계 관리자 페이지"""
conn = sqlite3.connect(LOGS_DB)
c = conn.cursor()
# 총 조회수
c.execute('SELECT COUNT(*) FROM lecture_views')
total_views = c.fetchone()[0]
# 오늘 조회수
c.execute("SELECT COUNT(*) FROM lecture_views WHERE date(viewed_at) = date('now', 'localtime')")
today_views = c.fetchone()[0]
# 순 방문자 (unique IP)
c.execute('SELECT COUNT(DISTINCT ip_address) FROM lecture_views')
unique_ips = c.fetchone()[0]
# 강의별 통계
c.execute('''
SELECT lecture_id, COUNT(*) as cnt, MAX(viewed_at) as last_view
FROM lecture_views
GROUP BY lecture_id
ORDER BY cnt DESC
''')
lecture_stats = c.fetchall()
# 최근 로그 50건
c.execute('''
SELECT viewed_at, lecture_id, ip_address, referer
FROM lecture_views
ORDER BY viewed_at DESC
LIMIT 50
''')
recent_logs = c.fetchall()
conn.close()
return render_template_string(ADMIN_HTML,
total_views=total_views,
today_views=today_views,
unique_ips=unique_ips,
lecture_stats=lecture_stats,
recent_logs=recent_logs
)
if __name__ == '__main__':
print("=" * 50)
print("🐾 애니팜 투약지도서 API")
print("=" * 50)
print(f"📍 http://localhost:7002")
print(f"📋 GET /health - 헬스체크")
print(f"📋 GET /api/products - 약품 목록")
print(f"📋 POST /api/guide/pdf - PDF 생성")
print(f"📋 POST /api/guide/preview - 미리보기")
print("=" * 50)
app.run(host='0.0.0.0', port=7002, debug=False, threaded=True)

View File

@@ -1,58 +1,386 @@
{
"product_id": "MASTER-016",
"apc_code": "0519-ACTIBET",
"apc_code": "9240043910403",
"name": "액티벳정",
"english_name": "Actibet (Amoxicillin + Clavulanate)",
"manufacturer": "홍익메디케어",
"category": "antibiotic",
"category_display": "항생제 (β-Lactam)",
"target_animal": ["개", "고양이"],
"drug_class": "Aminopenicillin + β-Lactamase 억제제",
"ema_ameg_category": "D (Prudence) — 1차 선택 가능",
"who_classification": "CIA (Critically Important Antimicrobials) - High Priority",
"target_animal": [
"개",
"고양이"
],
"administration": "경구 (정제)",
"indication": "광범위 세균 감염 (피부, 호흡기, 요로, 치주)",
"composition": {
"amoxicillin_mg": 40,
"potassium_clavulanate_mg": 10,
"ratio": "4:1",
"description": "아목시실린 40mg + 클라불란산칼륨 10mg (1정 기준)"
},
"mechanism": {
"amoxicillin": "40mg - PBP 결합 → 세포벽 합성 억제 → 살균",
"clavulanate": "10mg - β-Lactamase 억제 → 내성균 커버 확장",
"ratio": "4:1 (Amoxicillin:Clavulanate)"
"amoxicillin": "세균 세포벽 합성 효소(PBP)에 결합 → Peptidoglycan 교차결합 억제 → 세포벽 파괴 → 살균",
"clavulanate": "β-Lactamase 효소에 비가역적 결합 → 아목시실린 분해 방지 → 내성균 커버 확장",
"killing_type": "살균성(bactericidal), 시간 의존적(time-dependent)",
"clinical_implication": "MIC 이상 농도 유지 시간이 효능 결정 → 1일 2회 분할 투여 필수"
},
"dosage": {
"standard": "12.5mg/kg 1일 2회",
"formula": "체중 4kg당 1정",
"duration": "5~7일 (질환별 상이)"
},
"dosage_table": [
{"weight": "4kg", "tablets": "1정 × 2회"},
{"weight": "8kg", "tablets": "2정 × 2회"},
{"weight": "12kg", "tablets": "3정 × 2회"},
{"weight": "20kg", "tablets": "5정 × 2회"}
"spectrum": {
"gram_positive_aerobic": [
"Staphylococcus pseudintermedius (MSSP)",
"Staphylococcus aureus (MSSA)",
"Streptococcus spp.",
"Enterococcus faecalis"
],
"indications_by_disease": {
"skin_pyoderma": "5~7일 (표재성) / 3~4주 (심부)",
"uti": "7~14일",
"respiratory": "7~10일",
"dental": "수술 전후 5~7일"
},
"warnings": [
"⚠️ 페니실린 알레르기 과거력 확인",
"⚠️ 소형견/고양이 정확한 체중 투여",
"⚠️ 시간 의존적 살균 → 분할 투여 필수",
"⚠️ 장기 투여 시 내성균 모니터링"
"gram_negative_aerobic": [
"Escherichia coli",
"Proteus mirabilis",
"Klebsiella spp.",
"Pasteurella multocida"
],
"clinical_notes": [
"EMA AMEG Category D: 1차 선택 가능",
"β-Lactamase 생산균까지 커버 (단독 AMX 대비)",
"MIC 이상 농도 유지 시간이 핵심 → BID 분할"
"anaerobes": [
"Bacteroides spp.",
"Fusobacterium spp.",
"Clostridium spp. (일부)"
],
"source": {
"guidelines": ["ISCAID (수의 피부과)", "AAHA"]
"resistant_organisms": [
"MRSP (메티실린 내성 S. pseudintermedius)",
"MRSA",
"Pseudomonas aeruginosa",
"Mycoplasma spp.",
"Bordetella bronchiseptica (일부)"
]
},
"storage": "25°C 이하, 건조, 차광 보관"
"indications": {
"summary": "광범위 세균 감염 (피부, 요로, 호흡기, 연조직, 구강)",
"detailed": [
{
"name": "피부감염 (농피증)",
"description": "표재성 및 심부 세균성 피부감염",
"iscaid_position": "전신 항생제 1차 선택 (국소치료 실패 시)"
},
{
"name": "요로감염 (방광염, 신우신염)",
"description": "단순 산발성 방광염부터 복잡성 상부 UTI까지",
"iscaid_position": "1차 선택"
},
{
"name": "호흡기 감염",
"description": "상·하부 호흡기 세균 감염 (폐렴 포함)",
"iscaid_position": "대안 1차 (Doxycycline 불가 시)"
},
{
"name": "연조직 감염",
"description": "농양, 항문낭염, 교상(물린 상처)",
"iscaid_position": "1차 선택"
},
{
"name": "구강/치주 감염",
"description": "치주질환, 구강 내 혼합감염",
"iscaid_position": "2차 (Clindamycin이 1차)"
}
]
},
"dosage": {
"standard": "12.5mg/kg (복합) 1일 2회 (q12h)",
"formula": "체중 4kg당 1정, 12시간 간격",
"per_kg": {
"amoxicillin": "10mg/kg/회",
"clavulanate": "2.5mg/kg/회"
}
},
"dosage_table": [
{
"weight": "2kg",
"tablets_per_dose": "0.5정",
"frequency": "1일 2회",
"daily_amoxicillin": "40mg",
"daily_clavulanate": "10mg"
},
{
"weight": "4kg",
"tablets_per_dose": "1정",
"frequency": "1일 2회",
"daily_amoxicillin": "80mg",
"daily_clavulanate": "20mg"
},
{
"weight": "6kg",
"tablets_per_dose": "1.5정",
"frequency": "1일 2회",
"daily_amoxicillin": "120mg",
"daily_clavulanate": "30mg"
},
{
"weight": "8kg",
"tablets_per_dose": "2정",
"frequency": "1일 2회",
"daily_amoxicillin": "160mg",
"daily_clavulanate": "40mg"
},
{
"weight": "10kg",
"tablets_per_dose": "2.5정",
"frequency": "1일 2회",
"daily_amoxicillin": "200mg",
"daily_clavulanate": "50mg"
},
{
"weight": "12kg",
"tablets_per_dose": "3정",
"frequency": "1일 2회",
"daily_amoxicillin": "240mg",
"daily_clavulanate": "60mg"
},
{
"weight": "16kg",
"tablets_per_dose": "4정",
"frequency": "1일 2회",
"daily_amoxicillin": "320mg",
"daily_clavulanate": "80mg"
},
{
"weight": "20kg",
"tablets_per_dose": "5정",
"frequency": "1일 2회",
"daily_amoxicillin": "400mg",
"daily_clavulanate": "100mg"
}
],
"duration_by_indication": [
{
"indication": "단순 방광염",
"duration": "3~5일",
"note": "ISCAID 2019 권장. 증상 소실 후에도 완료",
"source": "ISCAID UTI Guidelines 2019"
},
{
"indication": "신우신염 (상부 UTI)",
"duration": "10~14일",
"note": "전신 증상 동반 시. 배양검사 권장",
"source": "ISCAID UTI Guidelines 2019"
},
{
"indication": "표재성 농피증",
"duration": "2주 + 재평가",
"note": "국소치료 실패 시만 전신투여. 임상호전 후 1주 추가",
"source": "ISCAID Pyoderma Guidelines 2025"
},
{
"indication": "심부 농피증",
"duration": "3주 + 재평가",
"note": "배양검사 권장. 증상 소실 후 최소 1주 연장",
"source": "ISCAID Pyoderma Guidelines 2025"
},
{
"indication": "상부 호흡기 감염",
"duration": "7~10일",
"note": "Mycoplasma 의심 시 Doxycycline 선택",
"source": "ISCAID Respiratory Guidelines 2017"
},
{
"indication": "하부 호흡기/폐렴 (개)",
"duration": "14일",
"note": "경증~중등도 폐렴",
"source": "ISCAID Respiratory Guidelines 2017"
},
{
"indication": "하부 호흡기/폐렴 (고양이)",
"duration": "21일",
"note": "고양이는 재발률 높아 장기 투여",
"source": "ISCAID Respiratory Guidelines 2017"
},
{
"indication": "연조직 감염/교상",
"duration": "5~7일",
"note": "Pasteurella + 혐기성균 동시 커버",
"source": "ISCAID"
},
{
"indication": "치주/구강 감염",
"duration": "5~7일",
"note": "수술 전후 예방적 투여 포함",
"source": "General practice"
}
],
"administration_instructions": {
"timing": [
"1일 2회, 12시간 간격 유지 (예: 아침 8시, 저녁 8시)",
"시간 의존적 살균제 → 일정한 간격이 효과에 중요"
],
"with_food": {
"recommended": true,
"reason": "음식과 함께 투여 시 위장관 부작용 감소",
"note": "공복 투여도 가능하나 구토/설사 위험 증가"
},
"completion_importance": {
"message": "증상이 나아져도 처방 기간 끝까지 복용 완료",
"reason": "불완전 투약 시 남은 세균이 내성을 획득할 위험",
"warning": "임의 중단은 항생제 내성 유발의 주요 원인"
},
"missed_dose": "1회분을 놓쳤을 경우 기억난 즉시 투여. 다음 투약 시간이 가까우면 건너뛰고 다음 회차에 정상 용량 투여 (2배 용량 투여 금지)"
},
"side_effects": {
"common": [
{
"symptom": "구토",
"frequency": "흔함",
"management": "음식과 함께 투여. 지속 시 수의사 상담"
},
{
"symptom": "설사",
"frequency": "흔함",
"management": "장내균총 교란 가능. 프로바이오틱스 병행 고려 (투약 2시간 간격)"
},
{
"symptom": "식욕 부진",
"frequency": "흔함",
"management": "대부분 일시적. 지속 시 수의사 상담"
}
],
"uncommon": [
{
"symptom": "알레르기 반응 (두드러기, 안면부종, 호흡곤란)",
"frequency": "드묾",
"management": "즉시 투약 중단 및 응급 처치 필요",
"severity": "심각"
},
{
"symptom": "아나필락시스",
"frequency": "매우 드묾",
"management": "응급 상황. 에피네프린 투여 필요",
"severity": "생명 위협"
}
],
"when_to_stop": [
"심한 구토/설사가 지속될 때",
"두드러기, 안면 부종, 호흡 곤란 발생 시 (알레르기)",
"혈변, 극심한 복통 등 심각한 증상 시"
]
},
"contraindications": [
{
"condition": "페니실린 계열 알레르기",
"severity": "절대 금기",
"note": "과거 페니실린/세팔로스포린 과민반응 이력 있는 경우"
},
{
"condition": "중증 신부전",
"severity": "주의 필요",
"note": "용량 조절 또는 투여 간격 연장 필요. 수의사 판단"
}
],
"warnings": [
"⚠️ 페니실린 알레르기 과거력 반드시 확인",
"⚠️ 소형견/고양이는 체중에 정확히 비례하여 투여 (과량 주의)",
"⚠️ 시간 의존적 살균제 → 1일 2회 분할 투여 필수 (1일 1회 투여 금지)",
"⚠️ 사람용 오그멘틴(Augmentin) 임의 투여 금지 (비율/용량 다름)",
"⚠️ 장기 투여 시 내성균 발생 모니터링 필요",
"⚠️ 치료 실패 시 배양검사 시행 (경험적 재처방 지양)"
],
"antibiotic_stewardship": {
"importance": "항생제 내성은 인수공통 문제. 동물에서의 오남용은 사람에게도 영향",
"principles": [
"처방된 기간 끝까지 복용 완료 (조기 중단 금지)",
"남은 약 보관 후 자가 투약 금지",
"증상 재발 시 수의사 재진 (같은 약 임의 복용 금지)",
"가능하면 배양검사 후 처방 (특히 재발/치료 실패 시)"
],
"resistance_warning": "불완전 투약, 과소/과다 용량, 불필요한 처방은 내성균 선택의 주요 원인",
"iscaid_effect": "ISCAID 가이드라인 준수 결과 이탈리아에서 E.coli의 AMX-CLV 내성률이 52.6%→25.6%로 감소 (PMID:41012835)"
},
"drug_interactions": [
{
"drug": "Methotrexate",
"effect": "Methotrexate 배설 감소 → 독성 증가 가능",
"recommendation": "병용 시 모니터링 필요"
},
{
"drug": "Probenecid",
"effect": "아목시실린 신장 배설 억제 → 혈중 농도 상승",
"recommendation": "용량 조절 고려"
},
{
"drug": "구충제 (일반)",
"effect": "대부분 병용 가능",
"recommendation": "펜벤다졸, 이버멕틴 등 일반 구충제와 병용 안전"
},
{
"drug": "프로바이오틱스",
"effect": "항생제로 인한 장내균총 교란 완화",
"recommendation": "병용 가능. 투약 시간 2시간 간격 권장"
}
],
"susceptibility_data": [
{
"pathogen": "E. coli (개 UTI)",
"susceptibility": "92%",
"source": "KuKanich 2020 (PMID:31777977)",
"region": "미국 중서부"
},
{
"pathogen": "E. coli (이탈리아, 2019 이후)",
"susceptibility": "74.4%",
"source": "Tagliasacchi 2025 (PMID:41012835)",
"note": "ISCAID 가이드라인 도입 후 내성률 25.6%로 감소"
},
{
"pathogen": "S. pseudintermedius (MSSP, 유럽)",
"susceptibility": "≥88.5%",
"source": "ComPath 2020 (PMID:32924232)",
"note": "피부 분리주"
},
{
"pathogen": "S. pseudintermedius (MRSP)",
"susceptibility": "내성 (일반)",
"source": "Pirolo 2023 (PMID:37294541)",
"note": "Low-level MRSP 일부는 임상 반응"
}
],
"clinical_notes": [
"EMA AMEG Category D: 경험적 처방 허용되는 1차 선택 항생제",
"β-Lactamase 생산균까지 커버 (Amoxicillin 단독 대비 스펙트럼 확장)",
"시간 의존적 살균 → MIC 이상 농도 유지가 핵심 → BID 분할 필수",
"ISCAID 가이드라인이 항생제 내성률 감소에 실질적 효과 입증됨",
"치료 실패 시 Category C (Cephalexin 등) → B (Fluoroquinolone) 순으로 상향"
],
"pharmacy_counseling": {
"key_messages": [
"체중 4kg당 1정, 하루 2번 (12시간 간격)",
"음식과 함께 드리면 위장 부작용 감소",
"증상 나아져도 처방 기간 끝까지 복용 완료 (내성 예방)",
"구토/설사 심하거나 알레르기 증상(부종, 호흡곤란) 시 즉시 중단"
],
"common_questions": [
{
"question": "며칠이나 먹여야 하나요?",
"answer": "질환에 따라 다릅니다. 방광염 3~5일, 피부감염 2~3주, 호흡기 7~21일. 수의사 처방 기간 준수하세요."
},
{
"question": "증상이 나았는데 계속 먹여야 하나요?",
"answer": "네, 반드시요. 증상만 나아지고 세균은 남아있을 수 있습니다. 중간에 끊으면 내성균이 생깁니다."
},
{
"question": "사람용 오그멘틴 줘도 되나요?",
"answer": "안 됩니다. 용량과 비율이 다릅니다. 동물 전용 제품만 사용하세요."
},
{
"question": "부작용은 없나요?",
"answer": "구토, 설사 같은 위장 증상이 흔합니다. 음식과 함께 주면 줄어듭니다. 알레르기 반응(부종, 호흡곤란)은 드물지만 발생 시 즉시 중단하세요."
}
]
},
"source": {
"guidelines": [
"ISCAID UTI Guidelines 2019 (PMID:30971357)",
"ISCAID Pyoderma Guidelines 2025 (PMID:40338805)",
"ISCAID Respiratory Guidelines 2017 (PMC5354050)",
"AAHA/AAFP Antimicrobial Stewardship Guidelines 2022"
],
"golden_pattern": "actibet_amoxicillin_clavulanate.md (2026-03-02)"
},
"storage": "25°C 이하, 건조, 차광 보관",
"last_updated": "2026-03-19",
"indication": "광범위 세균 감염 (피부, 요로, 호흡기, 연조직, 구강)"
}

View File

@@ -1,64 +1,101 @@
{
"product_id": "MASTER-014",
"apc_code": "0519-ANTELMIN",
"apc_code": "0230237810109",
"name": "안텔민 뽀삐/킹",
"english_name": "Antelmin (Mebendazole + Praziquantel)",
"manufacturer": "대성",
"category": "antiparasitic",
"category_display": "광범위 내부구충제",
"target_animal": ["개", "고양이"],
"target_animal": [
"개",
"고양이"
],
"administration": "경구 (정제)",
"indication": "회충, 조충(촌충), 십이지장충(구충), 편충 구제",
"coverage_summary": {
"covered": ["회충", "조충(촌충)", "구충(십이지장충)", "편충"],
"not_covered": ["벼룩", "진드기", "심장사상충"],
"covered": [
"회충",
"조충(촌충)",
"구충(십이지장충)",
"편충"
],
"not_covered": [
"벼룩",
"진드기",
"심장사상충"
],
"gap_solution": "넥스가드/셀라이트의 조충 갭 보완용"
},
"mechanism": {
"mebendazole": "벤즈이미다졸계 → 회충, 구충, 편충 구제",
"praziquantel": "프라지노이소퀴놀린계 → 조충(촌충) 구제"
},
"dosing": {
"interval": "3개월마다 (연 4회)",
"interval_reason": "ESCCAP/CAPC 가이드라인 기반, 기생충 prepatent period 고려",
"puppy_kitten": "6개월 미만: 2주~1개월 간격",
"minimum_age": "제한 없음"
},
"dosage_table": [
{"product": "뽀삐 정", "weight": "~5kg", "tablets": "1정"},
{"product": "킹 정 5kg", "weight": "5kg", "tablets": "1정"},
{"product": "킹 정 10kg", "weight": "10kg", "tablets": "2정"},
{"product": "킹 정 15kg", "weight": "15kg", "tablets": "3정"},
{"product": "킹 정 20kg", "weight": "20kg", "tablets": "4정"}
{
"product": "뽀삐 정",
"weight": "~5kg",
"tablets": "1정"
},
{
"product": "킹 정 5kg",
"weight": "5kg",
"tablets": "1정"
},
{
"product": "킹 정 10kg",
"weight": "10kg",
"tablets": "2정"
},
{
"product": "킹 정 15kg",
"weight": "15kg",
"tablets": "3정"
},
{
"product": "킹 정 20kg",
"weight": "20kg",
"tablets": "4정"
}
],
"prepatent_periods": [
{"parasite": "십이지장충", "period": "14~18일"},
{"parasite": "개회충", "period": "2~5주"},
{"parasite": "조충(벼룩매개)", "period": "~3주"},
{"parasite": "편충", "period": "10~12주"}
{
"parasite": "십이지장충",
"period": "14~18일"
},
{
"parasite": "개회충",
"period": "2~5주"
},
{
"parasite": "조충(벼룩매개)",
"period": "~3주"
},
{
"parasite": "편충",
"period": "10~12주"
}
],
"warnings": [
"⚠️ 공복 투여 권장 (효과 증가)",
"⚠️ 다두 사육 시 동시 투약 (교차 감염 방지)",
"⚠️ 유기동물: 즉시 투약 + 2주 후 재투약"
],
"clinical_notes": [
"넥스가드 스펙트라/셀라이트의 조충 미커버 보완",
"3개월 간격 정기 투약 권장 (ESCCAP/CAPC)",
"벼룩 관리 필수 (조충 중간숙주)"
],
"source": {
"guidelines": ["ESCCAP GL01 7th Ed (2025)", "CAPC Guidelines"]
"guidelines": [
"ESCCAP GL01 7th Ed (2025)",
"CAPC Guidelines"
]
},
"storage": "실온 보관"
}

View File

@@ -1,38 +1,58 @@
{
"product_id": "MASTER-002",
"apc_code": "0232617800004",
"apc_code": "0232635710103",
"name": "아시카프 츄어블정",
"english_name": "Asikaff Chewable (Carprofen 50mg)",
"manufacturer": "미상",
"category": "nsaid",
"category_display": "진통소염제 (NSAIDs)",
"target_animal": ["개"],
"target_animal": [
"개"
],
"administration": "경구 (츄어블정)",
"image_url": "/images/asikaff.png",
"indication": "개의 관절염, 수술 후 통증, 근골격계 염증 완화",
"mechanism": {
"drug_class": "프로피온산계 NSAIDs",
"action": "COX-2 우선 억제 → 염증성 프로스타글란딘 생성 억제",
"selectivity": "COX-2 우선 (preferential) - 완전 선택적 아님"
},
"dosage": {
"standard": "4.4mg/kg 1일 1회",
"alternative": "2.2mg/kg 1일 2회",
"note": "최소 유효 용량 원칙 - 효과 확인 후 감량 시도"
},
"dosage_table": [
{"weight": "5kg", "daily_dose": "22mg", "tablets": "0.5정 (반정)"},
{"weight": "10kg", "daily_dose": "44mg", "tablets": "1정"},
{"weight": "15kg", "daily_dose": "66mg", "tablets": "1.5정"},
{"weight": "20kg", "daily_dose": "88mg", "tablets": "2정"},
{"weight": "25kg", "daily_dose": "110mg", "tablets": "2.5정"},
{"weight": "30kg", "daily_dose": "132mg", "tablets": "3정"}
{
"weight": "5kg",
"daily_dose": "22mg",
"tablets": "0.5정 (반정)"
},
{
"weight": "10kg",
"daily_dose": "44mg",
"tablets": "1정"
},
{
"weight": "15kg",
"daily_dose": "66mg",
"tablets": "1.5정"
},
{
"weight": "20kg",
"daily_dose": "88mg",
"tablets": "2정"
},
{
"weight": "25kg",
"daily_dose": "110mg",
"tablets": "2.5정"
},
{
"weight": "30kg",
"daily_dose": "132mg",
"tablets": "3정"
}
],
"absolute_contraindications": [
{
"item": "고양이 사용 절대 금지",
@@ -50,7 +70,6 @@
"severity": "치명적"
}
],
"relative_contraindications": [
"신장 기능 저하",
"간 기능 저하",
@@ -59,7 +78,6 @@
"심부전",
"탈수 상태"
],
"warnings": [
"🚫 고양이에게 절대 투여하지 마세요 (치명적)",
"🚫 스테로이드와 함께 투여하지 마세요",
@@ -67,16 +85,33 @@
"⚠️ 장기 투여 시 3~6개월마다 혈액검사 필요",
"⚠️ 음식과 함께 투여하면 위장 자극 감소"
],
"side_effects": {
"common": ["구토", "설사", "식욕부진"],
"serious": ["위장관 궤양/출혈 (흑색변)", "간독성 (황달)", "신독성 (다음다뇨)"],
"monitoring_signs": ["흑색변", "토혈", "황달", "기력저하", "다음다뇨"]
"common": [
"구토",
"설사",
"식욕부진"
],
"serious": [
"위장관 궤양/출혈 (흑색변)",
"간독성 (황달)",
"신독성 (다음다뇨)"
],
"monitoring_signs": [
"흑색변",
"토혈",
"황달",
"기력저하",
"다음다뇨"
]
},
"monitoring": {
"required": true,
"pre_treatment": ["CBC", "간기능 (ALT, ALP, AST)", "신기능 (BUN, Cr)", "뇨검사"],
"pre_treatment": [
"CBC",
"간기능 (ALT, ALP, AST)",
"신기능 (BUN, Cr)",
"뇨검사"
],
"during_treatment": {
"2_4_weeks": "혈청 화학 (간·신기능)",
"3_months": "혈청 화학, 뇨검사",
@@ -89,31 +124,39 @@
"황달"
]
},
"washout_period": {
"to_other_nsaid": "3~5일",
"to_steroid": "5~7일",
"from_short_steroid": "5~7일",
"from_long_steroid": "2주 이상"
},
"clinical_efficacy": {
"osteoarthritis": "89.1~92.4% 개선",
"post_surgical": "우수한 통증 관리",
"source_pmid": ["7759332", "12665145", "17056650", "25433056"]
"source_pmid": [
"7759332",
"12665145",
"17056650",
"25433056"
]
},
"storage": "실온 보관, 습기 피할 것",
"pharmacist_tips": [
"음식과 함께 투여 권장 (위장 자극 감소)",
"장기 투여 시 정기 검사 안내 필수",
"보호자에게 중단 신호 교육 (흑색변, 구토, 황달)",
"스테로이드 병용 여부 반드시 확인"
],
"source": {
"guidelines": ["WSAVA Pain Management Guidelines"],
"pmid": ["7759332", "12665145", "17056650", "16468926", "25433056"]
"guidelines": [
"WSAVA Pain Management Guidelines"
],
"pmid": [
"7759332",
"12665145",
"17056650",
"16468926",
"25433056"
]
}
}

View File

@@ -1,39 +1,36 @@
{
"product_id": "MASTER-009",
"apc_code": "0519-CHLORHEX-SHAMPOO",
"apc_code": "0231334930108",
"name": "클로르헥시딘 샴푸",
"english_name": "Chlorhexidine Shampoo 2%",
"manufacturer": "비르박",
"category": "topical",
"category_display": "피부외용제 (샴푸)",
"target_animal": ["개", "고양이"],
"target_animal": [
"개",
"고양이"
],
"administration": "외용 (샴푸)",
"indication": "세균성/진균성 피부염, 농피증, 피부 감염 예방",
"mechanism": {
"drug_class": "비구아나이드계 소독제",
"action": "세균 세포막 파괴 → 살균 작용",
"spectrum": "그람양성균, 그람음성균, 효모균"
},
"dosage": {
"frequency": "주 2~3회",
"contact_time": "5~10분간 방치 후 헹굼",
"duration": "증상 호전 시까지 (보통 2~4주)"
},
"warnings": [
"⚠️ 눈, 귀, 점막 접촉 피할 것",
"⚠️ 사용 후 완전히 헹굴 것",
"⚠️ 깊은 상처에는 사용 금지"
],
"clinical_notes": [
"경구 항생제와 병용 시 효과 증가",
"거품을 충분히 내어 피부에 접촉시키는 것이 중요",
"피부 건조 시 보습제 병용 권장"
],
"storage": "실온 보관, 직사광선 피할 것"
}

View File

@@ -1,67 +1,89 @@
{
"product_id": "MASTER-003",
"apc_code": "0519-ENROFLOXACIN",
"apc_code": "0232532310106",
"name": "아시엔로 50",
"english_name": "Enrofloxacin 50mg",
"manufacturer": "아시아제약",
"category": "antibiotic",
"category_display": "항생제 (퀴놀론계)",
"target_animal": ["개", "고양이"],
"target_animal": [
"개",
"고양이"
],
"administration": "경구 (정제)",
"image_url": "/images/enrofloxacin.png",
"indication": "피부감염, 요로감염, 호흡기감염, 상처감염 등 세균성 감염증 치료",
"mechanism": {
"drug_class": "Fluoroquinolone (3세대 퀴놀론)",
"action": "DNA gyrase 및 topoisomerase IV 억제 → 세균 DNA 복제 차단",
"spectrum": "그람양성균, 그람음성균 광범위"
},
"dosage": {
"standard": "5mg/kg 1일 1회",
"duration": "7~14일",
"note": "음식과 함께 또는 공복 투여 가능"
},
"dosage_table": [
{"weight": "5kg", "daily_dose": "25mg", "tablets": "0.5정"},
{"weight": "10kg", "daily_dose": "50mg", "tablets": "1정"},
{"weight": "15kg", "daily_dose": "75mg", "tablets": "1.5정"},
{"weight": "20kg", "daily_dose": "100mg", "tablets": "2정"},
{"weight": "25kg", "daily_dose": "125mg", "tablets": "2.5정"}
{
"weight": "5kg",
"daily_dose": "25mg",
"tablets": "0.5정"
},
{
"weight": "10kg",
"daily_dose": "50mg",
"tablets": "1정"
},
{
"weight": "15kg",
"daily_dose": "75mg",
"tablets": "1.5정"
},
{
"weight": "20kg",
"daily_dose": "100mg",
"tablets": "2정"
},
{
"weight": "25kg",
"daily_dose": "125mg",
"tablets": "2.5정"
}
],
"warnings": [
"⚠️ 고양이: 5mg/kg 초과 금지 (망막 독성 위험!)",
"⚠️ 성장기 동물: 연골 손상 가능성 (1세 미만 주의)",
"⚠️ 간질/경련 병력 동물 주의",
"⚠️ 제산제(알루미늄, 마그네슘)와 2시간 간격 투여"
],
"contraindications": [
"1세 미만 강아지 (대형견은 18개월 미만)",
"임신/수유 중",
"간질/경련 병력",
"퀴놀론 과민반응 이력"
],
"side_effects": {
"common": ["구토", "설사", "식욕부진"],
"serious": ["고양이 망막 독성 (고용량)", "연골 손상 (성장기)", "경련 (드묾)"]
"common": [
"구토",
"설사",
"식욕부진"
],
"serious": [
"고양이 망막 독성 (고용량)",
"연골 손상 (성장기)",
"경련 (드묾)"
]
},
"cat_warning": {
"max_dose": "5mg/kg/day",
"max_duration": "21일",
"risk": "망막 변성 → 실명 가능",
"source": "다수 문헌 보고"
},
"storage": "실온 보관, 습기 피할 것",
"source": {
"guidelines": ["ISCAID Antimicrobial Guidelines"],
"guidelines": [
"ISCAID Antimicrobial Guidelines"
],
"notes": "고양이 망막 독성 관련 다수 증례 보고"
}
}

View File

@@ -6,43 +6,63 @@
"manufacturer": "한국동물약품",
"category": "antiparasitic",
"category_display": "외부구충제 (스팟온)",
"target_animal": ["개", "고양이"],
"target_animal": [
"개",
"고양이"
],
"administration": "경피 도포 (스팟온)",
"indication": "벼룩, 진드기 구제",
"coverage": {
"external": {
"fleas": {"covered": true, "note": "4~8시간 내 사멸"},
"ticks": {"covered": true, "note": "접촉 사멸"}
"fleas": {
"covered": true,
"note": "4~8시간 내 사멸"
},
"heartworm": {"covered": false},
"intestinal": {
"roundworm": {"covered": false},
"hookworm": {"covered": false},
"whipworm": {"covered": false},
"tapeworm": {"covered": false}
"ticks": {
"covered": true,
"note": "접촉 사멸"
}
},
"heartworm": {
"covered": false
},
"intestinal": {
"roundworm": {
"covered": false
},
"hookworm": {
"covered": false
},
"whipworm": {
"covered": false
},
"tapeworm": {
"covered": false
}
}
},
"coverage_summary": {
"covered": ["벼룩", "진드기"],
"not_covered": ["심장사상충", "내부기생충"],
"covered": [
"벼룩",
"진드기"
],
"not_covered": [
"심장사상충",
"내부기생충"
],
"gap_solution": "심장사상충: 하트세이버 / 내부기생충: 안텔민 추가"
},
"dosing": {
"interval": "매월 1회",
"interval_reason": "효능 지속 4주",
"minimum_age": "8주 이상",
"minimum_weight": "제한 없음"
},
"warnings": [
"⚠️ 도포 후 2일간 목욕/수영 금지",
"⚠️ 토끼에게는 독성 (사용 금지)",
"⚠️ 피부 상처 부위 도포 금지"
],
"storage": "실온 보관, 직사광선 피할 것"
"storage": "실온 보관, 직사광선 피할 것",
"image_url": "https://d1vgkbcgf4kpck.cloudfront.net/medicine/3faefec5-4bdf-4039-93e3-b99b55ef9417.png"
}

View File

@@ -1,43 +1,264 @@
{
"product_id": "MASTER-012",
"apc_code": "0231093500002",
"apc_code": "0231093520106",
"apc_variants": {
"5g": "0231093510108",
"10g": "0231093520106",
"15g": "0231093530104",
"20g": "0231093540102",
"30g": "0231093550109",
"50g": "0231093560107",
"100g": "0231093570105",
"200g": "0231093580103"
},
"name": "복합 개시딘 겔",
"english_name": "GaeSidin Gel (Fusidic acid + Betamethasone)",
"manufacturer": "(주)이엘티사이언스",
"approval_number": "194",
"approval_date": "2020-02-13",
"category": "topical",
"category_display": "피부외용제 (농피증)",
"target_animal": ["개"],
"target_animal": [
"개"
],
"administration": "외용 (겔)",
"indication": "표면성 세균성 농피증 국소 치료",
"mechanism": {
"fusidic_acid": "0.5% - 황색포도상구균·MRSP 살균",
"betamethasone": "0.1% - 항염증·항소양 (Class III 스테로이드)"
"active_ingredients": {
"fusidic_acid": {
"concentration": "5mg/g (0.5%)",
"class": "스테로이드 구조 항생제",
"mechanism": "EF-G 결합 → 단백질 합성 억제 → 살균",
"target_bacteria": [
"황색포도상구균",
"S. pseudintermedius",
"MRSP"
]
},
"betamethasone_valerate": {
"concentration": "1mg/g (0.1%)",
"class": "Class III 코르티코스테로이드",
"mechanism": "PLA2 억제 → 프로스타글란딘/루코트리엔 감소 → 항염증·항소양"
}
},
"formulation_advantage": {
"why_gel": "털이 있는 개 피부에 최적화 - 겔이 털 사이로 침투하여 피부에 직접 도달",
"vs_cream": "크림/연고는 털에 흡착되어 피부 도달 저하",
"ph_optimization": "개 피부 pH(6.5~8.2)에 맞는 중성~친수성 기제",
"efficacy_evidence": "피부 내 농도 MIC90의 67,000배 달성 (PMID 29162115)"
},
"dosage": {
"frequency": "1일 2회",
"duration": "최소 5일 → 증상 소실 후 2일 추가",
"max_duration": "7일 초과 금지",
"application": "환부 청결 후 환부에만 국소 도포"
"duration_min": "최소 5일",
"duration_after_resolution": "증상 소실 후 2일 추가",
"duration_max": "7일 (절대 초과 금지)",
"amount": "소량을 환부에만"
},
"warnings": [
"⚠️ 7일 초과 사용 금지",
"⚠️ 3일 사용 후 호전 없으면 수의사 재진",
"⚠️ 눈·점막·깊은 상처 도포 금지",
"⚠️ 도포 후 핥지 않도록 엘리자베스 칼라"
"application_method": {
"step_1": {
"action": "환부 세정",
"detail": "미온수 또는 클로르헥시딘 희석액으로 환부를 깨끗이 닦고 완전히 건조"
},
"step_2": {
"action": "털 갈라내기",
"detail": "환부 주변 털을 손가락으로 갈라 피부를 최대한 노출"
},
"step_3": {
"action": "도포",
"detail": "소량(완두콩 크기 정도)을 환부에만 얇게 펴 바름"
},
"step_4": {
"action": "흡수 대기",
"detail": "2~3분간 자연 건조 - 겔이 빠르게 흡수됨"
},
"step_5": {
"action": "핥기 방지",
"detail": "도포 직후 엘리자베스 칼라 착용 또는 15분간 감시"
},
"caregiver_tip": "장갑 착용 권장 - 베타메타손 피부 흡수 방지"
},
"wound_care_guidelines": {
"before_application": [
"환부가 심하게 오염된 경우 생리식염수로 세척",
"딱지나 가피가 있으면 무리하게 제거하지 말 것",
"출혈이 있는 깊은 상처에는 사용 금지"
],
"after_application": [
"통기성 유지 - 밀폐 드레싱 금지",
"붕대 감기 비권장 (습기 축적 → 세균 증식)",
"환부 긁기 방지를 위해 발톱 정리 권장"
],
"environment": [
"도포 후 30분간 산책/목욕 금지",
"수영/물놀이 금지 (치료 기간 중)",
"습한 환경 피하기 - 건조한 환경 유지"
]
},
"elizabethan_collar_guide": {
"necessity": "필수 - 베타메타손 경구 섭취 시 전신 흡수 위험",
"timing": "도포 직후 최소 15~20분, 가능하면 치료 기간 내내",
"size_selection": "코 끝이 칼라 가장자리에 닿지 않는 크기 선택",
"alternatives": [
"도넛형 넥칼라 (목 부담 적음)",
"수술복/보호복 (체간 환부인 경우)",
"발 환부인 경우 양말+테이프"
],
"signs_of_licking": [
"환부 주변 털이 축축함",
"겔이 번들거리지 않고 매트함",
"환부 악화 또는 발적 증가"
]
},
"progress_monitoring": {
"day_1_2": {
"expected": "소양감 감소 시작 (베타메타손 효과)",
"observe": [
"긁는 빈도 감소",
"발적 약간 완화"
],
"action": "계속 도포, 칼라 유지"
},
"day_3": {
"expected": "병변 크기 감소, 삼출물 감소",
"observe": [
"환부 건조해짐",
"딱지 형성 시작"
],
"checkpoint": true,
"action_if_improved": "계속 도포",
"action_if_no_change": "⚠️ 수의사 재진 필요 (내성균 또는 진균 가능성)"
},
"day_5": {
"expected": "대부분 증상 소실",
"observe": [
"피부 정상색 회복",
"털 재성장 시작"
],
"action": "증상 소실 확인 후 2일 추가 도포"
},
"day_7": {
"expected": "완전 치유",
"observe": [
"환부 완전 건조",
"정상 피부와 구분 어려움"
],
"action": "사용 종료 - 7일 초과 절대 금지"
}
},
"veterinary_revisit_triggers": {
"timing_3_days": "3일 사용 후 호전 없거나 악화 시",
"immediate_triggers": [
"환부 급격히 확대",
"고름 증가 또는 악취",
"발열, 식욕저하, 무기력",
"전신으로 병변 확산"
],
"possible_causes": [
"퓨시드산 내성균 감염 (한국 27%)",
"진균성(Malassezia) 농피증 오진",
"심부 농피증으로 진행"
],
"required_tests": "세균 배양검사 및 감수성 검사 권장"
},
"warnings": [
"⚠️ 7일 초과 사용 금지 - HPA 억제 위험",
"⚠️ 3일 사용 후 호전 없으면 수의사 재진",
"⚠️ 눈·점막·귀 내부·깊은 상처 도포 금지",
"⚠️ 도포 후 핥지 않도록 엘리자베스 칼라 필수",
"⚠️ 사용자(보호자) 장갑 착용 권장"
],
"contraindications": {
"absolute": [
"진균성(곰팡이) 농피증 - 스테로이드가 악화시킴",
"고양이 - 개 전용 허가",
"고막 천공된 귀 감염",
"바이러스성 피부 감염"
],
"relative": [
"임신·수유 중인 개 - 수의사 판단",
"당뇨병 환자 - 스테로이드 영향",
"쿠싱 증후군 환자"
]
},
"side_effects": {
"local": [
"도포 부위 자극감 (드묾)",
"피부 얇아짐 - 장기 사용 시"
],
"systemic_if_ingested": [
"다음다뇨 (스테로이드 효과)",
"식욕 증가",
"장기: HPA 축 억제"
]
},
"vs_human_fucidin": {
"can_use_human": false,
"reason_1": "제형 차이: 사람용=크림(털에 흡착), 개시딘=겔(털 통과)",
"reason_2": "pH 차이: 사람 피부 4.5~5.5 vs 개 피부 6.5~8.2",
"reason_3": "농도 차이: 사람용 2% vs 개시딘 0.5%+스테로이드 복합"
},
"clinical_evidence": {
"skin_penetration": "표재성 240μm에서 MIC90의 67,000배 농도 (PMID 29162115)",
"mrsp_coverage": "MRSP 포함 대부분 MIC ≤0.03 mg/L (PMID 25749003)",
"resistance_korea": "한국 S. pseudintermedius 내성률 27% (PMID 32115810)"
},
"available_sizes": [
"5g",
"10g",
"15g",
"20g",
"30g",
"50g",
"100g",
"200g"
],
"storage": "실온 보관, 직사광선 피할 것",
"prescription_required": false,
"pharmacy_counseling": {
"quick_explanation": "개 피부 농피증(세균성 피부병) 치료 겔이에요. 항생제와 소염제가 함께 들어있어 세균도 죽이고 가려움도 줄여줘요.",
"key_points": [
"하루 2번, 환부에만 얇게",
"최소 5일, 최대 7일",
"핥지 못하게 넥칼라 필수",
"3일째 안 좋아지면 병원으로"
],
"common_question": {
"q": "사람 후시딘 써도 되나요?",
"a": "제형이 달라요. 사람용 크림은 개 털에 묻어서 피부에 안 닿아요. 개시딘 겔은 털 사이로 스며들어 피부에 직접 도달해요."
}
},
"references": [
{
"pmid": "29162115",
"title": "Opportunities for topical antimicrobial therapy: permeation of canine skin by fusidic acid",
"key_finding": "퓨시드산 겔 피부 침투: MIC의 67,000배 농도"
},
{
"pmid": "25749003",
"title": "Susceptibility in vitro of canine staphylococcal isolates to fusidic acid",
"key_finding": "MRSP 포함 대부분 MIC ≤0.03 mg/L"
},
{
"pmid": "34414614",
"title": "Influence of age, sex on skin pH in dogs",
"key_finding": "개 피부 pH 4.4~8.2 (사람보다 알칼리성)"
},
{
"pmid": "32115810",
"title": "Fusidic acid resistance in S. pseudintermedius from dogs in Korea",
"key_finding": "한국 퓨시드산 내성률 27%"
}
],
"last_updated": "2026-03-19",
"version": "2.0",
"clinical_notes": [
"개 피부 pH (4.4~8.2)에 최적화된 겔 제형",
"사람용 후시딘과 농도·제형 다름",
"사람용 후시딘과 농도/제형 다름 (동물 피부 pH 최적화)",
"개 피부 pH (4.4~8.2)에 맞춘 겔 제형",
"털 있는 피부 침투에 유리한 겔 타입",
"MRSP(메티실린 내성 포도상구균)에도 효과"
],
"available_sizes": ["5g", "10g", "15g", "20g", "30g", "50g", "100g"],
"storage": "실온 보관"
"pharmacy_tips": {
"human_vs_animal": "사람용 후시딘: 크림제형, 농도 2% / 동물용 개시딘: 겔제형, 농도 0.5%",
"ph_tip": "개 피부 pH는 4.4~8.2로 사람(5.5)보다 넓음. 겔 제형이 털 사이 침투에 유리",
"mrsp_note": "MRSP(메티실린 내성 포도상구균)에도 효과 있음"
}
}

View File

@@ -1,51 +1,74 @@
{
"product_id": "MASTER-005",
"apc_code": "0519-HEARTSAVER",
"apc_code": "0230467230300",
"name": "하트세이버 츄어블",
"english_name": "Heartsaver (Ivermectin + Pyrantel)",
"manufacturer": "중앙바이오텍",
"category": "antiparasitic",
"category_display": "심장사상충 예방",
"target_animal": ["개"],
"target_animal": [
"개"
],
"administration": "경구 (츄어블)",
"indication": "심장사상충 예방 + 회충/구충 구제",
"coverage": {
"external": {
"fleas": {"covered": false, "note": ""},
"ticks": {"covered": false, "note": ""}
"fleas": {
"covered": false,
"note": ""
},
"ticks": {
"covered": false,
"note": ""
}
},
"heartworm": {
"covered": true,
"note": "L3/L4 유충 구제"
},
"intestinal": {
"roundworm": {"covered": true, "note": "회충"},
"hookworm": {"covered": true, "note": "구충"},
"whipworm": {"covered": false, "note": ""},
"tapeworm": {"covered": false, "note": ""}
"roundworm": {
"covered": true,
"note": "회충"
},
"hookworm": {
"covered": true,
"note": "구충"
},
"whipworm": {
"covered": false,
"note": ""
},
"tapeworm": {
"covered": false,
"note": ""
}
}
},
"coverage_summary": {
"covered": ["심장사상충", "회충", "구충"],
"not_covered": ["벼룩", "진드기", "편충", "조충"],
"covered": [
"심장사상충",
"회충",
"구충"
],
"not_covered": [
"벼룩",
"진드기",
"편충",
"조충"
],
"gap_solution": "외부구충: 프로닐스팟 / 편충·조충: 안텔민 추가"
},
"dosing": {
"interval": "매월 1회",
"interval_reason": "심장사상충 윈도우 30일",
"minimum_age": "6주 이상",
"minimum_weight": "제한 없음"
},
"warnings": [
"⚠️ 콜리 품종: MDR1 유전자 확인 필요",
"⚠️ 투약 전 심장사상충 검사 필수",
"⚠️ 감염견에 투약 시 쇼크 위험"
],
"storage": "실온 보관"
}

View File

@@ -1,60 +1,91 @@
{
"product_id": "MASTER-013",
"apc_code": "0232873800003",
"apc_code": "0232873820205",
"name": "임팩트액",
"english_name": "Impact (Imidacloprid + Moxidectin)",
"manufacturer": "제이에스코리아 (애드보킷 제네릭)",
"category": "antiparasitic",
"category_display": "스팟온 복합구충제",
"target_animal": ["개", "고양이", "페렛"],
"target_animal": [
"개",
"고양이",
"페렛"
],
"administration": "경피 도포 (스팟온)",
"indication": "벼룩 + 심장사상충 예방 + 회충 + 구충 + 귀진드기 + 모낭충",
"coverage_summary": {
"covered": ["벼룩", "심장사상충", "회충", "구충", "편충(개)", "귀진드기", "모낭충", "개선충"],
"not_covered": ["진드기", "조충"],
"covered": [
"벼룩",
"심장사상충",
"회충",
"구충",
"편충(개)",
"귀진드기",
"모낭충",
"개선충"
],
"not_covered": [
"진드기",
"조충"
],
"gap_solution": "진드기: 프로닐스팟 추가 / 조충: 안텔민 추가"
},
"dosing": {
"interval": "매월 1회",
"interval_reason": "심장사상충 L3→L5 30일 윈도우",
"minimum_age": "개 7주, 고양이 9주 이상",
"minimum_weight": "제한 없음"
},
"weight_products": [
{"size": "개 XS", "weight_range": "~4kg", "dose": "0.4mL"},
{"size": "개 S", "weight_range": "4~10kg", "dose": "1.0mL"},
{"size": "개 M", "weight_range": "10~25kg", "dose": "2.5mL"},
{"size": "개 L", "weight_range": "25~40kg", "dose": "4.0mL"},
{"size": "고양이 S", "weight_range": "~4kg", "dose": "0.4mL"},
{"size": "고양이 M", "weight_range": "4~8kg", "dose": "0.8mL"}
{
"size": "개 XS",
"weight_range": "~4kg",
"dose": "0.4mL"
},
{
"size": "개 S",
"weight_range": "4~10kg",
"dose": "1.0mL"
},
{
"size": "개 M",
"weight_range": "10~25kg",
"dose": "2.5mL"
},
{
"size": "개 L",
"weight_range": "25~40kg",
"dose": "4.0mL"
},
{
"size": "고양이 S",
"weight_range": "~4kg",
"dose": "0.4mL"
},
{
"size": "고양이 M",
"weight_range": "4~8kg",
"dose": "0.8mL"
}
],
"special_protocols": {
"demodex": "모낭충: 2~4주 간격, 2회 연속 피부검사 음성까지",
"mf_treatment": "마이크로필라리아 치료: 월 1회, 성충구제 후 9개월"
},
"warnings": [
"⚠️ 도포 후 48시간 목욕 금지 (셀라멕틴 2시간과 다름)",
"⚠️ 등 전체 정중선으로 분산 도포 (한 곳 X)",
"⚠️ 도포 부위 마를 때까지 다른 동물과 격리",
"⚠️ 핥으면 신경 증상 가능"
],
"clinical_notes": [
"셀라이트보다 커버 넓음: 구충+편충+모낭충까지",
"진드기 미커버 → 진드기 유행 시 프로닐 추가",
"이미다클로프리드: 접촉 즉시 사멸 (흡혈 전)",
"목시덱틴: 전신 흡수 → 심장사상충·내부기생충"
],
"source": {
"original": "애드보킷 (Advocate®, 엘랑코)"
},
"storage": "직사광선 피하여 서늘한 곳 보관"
}

View File

@@ -1,37 +1,58 @@
{
"product_id": "MASTER-011",
"apc_code": "0232523500007",
"apc_code": "0232523510309",
"name": "멜록시캐시 CH",
"english_name": "Meloxicash (Meloxicam 1mg)",
"manufacturer": "국내",
"category": "nsaid",
"category_display": "진통소염제 (NSAIDs)",
"target_animal": ["개"],
"target_animal": [
"개"
],
"administration": "경구 (츄어블정)",
"indication": "개의 급성·만성 근골격계 질환 통증경감 및 염증 치료",
"mechanism": {
"drug_class": "옥시캄계 NSAIDs",
"action": "COX-2 강선택 억제 → 카프로펜보다 위장관 유리",
"half_life": "~24시간 (1일 1회 투여 가능)"
},
"dosage": {
"standard": "로딩 0.2mg/kg → 유지 0.1mg/kg",
"note": "첫날 2배 용량 → 다음날부터 1일 1회",
"formula": "유지: 10kg당 1정"
},
"dosage_table": [
{"weight": "5kg", "loading": "1.0mg", "tablets": "0.5정"},
{"weight": "10kg", "loading": "2.0mg", "tablets": "1정"},
{"weight": "15kg", "loading": "3.0mg", "tablets": "1.5정"},
{"weight": "20kg", "loading": "4.0mg", "tablets": "2정"},
{"weight": "30kg", "loading": "6.0mg", "tablets": "3정"},
{"weight": "40kg", "loading": "8.0mg", "tablets": "4정"}
{
"weight": "5kg",
"loading": "1.0mg",
"tablets": "0.5정"
},
{
"weight": "10kg",
"loading": "2.0mg",
"tablets": "1정"
},
{
"weight": "15kg",
"loading": "3.0mg",
"tablets": "1.5정"
},
{
"weight": "20kg",
"loading": "4.0mg",
"tablets": "2정"
},
{
"weight": "30kg",
"loading": "6.0mg",
"tablets": "3정"
},
{
"weight": "40kg",
"loading": "8.0mg",
"tablets": "4정"
}
],
"absolute_contraindications": [
{
"item": "다른 NSAIDs 동시 투여 금지",
@@ -46,28 +67,28 @@
"reason": "31일 반복 투여 시 신장 손상 입증 (PMID:41549544)"
}
],
"washout_period": {
"to_other_nsaid": "3~5일",
"to_steroid": "5~7일"
},
"warnings": [
"⚠️ 탈수·저혈압 상태 투여 금지 (신장독성)",
"⚠️ 장기 투여 시 정기 혈액검사 필요",
"⚠️ 구토, 흑색변, 식욕부진 시 즉시 중단",
"✅ 카프로펜보다 COX-2 선택성 높음"
],
"clinical_notes": [
"로딩 용량: 첫날 치료 농도 즉시 달성",
"수술 후 24시간 통증: 로베나콕시브보다 우수 (PMID:30637777)",
"OA 개: 마바콕시브와 동등 효과 (PMID:24859353)"
],
"source": {
"pmid": ["10769766", "24859353", "30637777", "32059002"]
"pmid": [
"10769766",
"24859353",
"30637777",
"32059002"
]
},
"storage": "실온 보관"
}

File diff suppressed because one or more lines are too long

View File

@@ -1,39 +1,36 @@
{
"product_id": "MASTER-007",
"apc_code": "0519-ORIDERMYL",
"apc_code": "0231065620103",
"name": "오리더밀",
"english_name": "Oridermyl (Nystatin+Neomycin+Triamcinolone)",
"manufacturer": "TVM",
"category": "otic",
"category_display": "귀염증 치료제",
"target_animal": ["개", "고양이"],
"target_animal": [
"개",
"고양이"
],
"administration": "점이 (귀에 투약)",
"indication": "외이염, 귀진드기 감염, 세균성/진균성 귀감염",
"mechanism": {
"nystatin": "항진균 (칸디다, 말라세지아)",
"neomycin": "항균 (그람음성균)",
"triamcinolone": "항염증 (가려움, 부종 완화)",
"permethrin": "귀진드기 구제"
},
"dosage": {
"standard": "1일 1~2회",
"amount": "귀당 5~10방울",
"duration": "7~14일"
},
"warnings": [
"⚠️ 고막 천공 시 사용 금지",
"⚠️ 투약 전 귀 세정 권장",
"⚠️ 장기 사용 시 내성균 주의"
],
"contraindications": [
"고막 천공/손상",
"아미노글리코사이드 과민증"
],
"storage": "실온 보관"
}

View File

@@ -1,69 +1,119 @@
{
"product_id": "MASTER-010",
"apc_code": "0519-SELIGHT",
"apc_code": "0232545420203",
"name": "셀라이트",
"english_name": "Selight (Selamectin)",
"manufacturer": "국내산 (레볼루션 제네릭)",
"category": "antiparasitic",
"category_display": "스팟온 종합구충제",
"target_animal": ["개", "고양이"],
"target_animal": [
"개",
"고양이"
],
"administration": "경피 도포 (스팟온)",
"indication": "심장사상충 예방 + 벼룩 + 귀진드기 + 개선충(옴) + 회충 + 이 + 참진드기(개)",
"coverage_summary": {
"covered": ["심장사상충", "벼룩", "귀진드기", "개선충", "회충", "이", "진드기(개)"],
"not_covered": ["조충(촌충)", "편충", "구충(개)"],
"covered": [
"심장사상충",
"벼룩",
"귀진드기",
"개선충",
"회충",
"이",
"진드기(개)"
],
"not_covered": [
"조충(촌충)",
"편충",
"구충(개)"
],
"gap_solution": "안텔민 3개월마다 보조 투약 (조충·편충 보완)"
},
"dosing": {
"interval": "매월 1회",
"interval_reason": "심장사상충 L3→L5 전환 30일 윈도우 + 벼룩 라이프사이클",
"minimum_age": "6주 이상",
"minimum_weight": "제한 없음"
},
"weight_products": [
{"size": "SS", "weight_range": "~2.5kg", "dose": "0.25mL (15mg)"},
{"size": "S", "weight_range": "2.5~5kg", "dose": "0.5mL (30mg)"},
{"size": "M", "weight_range": "5~10kg", "dose": "0.5mL (60mg)"},
{"size": "L", "weight_range": "10~20kg", "dose": "1.0mL (120mg)"},
{"size": "XL", "weight_range": "20~40kg", "dose": "2.0mL (240mg)"}
{
"size": "SS",
"weight_range": "~2.5kg",
"dose": "0.25mL (15mg)"
},
{
"size": "S",
"weight_range": "2.5~5kg",
"dose": "0.5mL (30mg)"
},
{
"size": "M",
"weight_range": "5~10kg",
"dose": "0.5mL (60mg)"
},
{
"size": "L",
"weight_range": "10~20kg",
"dose": "1.0mL (120mg)"
},
{
"size": "XL",
"weight_range": "20~40kg",
"dose": "2.0mL (240mg)"
}
],
"special_protocols": {
"tick_intensive": "진드기 집중: 2주 간격 3회 → 이후 월 1회",
"sarcoptes": "옴 치료: Day 0 + Day 30 (2회)",
"ear_mite_cat": "귀진드기(고양이): 단일 도포 (100%)",
"ear_mite_dog": "귀진드기(개): Day 0 + Day 30 (2회 - 이도 깊음)"
},
"efficacy_data": [
{"target": "심장사상충", "efficacy": "100%", "source": "PMID:10940527"},
{"target": "벼룩(C.felis)", "efficacy": "≥98.9%", "source": "PMID:10940521"},
{"target": "귀진드기(고양이)", "efficacy": "94~100%", "source": "PMID:10940530"},
{"target": "개선충(옴)", "efficacy": "100% (Day60)", "source": "PMID:10940530"}
{
"target": "심장사상충",
"efficacy": "100%",
"source": "PMID:10940527"
},
{
"target": "벼룩(C.felis)",
"efficacy": "≥98.9%",
"source": "PMID:10940521"
},
{
"target": "귀진드기(고양이)",
"efficacy": "94~100%",
"source": "PMID:10940530"
},
{
"target": "개선충(옴)",
"efficacy": "100% (Day60)",
"source": "PMID:10940530"
}
],
"warnings": [
"⚠️ 6주 미만 사용 금지",
"⚠️ 도포 후 2시간 이후 목욕 가능",
"⚠️ 피부 상처 부위 도포 금지",
"✅ 콜리 품종 안전 (PMID:10940536 확인)"
],
"clinical_notes": [
"레볼루션(Zoetis) 국내산 제네릭 - 동일 성분·동일 효능",
"개+고양이 겸용 (체중별 제품 선택)",
"조충·편충 미커버 → 안텔민 병행 필요",
"도포 후 건조될 때까지 다른 동물이 핥지 않도록"
],
"source": {
"guidelines": ["AHS 2024", "ESCCAP GL5 2024", "CAPC 2024"],
"pmid": ["10940527", "10940521", "10940530", "10940536"]
"guidelines": [
"AHS 2024",
"ESCCAP GL5 2024",
"CAPC 2024"
],
"pmid": [
"10940527",
"10940521",
"10940530",
"10940536"
]
},
"storage": "직사광선 피하여 서늘한 곳 보관"
}

View File

@@ -1,23 +1,22 @@
{
"product_id": "MASTER-004",
"apc_code": "0519-SERENIA",
"apc_code": "0231884620107",
"name": "세레니아 정",
"english_name": "Serenia (Maropitant citrate)",
"manufacturer": "조에티스 (Zoetis)",
"category": "antiemetic",
"category_display": "항구토제",
"target_animal": ["개", "고양이"],
"target_animal": [
"개",
"고양이"
],
"administration": "경구 (정제)",
"image_url": "/images/serenia.png",
"indication": "급성 구토, 멀미(차멀미) 예방 및 치료",
"mechanism": {
"drug_class": "NK1 수용체 길항제",
"action": "구토중추의 NK1 수용체 차단 → 구토 억제",
"feature": "중추 및 말초 모두 작용"
},
"dosage": {
"acute_vomiting": {
"dose": "2mg/kg 1일 1회",
@@ -29,43 +28,66 @@
"note": "공복 상태 권장 (효과 향상)"
}
},
"dosage_table": [
{"weight": "3kg", "acute": "6mg", "motion": "24mg"},
{"weight": "5kg", "acute": "10mg", "motion": "40mg"},
{"weight": "10kg", "acute": "20mg", "motion": "80mg"},
{"weight": "15kg", "acute": "30mg", "motion": "120mg"},
{"weight": "20kg", "acute": "40mg", "motion": "160mg"}
{
"weight": "3kg",
"acute": "6mg",
"motion": "24mg"
},
{
"weight": "5kg",
"acute": "10mg",
"motion": "40mg"
},
{
"weight": "10kg",
"acute": "20mg",
"motion": "80mg"
},
{
"weight": "15kg",
"acute": "30mg",
"motion": "120mg"
},
{
"weight": "20kg",
"acute": "40mg",
"motion": "160mg"
}
],
"available_strengths": [
"16mg",
"24mg",
"60mg",
"160mg"
],
"available_strengths": ["16mg", "24mg", "60mg", "160mg"],
"warnings": [
"⚠️ 16주(4개월) 미만 강아지 금지",
"⚠️ 고양이: 급성 구토에만 사용 (멀미 적응증 없음)",
"⚠️ 5일 이상 연속 투여 금지 (급성 구토)",
"⚠️ 차멀미 예방 시 공복 상태에서 효과적"
],
"contraindications": [
"16주 미만 강아지",
"위장관 폐색 의심 시 (구토 억제가 위험)",
"독소 섭취 후 (구토 유도 필요 시)"
],
"side_effects": {
"common": ["침흘림 (일시적)", "무기력"],
"rare": ["설사", "식욕부진"]
"common": [
"침흘림 (일시적)",
"무기력"
],
"rare": [
"설사",
"식욕부진"
]
},
"clinical_notes": [
"구토 원인 파악 필수 (단순 증상 억제 아님)",
"위장관 폐색, 독소 섭취 시에는 구토 유도가 필요할 수 있음",
"멀미 예방: 이동 2시간 전 + 공복 = 최대 효과"
],
"storage": "실온 보관",
"source": {
"product_info": "Zoetis Serenia Product Information",
"notes": "FDA 승인 수의용 항구토제"

View File

@@ -1,6 +1,6 @@
{
"product_id": "MASTER-019",
"apc_code": "0519-SIMPARICA",
"apc_code": "0232571730106",
"name": "심파리카 트리오",
"english_name": "Simparica Trio (Sarolaner+Moxidectin+Pyrantel)",
"manufacturer": "조에티스 (Zoetis)",

View File

@@ -1,38 +1,35 @@
{
"product_id": "MASTER-008",
"apc_code": "0519-TERBIDERM",
"apc_code": "0232064110102",
"name": "터비덤 스프레이",
"english_name": "Terbiderm (Terbinafine)",
"manufacturer": "동방동물약품",
"category": "antifungal",
"category_display": "항진균제 (피부)",
"target_animal": ["개", "고양이"],
"target_animal": [
"개",
"고양이"
],
"administration": "외용 (스프레이)",
"indication": "피부사상균증 (백선), 말라세지아 피부염",
"mechanism": {
"drug_class": "알릴아민계 항진균제",
"action": "스쿠알렌 에폭시다제 억제 → 진균 세포막 합성 차단"
},
"dosage": {
"frequency": "1일 1~2회",
"duration": "2~4주 (완치 후 1주 추가)",
"application": "병변 및 주변 2cm까지 도포"
},
"warnings": [
"⚠️ 눈, 점막 접촉 피할 것",
"⚠️ 핥지 못하게 엘리자베스 칼라 권장",
"⚠️ 경구 항진균제 병용 시 효과 증가"
],
"clinical_notes": [
"피부사상균 배양 검사 권장 (치료 전)",
"환경 소독 병행 필수 (재감염 방지)",
"장모종은 병변 주변 제모 권장"
],
"storage": "실온 보관, 화기 주의"
}

View File

@@ -1,50 +1,393 @@
{
"product_id": "MASTER-015",
"apc_code": "0231089400001",
"apc_code": "0231089420409",
"name": "티어가드 정",
"english_name": "TierGard (Tylosin tartrate)",
"manufacturer": "국내",
"name_meaning": "Tier(동물) + Guard(보호) — 동물 안구·피부 감염 보호",
"manufacturer": "(주)이엘티사이언스",
"country": "한국",
"global_status": "한국 독자 허가 제품 (글로벌 개용 60mg 정제 시판 없음)",
"approval_date": "2013-03-20",
"approval_number": "159",
"category": "antibiotic",
"category_display": "항생제 (마크롤라이드계)",
"target_animal": ["개"],
"target_animal": [
"개"
],
"administration": "경구 (정제)",
"indication": "결막염, 눈물 자국(세균성), 농피증 치료",
"indication": "포도상구균·연쇄상구균에 의한 결막염, 농피증 치료",
"mechanism": {
"drug_class": "마크롤라이드계 항생제 (16원환)",
"action": "세균 50S 리보솜 결합 → 단백 합성 억제",
"spectrum": "포도상구균, 연쇄상구균, 마이코플라즈마"
"drug_class": "마크롤라이드계 항생제 (16원환 Macrolide)",
"action": "세균 50S 리보솜 결합 → 단백 합성 억제 → 정균 작용",
"spectrum": {
"covered": [
"Staphylococcus pseudintermedius",
"Staphylococcus aureus",
"Streptococcus spp.",
"Mycoplasma spp."
],
"not_covered": [
"Pseudomonas aeruginosa",
"E. coli",
"Proteus spp.",
"진균류"
],
"susceptibility_rate": "82.61% (항생제 미노출 S. pseudintermedius, PMID: 20960412)"
},
"dosage": {
"standard": "10~20mg/kg 1일 2회",
"duration": "4주간",
"note": "소형견(말티즈·비숑) 주 사용"
"tear_staining_mechanism": {
"description": "세균성 분비물 감소 + 마크롤라이드 항염증 효과 복합 작용",
"pathway": [
"내안각·결막 세균 (S. pseudintermedius, Mycoplasma 등)",
"타일로신 → 세균 50S 리보솜 결합 → 단백 합성 억제",
"세균 부하 감소",
"결막·비루관 주변 만성 염증 감소 + 세균성 분비물 감소",
"눈물관 주변 환경 개선",
"포르피린 착색 유발 삼출물 감소",
"눈물 자국 완화 (수주 이상 소요)"
],
"limitation": "이미 착색된 털은 항생제로 탈색 불가 — 새 털이 자라면서 교체됨"
},
"dosage_table": [
{"weight": "2kg", "dose": "40mg", "tablets": "20mg × 2정"},
{"weight": "3kg", "dose": "60mg", "tablets": "60mg × 1정"},
{"weight": "5kg", "dose": "100mg", "tablets": "60mg × 1.7정"},
{"weight": "10kg", "dose": "200mg", "tablets": "200mg × 1정"},
{"weight": "15kg", "dose": "300mg", "tablets": "200mg × 1.5정"}
],
"available_strengths": ["20mg", "60mg", "200mg"],
"warnings": [
"⚠️ 세균성 원인에만 효과 (구조적·알레르기성 X)",
"⚠️ 비루관 협착 시 수술/시술 필요",
"⚠️ 4주 이상 투여 시 내성균 주의"
],
"clinical_notes": [
"눈물 자국: 세균 부하 감소 → 염증 감소 → 완화",
"포르피린 착색: 햇빛 노출 시 더 진해짐",
"구조적 원인 먼저 교정해야 효과 극대화",
"흰 털 품종(말티즈, 비숑)에서 눈물 자국 두드러짐"
],
"storage": "실온 보관"
"porphyrin_explanation": {
"what": "혈액 속 헤모글로빈의 헴(heme) 합성 과정에서 생성되는 대사산물",
"why_staining": "눈물에 과도하게 분비되면 흰 털에 갈색-적갈색 얼룩",
"why_darkens": "빛(자외선)에 노출되면 산화되어 색이 짙어짐",
"note": "포르피린 자체는 무해하나 미용적으로 문제"
}
},
"dosage": {
"standard": "20mg/kg (타일로신 기준)",
"approved_range": "10~20mg/kg (한국 허가사항)",
"confirmed_dose": "20mg/kg bid (임상 근거 확정)",
"frequency": "1일 2회 (12시간 간격)",
"duration": "4주 (한국 허가사항)",
"with_food": "권장 (위장관 자극 최소화)",
"note": "반감기 54분으로 짧아 1일 2회 투여 필수"
},
"dosage_table": [
{
"weight": "2kg",
"dose": "40mg",
"tablets": "20mg × 2정"
},
{
"weight": "3kg",
"dose": "60mg",
"tablets": "60mg × 1정",
"breed_example": "말티즈·요크셔"
},
{
"weight": "5kg",
"dose": "100mg",
"tablets": "60mg × 1.5~2정",
"breed_example": "푸들·비숑"
},
{
"weight": "6kg",
"dose": "120mg",
"tablets": "60mg × 2정",
"breed_example": "시추·페키니즈"
},
{
"weight": "9kg",
"dose": "180mg",
"tablets": "60mg × 3정",
"breed_example": "코커스패니얼"
},
{
"weight": "10kg",
"dose": "200mg",
"tablets": "200mg × 1정",
"note": "중형견 경계"
},
{
"weight": "15kg",
"dose": "300mg",
"tablets": "200mg × 1.5정"
},
{
"weight": "20kg",
"dose": "400mg",
"tablets": "200mg × 2정"
}
],
"available_strengths": [
"20mg",
"60mg",
"200mg"
],
"strength_recommendation": {
"small_dog": "60mg 정이 가장 실용적 (3~6kg 소형견)",
"medium_large": "10kg 이상은 200mg 정 전환 권장"
},
"treatment_timeline": {
"description": "효과가 나타나는 시기 (눈물자국 기준)",
"phases": [
{
"week": "1~2주",
"expected": "결막 충혈·분비물 감소 (세균성인 경우)"
},
{
"week": "2~3주",
"expected": "눈물 분비량 감소 시작"
},
{
"week": "4주",
"expected": "눈물 자국 색이 옅어지기 시작"
},
{
"week": "4주 이후",
"expected": "새 털이 자라면서 착색 털 교체 (트리밍 병행)"
}
],
"realistic_expectation": "효과를 눈으로 확인하려면 최소 4~8주 소요",
"important_note": "이미 착색된 털은 항생제로 탈색되지 않음"
},
"follow_up_points": {
"description": "4주 복용 후 경과 관찰 포인트",
"checkpoints": [
{
"timing": "2주차",
"items": [
"병변 면적 감소 확인",
"눈물 분비량 변화",
"새 병변 발생 여부"
]
},
{
"timing": "4주차",
"items": [
"완치 여부 판단",
"추가 연장 필요성 결정",
"착색 털 트리밍 권고"
]
},
{
"timing": "치료 완료 후",
"items": [
"근본 원인(알레르기·구조적) 교정 여부 확인",
"재발 모니터링"
]
}
],
"treatment_failure_signs": [
"2주 투여 후 뚜렷한 개선 없음 → 감수성 재검",
"반복 재발 (3개월 내) → 원인 감별 + 배양 검사",
"MRSP 의심 → 다약제 내성 확인"
]
},
"relapse_prevention": {
"description": "재발 방지 관리법",
"daily_care": [
{
"action": "외안각 세정",
"detail": "매일 생리식염수나 안과용 세정제로 내안각(눈물 고이는 부분) 닦기"
},
{
"action": "물 관리",
"detail": "정수 또는 생수 사용 (철분 포함 수돗물은 포르피린 착색 악화 가능)"
},
{
"action": "미용 관리",
"detail": "착색된 털은 정기적으로 트리밍"
}
],
"dietary_management": {
"principle": "알레르기 원인 제거",
"recommendation": "첨가물 없는 단순 식이로 변경 검토"
},
"root_cause_correction": {
"importance": "근본 원인 미교정 시 치료 중단 후 재발 빈번",
"causes_to_address": [
"비루관 협착",
"삼모증",
"안검 내번",
"알레르기"
],
"warning": "마크롤라이드 100일 이상 장기 투여 시 내성균 선택 위험 (PMID: 32109782)"
},
"relapse_rate": "28.6% (3개월 내, PMID: 7994702)"
},
"concurrent_treatments": {
"description": "병행 시술 안내",
"structural_causes": {
"conditions": [
"비루관 협착·폐쇄",
"속눈썹 이상(삼모증)",
"안검 내번"
],
"treatment": "수의안과 전문 처치/수술 필요",
"note": "구조적 원인은 항생제로 해결 불가"
},
"nasolacrimal_flushing": {
"description": "비루관 세척",
"purpose": "비루관 협착 예방 및 눈물 배출 개선",
"frequency": "수의사가 주기적으로 시행",
"when_needed": "비루관 폐쇄 의심 시, 반복적 눈물 과다 시"
},
"topical_treatments": {
"eye_cleaning": "안과용 세정제로 외안부 세정 병행",
"note": "전신 항생제 + 국소 관리 병행 시 효과 극대화"
}
},
"tear_staining_info": {
"description": "눈물자국(Tear Staining) 상세 정보",
"causes_multifactorial": {
"bacterial": {
"role": "내안각 만성 세균 감염 → 분비물 증가",
"tylosin_helps": true
},
"structural": {
"conditions": [
"비루관 협착·폐쇄",
"삼모증",
"안검 내번"
],
"tylosin_helps": false,
"treatment": "수술/시술 필요"
},
"allergic": {
"conditions": [
"음식 알레르기",
"환경 알레르기"
],
"tylosin_helps": false,
"treatment": "원인 제거 필요"
},
"dietary": {
"issue": "포르피린 전구체 함유 식품 과다",
"tylosin_helps": false
},
"breed_predisposition": {
"issue": "단두형 안구 돌출, 얕은 안와",
"tylosin_helps": false,
"note": "해부학적 한계"
}
},
"high_risk_breeds": [
{
"breed": "말티즈",
"reason": "흰 털 + 비루관 저형성 빈번"
},
{
"breed": "비숑 프리제",
"reason": "흰 털 + 내안각 삼모증"
},
{
"breed": "토이·미니어처 푸들",
"reason": "흰 털 개체에서 두드러짐"
},
{
"breed": "시추",
"reason": "안검불완전폐쇄 82%, 삼모증 100%, TBUT 4초"
},
{
"breed": "퍼그·페키니즈·불독",
"reason": "단두형 안구 돌출"
}
],
"key_message": "타일로신은 세균성 원인에만 작용. 구조적·알레르기성 원인 먼저 교정해야 효과 극대화"
},
"pharmacokinetics": {
"t_half": "54분 (IV, 개)",
"Vd": "1.7-2.0 L/kg (높음 → 조직 침투 우수)",
"primary_excretion": "담즙 (간→장), bile/serum ratio 1,230-3,780",
"renal_excretion": "극소량",
"accumulation": "없음 (29일, 2년 투여 확인)",
"bioavailability_im": "92.6%",
"clinical_implication": "반감기 매우 짧아 1일 2회 투여 필수"
},
"safety": {
"NOAEL_dog_2yr": "100 mg/kg/day",
"LD50_dog_oral": ">800 mg/kg",
"clinical_dose": "40 mg/kg/day (20mg/kg bid)",
"safety_margin": "2.5배 (NOAEL/임상용량)",
"liver_burden": "주 대사·배설 경로이나 100mg/kg/day까지 중대한 간 손상 없음",
"kidney_burden": "신장 배설 극소량 → 부담 매우 낮음",
"gi_side_effect": "일과성 위염 3.3% (30마리 중 1마리)",
"long_term_risk": "100일 이상 투여 시 마크롤라이드 내성균 선택 위험"
},
"warnings": [
"⚠️ 세균성 원인에만 효과 (구조적·알레르기성 원인은 별도 처치 필요)",
"⚠️ 비루관 협착 시 수술/시술 필요 — 항생제로 해결 불가",
"⚠️ 이미 착색된 털은 탈색 불가 — 트리밍으로 제거",
"⚠️ 4주 이상 장기 투여 시 내성균 주의",
"⚠️ 식사와 함께 투여 (공복 시 위장관 자극 가능)"
],
"contraindications": [
"❌ 마크롤라이드계 항생제 과민반응·쇼크 병력",
"❌ 린코사마이드계 항생제(린코마이신·클린다마이신) 동시 투여",
"❌ 다른 마크롤라이드 동시 투여",
"❌ 고양이 (개 전용 제품)",
"⚠️ 임신·수유 중 암캐 — 수의사 상담 후 결정"
],
"clinical_notes": [
"눈물 자국: 세균 부하 감소 → 염증 감소 → 분비물 감소 → 완화",
"포르피린 착색: 햇빛 노출 시 더 진해짐 (실내견보다 야외 활동 많은 개에서 더 진함)",
"구조적 원인 먼저 교정해야 효과 극대화",
"흰 털 품종(말티즈, 비숑)에서 눈물 자국 두드러짐",
"한국 독자 허가 — 글로벌에 개용 60mg 정제 없음"
],
"patient_education_qa": [
{
"q": "왜 눈 밑이 갈색으로 얼룩져 있나요?",
"a": "눈물에 포르피린이라는 물질이 포함되어 있어요. 눈물이 흘러넘치면 털에 쌓이고, 빛에 의해 산화되면서 갈색으로 변합니다."
},
{
"q": "티어가드를 먹이면 눈물 자국이 없어지나요?",
"a": "이미 생긴 자국은 사라지지 않습니다. 세균성 원인을 억제해서 새로 자라는 털에 자국이 덜 생기게 합니다. 기존 착색 털은 트리밍으로 제거하세요."
},
{
"q": "효과는 언제 나타나나요?",
"a": "1~2주: 분비물 감소, 2~4주: 눈물량 감소, 4~8주: 새 털에서 자국 감소. 눈으로 확인하려면 최소 4~8주 소요됩니다."
},
{
"q": "4주 먹였는데 효과가 없어요",
"a": "두 가지를 확인하세요: 1) 구조적 원인(비루관 협착, 삼모증) → 수의안과 진찰 필요, 2) 타일로신 내성균 → 세균 배양·감수성 검사"
},
{
"q": "재발을 막으려면 계속 먹여야 하나요?",
"a": "근본 원인 미교정 시 재발합니다. 장기 투여(100일+)는 내성 위험이 있어 권장하지 않습니다. 일상 관리(외안각 세정, 물 관리, 트리밍)와 근본 원인 교정이 장기 해결책입니다."
},
{
"q": "간이나 신장에 부담이 큰 약인가요?",
"a": "담즙으로 배설되며 신장 부담은 매우 낮습니다. 2년 장기 시험에서 임상 용량의 2.5배까지 중대한 손상 없었습니다. 4주 투여 범위에서 안전합니다."
}
],
"references": {
"korean_approval": "APDB 허가사항 (APC: 0231089400001, 허가번호: 159, 2013-03-20)",
"clinical_efficacy": [
"Scott et al. 1994 (PMID: 7994702) — 농피증 90.5% 성공률, n=21",
"Harvey 1996 (PMID: 8873399) — 표재성 농피증 80%, n=30",
"Scott BA et al. 2010 (PMID: 20960412) — In vitro 감수성 82.61%, n=103"
],
"pk_safety": [
"Weisel et al. 1977 (PMID: 842925) — PK: t½ 54분, Vd 1.7L/kg",
"Kim et al. 2011 (PMID: 21068517) — IM 생체이용률 92.6%",
"JECFA/WHO 1991 — 개 2년 독성시험, NOAEL 100mg/kg/day"
],
"pathogen_data": [
"Murphy et al. 1978 (PMID: 624664) — 결막염 원인균 (S. aureus 68%)",
"Casemiro et al. 2025 (PMID: 38768284) — 각막염 병원체",
"Cooper et al. 1993 (PMID: 8393208) — Mycoplasma 탁월한 활성"
],
"resistance_data": [
"Kang et al. 2014 (PMID: 24690601) — 한국 MRSP 36%",
"Cazer et al. 2020 (PMID: 32109782) — 100일+ 투여 시 내성 증가"
],
"tear_staining": [
"Sebbag & Sanchez 2023 (PMID: 36585820) — 단두형 안구 증후군 총설"
]
},
"storage": "실온 보관, 직사광선 피함",
"last_updated": "2026-03-19",
"version": "2.0",
"source_documents": [
"tiergard_tylosin_conjunctivitis_tearstain_v3.md",
"tiergard_tylosin_pyoderma_v2.md"
],
"indication_detail": {
"primary": "포도상구균·연쇄상구균에 의한 결막염, 농피증 치료",
"secondary": "세균성 눈물자국(tear staining) 완화 보조",
"note": "눈물자국 직접 치료 RCT 없음. 세균성 원인 있는 경우 임상적으로 사용됨."
}
}

View File

@@ -0,0 +1,347 @@
# 동물약 투약지도서 API - AI 매핑 아키텍처
> 작성일: 2026-03-19
> 작성자: 용림 🐉
---
## 1. 문제 정의
### 현재 상황
```
약국 POS (PIT3000)
└─ DrugCode: LB000003158
└─ GoodsName: "안텔민뽀삐(5kg이하)"
└─ BARCODE: 9990000001134 (자체 바코드) ❌ APC 아님
└─ CD_ITEM_UNIT_MEMBER
└─ 0230237010107 (APC) ✅ 있으면 좋음
└─ 9990000001134 (자체) ← 이것만 있는 경우 多
```
### 핵심 문제
| 상황 | 비율 | 처리 방법 |
|------|------|----------|
| APC 매핑 완료 | ~18% (17건) | APC로 바로 조회 ✅ |
| APC 미매핑 | ~82% (32건+) | **제품명 기반 AI 매핑 필요** ⚠️ |
### 왜 어려운가?
1. **약국마다 바코드 체계 다름**
- A약국: "안텔민사향" → 바코드 "A001"
- B약국: "안텔민사향" → 바코드 "B999"
- C약국: "안텔민사향" → 바코드 없음 (수기 입력)
2. **제품명 표기 불일치**
- POS: "안텔민뽀삐(5kg이하)"
- APDB: "뉴펫 안텔민 정사 정 100mg/25mg/10정"
- 쇼핑몰: "안텔민 뽀삐 5kg이하"
3. **사이즈/용량 구분**
- 하트세이버 mini/S/M/L → 각각 다른 APC
- 넥스가드 XS/S/M/L → 각각 다른 APC
---
## 2. 제안 아키텍처
### 2.1 전체 흐름
```
┌─────────────────────────────────────────────────────────────┐
│ API 요청 │
│ { │
│ "items": [ │
│ { "apc": "0230237010107", "name": "안텔민뽀삐" }, │ ← APC 있음
│ { "apc": null, "name": "하트세이버S(5.6~11kg)" } │ ← APC 없음
│ ], │
│ "patient_name": "김남곤", │
│ "pet_name": "뽀삐" │
│ } │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 매핑 분기 처리 │
├─────────────────────────────────────────────────────────────┤
│ │
│ for each item: │
│ if item.apc exists: │
│ ──────────────────▶ [직접 조회] │
│ else: │
│ ──────────────────▶ [AI 매핑 레이어] │
│ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ PDF 렌더링 │
│ │
│ 매핑된 APC들로 APDB 조회 → 템플릿 렌더링 → PDF 반환 │
└─────────────────────────────────────────────────────────────┘
```
### 2.2 AI 매핑 레이어 상세
```
┌─────────────────────────────────────────────────────────────┐
│ AI 매핑 레이어 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 입력: "하트세이버S(5.6~11kg)" │
│ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ Step 1: 정규화 (Normalize) │ │
│ │ - 공백/특수문자 정리 │ │
│ │ - 체중 정보 추출: 5.6~11kg → S사이즈 │ │
│ │ - 브랜드 추출: "하트세이버" │ │
│ └───────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ Step 2: 후보 검색 (Candidate Search) │ │
│ │ - PostgreSQL 퍼지 매칭 │ │
│ │ - 벡터 유사도 검색 (선택적) │ │
│ │ │ │
│ │ 결과: [ │ │
│ │ { apc: "0230474210202", name: "하트세이버S", score: 0.95 }, │
│ │ { apc: "0230474220200", name: "하트세이버M", score: 0.72 }, │
│ │ { apc: "0230470000008", name: "하트세이버mini", score: 0.68 }│
│ │ ] │ │
│ └───────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ Step 3: AI 최종 선택 (LLM Decision) │ │
│ │ │ │
│ │ 프롬프트: │ │
│ │ "POS 제품명: 하트세이버S(5.6~11kg) │ │
│ │ 후보 APC: │ │
│ │ 1. 0230474210202 - 하트세이버S (5.6~11kg) │ │
│ │ 2. 0230474220200 - 하트세이버M (12~22kg) │ │
│ │ 3. 0230470000008 - 하트세이버mini (5.6kg이하) │ │
│ │ │ │
│ │ 가장 적합한 APC는?" │ │
│ │ │ │
│ │ AI 응답: "0230474210202" (체중 범위 일치) │ │
│ └───────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ Step 4: 캐싱 (선택적) │ │
│ │ - 동일 제품명 재요청 시 캐시 사용 │ │
│ │ - Redis 또는 SQLite │ │
│ └───────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
```
---
## 3. 구현 옵션 비교
### 옵션 A: 규칙 기반 매핑 (No AI)
```python
def match_by_rules(product_name):
# 정규식 + 키워드 매칭
if "안텔민" in product_name:
if "뽀삐" in product_name or "5kg이하" in product_name:
return "0230237010107"
elif "" in product_name or "5kg이상" in product_name:
return "0230237810109"
# ... 수십 개 규칙
```
| 장점 | 단점 |
|------|------|
| 빠름, 비용 0 | 유지보수 지옥 |
| 예측 가능 | 새 제품 대응 불가 |
| | 표기 변형에 취약 |
**적합**: 제품 수 적고, 변동 없을 때
---
### 옵션 B: 퍼지 매칭 + 점수 기반
```python
from rapidfuzz import fuzz
def match_by_fuzzy(product_name, candidates):
scores = []
for c in candidates:
score = fuzz.token_sort_ratio(product_name, c['name'])
scores.append((c['apc'], score))
best = max(scores, key=lambda x: x[1])
if best[1] > 80: # 임계값
return best[0]
return None # 매칭 실패
```
| 장점 | 단점 |
|------|------|
| AI 비용 없음 | 체중/사이즈 구분 어려움 |
| 빠름 | 애매한 경우 오매핑 |
**적합**: 1:1 매핑이 명확한 경우
---
### 옵션 C: AI 하이브리드 (권장) ⭐
```python
def match_hybrid(product_name):
# 1. 캐시 확인
cached = cache.get(product_name)
if cached:
return cached
# 2. 퍼지 매칭으로 후보 추림
candidates = fuzzy_search(product_name, limit=5)
# 3. 고신뢰 매칭이면 바로 반환
if candidates[0]['score'] > 95:
return candidates[0]['apc']
# 4. 애매하면 AI 판단
if candidates[0]['score'] > 70:
apc = llm_decide(product_name, candidates)
cache.set(product_name, apc)
return apc
# 5. 전혀 못 찾으면 실패
return None
```
| 장점 | 단점 |
|------|------|
| 정확도 높음 | AI 비용 (캐싱으로 최소화) |
| 새 제품 대응 가능 | 초기 구축 복잡 |
| 체중/사이즈 정확 구분 | |
**적합**: 현재 상황 (다양한 표기, 사이즈 구분 필요)
---
## 4. 비용 분석
### AI 호출 비용 (GPT-4o-mini 기준)
| 시나리오 | 월 요청 | AI 호출률 | AI 호출 수 | 비용 |
|----------|---------|----------|-----------|------|
| 소규모 | 100건 | 30% | 30건 | ~$0.01 |
| 중규모 | 1,000건 | 20% | 200건 | ~$0.10 |
| 대규모 | 10,000건 | 10% | 1,000건 | ~$0.50 |
**캐싱 효과**: 동일 제품명 재요청 시 AI 호출 안 함 → 호출률 급감
---
## 5. 내 생각 (용림)
### 현실적인 접근
1. **Phase 1: 규칙 기반 시작**
- 현재 17건의 APC 매핑된 제품은 직접 조회
- 자주 쓰는 10~20개 제품은 수동 규칙 추가
- 나머지는 "매핑 실패" 로깅
2. **Phase 2: 퍼지 매칭 도입**
- PostgreSQL `pg_trgm` 확장으로 유사도 검색
- 95% 이상 매칭은 자동 처리
- 70~95%는 로깅 + 수동 검토
3. **Phase 3: AI 레이어 추가**
- 70~95% 구간에 LLM 판단 도입
- 판단 결과 캐싱
- 오매핑 피드백 루프
### 왜 AI가 필요한가?
```
POS: "하트세이버츄어블S(5.6~11kg)"
APDB: "뉴펫 하트세이버 츄어블 소형견용 5.6-11kg"
→ 퍼지 매칭만으로는 "소형견용 = S" 판단 어려움
→ 체중 범위 파싱 + 의미 이해 필요
→ LLM이 "5.6~11kg"와 "5.6-11kg" 같다고 판단 가능
```
### 우선순위 제안
| 순위 | 항목 | 이유 |
|------|------|------|
| 1 | APC 직접 매핑 확대 | 가장 정확, 비용 0 |
| 2 | 캐시 레이어 | AI 비용 절감 |
| 3 | 퍼지 매칭 | AI 호출 최소화 |
| 4 | AI 최종 판단 | 애매한 케이스만 |
---
## 6. API 인터페이스 (안)
### 요청
```json
POST /api/guide/pdf
{
"items": [
{
"apc": "0230237010107",
"name": "안텔민뽀삐",
"drugcode": "LB000003158"
},
{
"apc": null,
"name": "하트세이버S(5.6~11kg)",
"drugcode": "LB000003153"
}
],
"patient_name": "김남곤",
"pet_name": "뽀삐",
"pet_species": "푸들",
"pet_age": "3세"
}
```
### 응답
```json
{
"success": true,
"pdf_url": "/output/guide_20260319_abc123.pdf",
"mapping_results": [
{
"name": "안텔민뽀삐",
"apc": "0230237010107",
"method": "direct",
"confidence": 1.0
},
{
"name": "하트세이버S(5.6~11kg)",
"apc": "0230474210202",
"method": "ai_matched",
"confidence": 0.92,
"candidates_considered": 3
}
]
}
```
---
## 7. 다음 단계
- [ ] APDB 퍼지 검색 인덱스 구축 (`pg_trgm`)
- [ ] AI 매핑 프롬프트 설계
- [ ] 캐시 레이어 (Redis/SQLite)
- [ ] 매핑 실패 로깅 & 대시보드
- [ ] 피드백 루프 (오매핑 수정)
---
*이 문서는 논의용입니다. 피드백 주세요!* 🐉

226
docs/API_SPEC.md Normal file
View File

@@ -0,0 +1,226 @@
# 애니팜 투약지도서 API 명세서
> **Base URL:** `https://ap.0bin.in`
> **Local:** `http://localhost:7002`
> **Version:** 1.0.0
> **Last Updated:** 2026-03-19
---
## 📋 엔드포인트 목록
| Method | Endpoint | 설명 |
|--------|----------|------|
| GET | `/health` | 헬스체크 |
| GET | `/api/products` | 약품 목록 조회 |
| POST | `/api/guide/pdf` | PDF 생성 |
| POST | `/api/guide/preview` | 미리보기 (메타데이터) |
---
## 1. 헬스체크
서버 상태 확인
### Request
```
GET /health
```
### Response
```json
{
"status": "ok",
"service": "anipharm-api",
"timestamp": "2026-03-19T20:01:13.292109"
}
```
---
## 2. 약품 목록 조회
등록된 모든 약품 목록 반환
### Request
```
GET /api/products
```
### Response
```json
{
"success": true,
"count": 21,
"products": [
{
"product_id": "MASTER-001",
"name": "넥스가드 스펙트라",
"category": "antiparasitic",
"category_display": "올인원 구충제"
},
{
"product_id": "MASTER-002",
"name": "아시카프 츄어블정",
"category": "nsaid",
"category_display": "진통소염제 (NSAIDs)"
}
// ... 21개
]
}
```
---
## 3. PDF 생성
투약지도서 PDF 파일 생성 및 다운로드
### Request
```
POST /api/guide/pdf
Content-Type: application/json
```
### Request Body
```json
{
"product_ids": ["MASTER-001", "MASTER-002", "MASTER-005"],
"patient_name": "김남곤",
"pet_name": "뽀삐",
"pet_species": "푸들",
"pet_age": "3세",
"pharmacy_name": "청춘약국 동물약 전문상담",
"pharmacy_tel": "033-481-0384"
}
```
| 필드 | 타입 | 필수 | 설명 |
|------|------|------|------|
| product_ids | string[] | ✅ | 약품 ID 배열 |
| patient_name | string | ❌ | 보호자 이름 (기본: "보호자") |
| pet_name | string | ❌ | 반려동물 이름 (기본: "반려동물") |
| pet_species | string | ❌ | 품종 |
| pet_age | string | ❌ | 나이 |
| pharmacy_name | string | ❌ | 약국명 (기본: "청춘약국 동물약 전문상담") |
| pharmacy_tel | string | ❌ | 전화번호 (기본: "033-481-0384") |
### Response
- **Success:** `application/pdf` (PDF 파일 다운로드)
- **Error:**
```json
{
"success": false,
"error": "에러 메시지"
}
```
### cURL 예시
```bash
curl -X POST https://ap.0bin.in/api/guide/pdf \
-H "Content-Type: application/json" \
-d '{
"product_ids": ["MASTER-001", "MASTER-002"],
"patient_name": "김남곤",
"pet_name": "뽀삐",
"pet_species": "푸들",
"pet_age": "3세"
}' \
--output 투약지도서.pdf
```
---
## 4. 미리보기 (메타데이터)
PDF 생성 전 약품 정보 및 예상 페이지 수 확인
### Request
```
POST /api/guide/preview
Content-Type: application/json
```
### Request Body
```json
{
"product_ids": ["MASTER-001", "MASTER-002", "MASTER-005"]
}
```
### Response
```json
{
"success": true,
"drug_count": 3,
"page_count": 1,
"drugs": [
{
"id": "MASTER-001",
"name": "넥스가드 스펙트라",
"category": "antiparasitic",
"has_image": true
},
{
"id": "MASTER-002",
"name": "아시카프 츄어블정",
"category": "nsaid",
"has_image": true
},
{
"id": "MASTER-005",
"name": "하트세이버 츄어블",
"category": "antiparasitic",
"has_image": true
}
]
}
```
---
## 📦 등록된 약품 목록 (21개)
| ID | 이름 | 카테고리 |
|----|------|----------|
| MASTER-001 | 넥스가드 스펙트라 | antiparasitic |
| MASTER-002 | 아시카프 츄어블정 | nsaid |
| MASTER-003 | 아시엔로 50 | antibiotic |
| MASTER-004 | 세레니아 정 | antiemetic |
| MASTER-005 | 하트세이버 츄어블 | antiparasitic |
| MASTER-006 | 프로닐스팟 | antiparasitic |
| MASTER-007 | 오리더밀 | otic |
| MASTER-008 | 터비덤 스프레이 | antifungal |
| MASTER-009 | 클로르헥시딘 샴푸 | topical |
| MASTER-010 | 셀라이트 | antiparasitic |
| MASTER-011 | 멜록시캐시 CH | nsaid |
| MASTER-012 | 복합 개시딘 겔 | topical |
| MASTER-013 | 임팩트액 | antiparasitic |
| MASTER-014 | 안텔민 뽀삐/킹 | antiparasitic |
| MASTER-015 | 티어가드 정 | antibiotic |
| MASTER-016 | 액티벳정 | antibiotic |
| MASTER-017 | 아포퀠 | immunomodulator |
| MASTER-018 | 브라벡토 | antiparasitic |
| MASTER-019 | 심파리카 트리오 | antiparasitic |
| MASTER-020 | 가바펜틴 | analgesic |
| MASTER-021 | 메트로니다졸 | antibiotic |
---
## 🔧 서버 정보
| 항목 | 값 |
|------|-----|
| 프레임워크 | Flask |
| 포트 | 7002 |
| PM2 이름 | anipharm-api |
| PDF 엔진 | WeasyPrint |
| 페이지당 약품 | 4개 |
---
## 📝 변경 이력
| 날짜 | 버전 | 내용 |
|------|------|------|
| 2026-03-19 | 1.0.0 | 최초 배포 |

View File

@@ -0,0 +1,67 @@
# -*- coding: utf-8 -*-
"""마스터 JSON에 실제 쇼핑몰 APC 매핑"""
import json
import os
# 마스터 JSON → 쇼핑몰 APC 매핑
APC_MAPPING = {
"nexgard_spectra.json": "0232555060207", # 넥스포인트(20~40kg) - 넥스가드 대용
"heartsaver.json": "0230467230300", # 하트세이버L(23~45kg)
"impact.json": "0232873820205", # 임팩트 독(4~10kg)
"antelmin.json": "0230237810109", # 안텔민 킹(5kg이상)
"selight.json": "0232545420203", # 셀라이트 독(4~10kg)
"meloxicash.json": "0232523510309", # 멜록시캐시CH
"asikaff_carprofen.json": "0232635710103", # 아시카프정
"enrofloxacin.json": "0232532310106", # 아시엔로정
"tiergard.json": "0231089420409", # 티어가드(100T)
"chlorhexidine_shampoo.json": "0231334930108", # 클로르헥시딘샴푸(200ml)
"actibet.json": "9240043910403", # 액티벳(100T)
"serenia_maropitant.json": "0231884620107", # 세레니아정 24mg
"terbiderm.json": "0232064110102", # 터비더미 솔루션
"simparica.json": "0232571730106", # 심파리카 트리오 L(20~40kg)
"gaesidin.json": "0231093520106", # 복합개시딘겔(10g)
"oridermyl.json": "0231065620103", # 오이드로믹스클린(10ml) - 귀약 대용
"fronilspot.json": None, # 쇼핑몰 미등록
"apoquel.json": None, # 쇼핑몰 미등록
"bravecto.json": None, # 쇼핑몰 미등록
"gabapentin.json": None, # 쇼핑몰 미등록
"metronidazole.json": None, # 쇼핑몰 미등록
}
MASTER_DIR = os.path.join(os.path.dirname(__file__), "..", "data", "master")
def update_json_files():
updated = []
skipped = []
for filename, apc in APC_MAPPING.items():
filepath = os.path.join(MASTER_DIR, filename)
if not os.path.exists(filepath):
skipped.append(f"{filename} (파일 없음)")
continue
with open(filepath, 'r', encoding='utf-8') as f:
data = json.load(f)
old_apc = data.get('apc_code', '')
if apc:
data['apc_code'] = apc
with open(filepath, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
updated.append(f"{filename}: {old_apc}{apc}")
else:
skipped.append(f"{filename} (매핑 없음)")
print("=" * 60)
print("APC 매핑 업데이트 완료")
print("=" * 60)
print(f"\n✅ 업데이트됨 ({len(updated)}개):")
for item in updated:
print(f" {item}")
print(f"\n⏭️ 건너뜀 ({len(skipped)}개):")
for item in skipped:
print(f" {item}")
if __name__ == "__main__":
update_json_files()

File diff suppressed because one or more lines are too long

BIN
static/nexgard_spectra.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

137
templates/anipharm_logo.svg Normal file
View File

@@ -0,0 +1,137 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.1.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="레이어_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 400 150" style="enable-background:new 0 0 400 150;" xml:space="preserve">
<style type="text/css">
.st0{fill:#008BD5;}
.st1{fill:#231815;}
</style>
<g>
<g>
<path class="st0" d="M58.3,116.86c0-6.77-5.49-12.21-12.26-12.21h-9.12c-3.18,0-6.14-0.94-8.64-2.54
c-4.36-2.78-7.28-7.6-7.44-13.1c0-0.16-0.02-0.31-0.02-0.47c0-5.74,3.02-10.79,7.56-13.64c1.39-0.87,2.41-2.23,2.64-3.85
c0.55-3.86,1.85-7.48,3.75-10.72c5.68-9.64,16.64-15.82,28.89-14.42c1.97,0.22,3.89,0.66,5.73,1.27c2.73,0.91,5.71-0.23,7.03-2.79
l0,0c1.89-3.67,0.22-7.68-3.71-8.94c-3.87-1.24-7.97-1.92-12.2-1.95c-19.48-0.13-35.87,13.08-40.63,31.03
c-0.3,1.13-0.93,2.12-1.8,2.9c-7.6,6.79-11.54,17.59-8.38,29.1c3.35,12.2,14.91,20.34,27.56,20.34L58.3,116.86z"/>
</g>
</g>
<g>
<g>
<path class="st0" d="M45.48,73.68c0,2.16-1.76,3.92-3.92,3.92c-2.17,0-3.92-1.76-3.92-3.92c0-2.17,1.76-3.92,3.92-3.92
C43.73,69.76,45.48,71.52,45.48,73.68z"/>
</g>
</g>
<g>
<g>
<path class="st0" d="M108.86,33.5l-2.39,0c-15.94,0-28.87,12.93-28.87,28.87v54.46c0,0.01,0.01,0.03,0.03,0.03
c6.73-0.01,12.19-5.48,12.19-12.21v-4.32V78.02v-13c0-10.58,8.5-19.16,19.05-19.3c8.71-0.11,16.44,6.41,16.97,15.1
c0.57,9.34-6.86,17.12-16.08,17.12h-8.74c-3.38,0-6.12,2.74-6.12,6.12l0,0c0,3.37,2.73,6.1,6.1,6.1h8.76
c16.07,0,29.01-13.38,28.29-29.61C137.37,45.26,124.16,33.5,108.86,33.5z"/>
</g>
</g>
<g>
<g>
<path class="st1" d="M114.59,101.52v3.3h8.51v1.2h-4.27v2.06h6.73v1.16h-14.84v-1.16h6.8v-2.06h-4.27v-5.67h9.78v1.18H114.59z
M118.15,117.12c-2.77,0-4.44-1.5-4.44-3.38c0-1.87,1.67-3.4,4.44-3.4c2.77,0,4.44,1.53,4.44,3.4
C122.59,115.62,120.92,117.12,118.15,117.12z M118.15,111.48c-1.85,0-3.07,0.99-3.07,2.26c0,1.3,1.22,2.27,3.07,2.27
s3.07-0.97,3.07-2.27C121.22,112.46,120,111.48,118.15,111.48z"/>
</g>
<g>
<path class="st1" d="M129.39,116.76v-4.02h8.53v-1.59h-8.53v-1.18h4.34v-1.67h-6.79v-1.18h14.84v1.18h-6.75v1.67h4.18v3.97h-8.53
v1.66h9.01v1.16H129.39z M129.48,105.59v-5.48h9.76v5.48H129.48z M137.92,101.29h-7.12v3.1h7.12V101.29z"/>
</g>
<g>
<path class="st1" d="M147.45,108.29c-2.36,0-4.12-1.62-4.12-3.79c0-2.13,1.76-3.74,4.12-3.74c2.34,0,4.13,1.59,4.13,3.74
C151.57,106.67,149.79,108.29,147.45,108.29z M147.45,101.91c-1.62,0-2.75,1.2-2.75,2.59c0,1.38,1.13,2.63,2.75,2.63
c1.64,0,2.77-1.25,2.77-2.63C150.21,103.1,149.09,101.91,147.45,101.91z M154.5,116.48v-5h-8.07v-1.2h9.4v6.2H154.5z
M155.82,103.53v2.15h2.55v1.2h-2.55v2.47h-1.32v-9.36h1.32v2.34h2.55v1.2H155.82z"/>
</g>
<g>
<path class="st1" d="M170.64,110.75c-1.94,0.21-4.37,0.41-6.08,0.48c-1.59,0.07-3.72,0.12-5.15,0.12l-0.14-1.2
c1.25,0.02,3.4-0.04,5.01-0.09c1.87-0.07,4.53-0.19,6.26-0.42L170.64,110.75z M168.59,104.34c0,2.1-1.64,3.72-4.13,3.72
c-2.4,0-4.16-1.62-4.16-3.72c0-2.13,1.76-3.7,4.16-3.7C166.79,100.64,168.59,102.21,168.59,104.34z M164.47,101.82
c-1.76,0-2.84,1.08-2.84,2.52c0,1.41,1.06,2.54,2.84,2.54c1.73,0,2.75-1.13,2.75-2.54C167.22,102.89,166.19,101.82,164.47,101.82z
M171.59,114.7v-14.68h1.3v14.68H171.59z"/>
</g>
<g>
<path class="st1" d="M189.66,109.4c-1.96-0.6-3.47-1.9-4.16-3.49c-0.67,1.64-1.96,2.91-4.11,3.74l-0.65-1.09
c2.34-0.9,4.05-2.61,4.05-5.25v-0.95h-3.65v-1.16h8.46v1.16h-3.44v0.92c0,2.54,1.82,4.3,4.11,5.04L189.66,109.4z M185.08,116.11
v-5.53h1.3v4.32h8.21v1.22H185.08z M192.99,111.55v-5.97h-3.81v-1.16h3.81V100h1.3v11.54H192.99z"/>
</g>
<g>
<path class="st1" d="M203.81,112.99v-3.38h-7.1v-1.18h14.84v1.18h-6.45v3.38H203.81z M200.49,111.58v3.63h8.64v1.2h-9.96v-4.83
H200.49z M199.24,106.49v-6.01h9.76v6.01H199.24z M207.69,101.68h-7.12v3.61h7.12V101.68z"/>
</g>
<g>
<path class="st1" d="M221.14,101.13c-0.09,5.39-3.44,8.44-7.42,10.03l-0.78-1.15c3.95-1.5,6.35-4.16,6.73-7.7h-5.9v-1.18H221.14z
M225.57,106.19v8.51h-1.32v-14.68h1.32v4.99h2.79v1.18H225.57z"/>
</g>
<g>
<path class="st1" d="M229.12,109.43v-1.18h14.84v1.18H229.12z M232.96,111.2v3.77h8.67v1.2h-9.99v-4.97H232.96z M231.71,105.86
v-5.62h1.3v4.42h8.62v1.2H231.71z"/>
</g>
<g>
<path class="st1" d="M254.56,108.29c-2.36,0-4.12-1.62-4.12-3.79c0-2.13,1.76-3.74,4.12-3.74c2.34,0,4.13,1.59,4.13,3.74
C258.68,106.67,256.9,108.29,254.56,108.29z M254.56,101.91c-1.62,0-2.75,1.2-2.75,2.59c0,1.38,1.13,2.63,2.75,2.63
c1.64,0,2.77-1.25,2.77-2.63C257.33,103.1,256.2,101.91,254.56,101.91z M261.61,116.48v-5h-8.07v-1.2h9.4v6.2H261.61z
M262.93,103.53v2.15h2.55v1.2h-2.55v2.47h-1.32v-9.36h1.32v2.34h2.55v1.2H262.93z"/>
</g>
<g>
<path class="st1" d="M274.93,110.65c-1.66-0.95-3.45-3.06-3.88-4.81c-0.37,1.85-1.92,4.09-3.97,5.18l-0.85-0.95
c2.38-1.27,4.07-3.9,4.07-7.26v-2.13h1.41v2.08c0,3.3,1.82,5.71,4.04,6.91L274.93,110.65z M279.14,106.19v8.51h-1.31v-14.68h1.31
v4.99h2.78v1.18H279.14z"/>
</g>
<g>
<path class="st1" d="M287.52,108.36c-2.38,0-4.18-1.62-4.18-3.86c0-2.24,1.8-3.82,4.18-3.82c2.43,0,4.21,1.59,4.21,3.82
C291.73,106.73,289.97,108.36,287.52,108.36z M287.52,101.84c-1.69,0-2.84,1.23-2.84,2.66c0,1.41,1.15,2.68,2.84,2.68
c1.78,0,2.89-1.27,2.89-2.68C290.41,103.07,289.3,101.84,287.52,101.84z M287.1,116.62v-6.84h1.3v2.08h6.77v-2.08h1.32v6.84H287.1
z M295.17,113.03h-6.77v2.41h6.77V113.03z M295.17,108.8v-8.81h1.32v8.81H295.17z"/>
</g>
<g>
<path class="st1" d="M301.3,108.9c3.1,0,5.76-0.21,7.83-0.67l0.19,1.16c-2.38,0.53-5.66,0.71-9.36,0.71v-9.13h1.34V108.9z
M311.13,100.04h1.32v14.67h-1.32V100.04z"/>
</g>
<g>
<path class="st1" d="M324.94,109.78c-2.66,0.42-5.82,0.62-9.22,0.49v-9.22h7.31v1.16h-5.97v6.86c2.01,0.11,5.62-0.12,7.74-0.51
L324.94,109.78z M327.74,105.01h2.79v1.18h-2.79v8.51h-1.3v-14.68h1.3V105.01z"/>
</g>
</g>
<g>
<path class="st1" d="M153.8,52.47c0-3.53,0.86-6.64,2.58-9.33c1.72-2.69,4.01-4.8,6.89-6.34c2.88-1.53,6.03-2.3,9.47-2.3
c3.43,0,6.59,0.77,9.47,2.3c2.88,1.53,5.2,3.64,6.96,6.34c1.76,2.69,2.65,5.8,2.65,9.33c0,3.62-0.88,6.8-2.65,9.54
c-1.76,2.74-4.09,4.87-6.96,6.41c-2.88,1.53-6.04,2.3-9.47,2.3c-3.44,0-6.59-0.77-9.47-2.3c-2.88-1.53-5.18-3.67-6.89-6.41
C154.66,59.27,153.8,56.09,153.8,52.47z M165.5,52.47c0,2.23,0.72,3.97,2.16,5.22c1.44,1.25,3.13,1.88,5.08,1.88
c2.13,0,3.9-0.63,5.29-1.88c1.39-1.25,2.09-2.99,2.09-5.22c0-2.13-0.7-3.83-2.09-5.08c-1.39-1.25-3.16-1.88-5.29-1.88
c-1.95,0-3.64,0.63-5.08,1.88C166.21,48.64,165.5,50.34,165.5,52.47z M229.69,75.86c0,1.76-0.54,3.2-1.6,4.32
c-1.07,1.11-2.39,1.67-3.97,1.67c-1.76,0-3.16-0.56-4.18-1.67c-1.02-1.11-1.53-2.55-1.53-4.32V63.05c0-0.74-0.26-1.46-0.77-2.16
c-0.51-0.7-1.28-1.05-2.3-1.05h-1.81c-0.93,0.09-1.62,0.44-2.09,1.05c-0.47,0.6-0.7,1.32-0.7,2.16v12.53c0,1.77-0.51,3.2-1.53,4.32
c-1.02,1.11-2.41,1.67-4.18,1.67c-1.67,0-3.02-0.56-4.04-1.67c-1.02-1.12-1.53-2.55-1.53-4.32V38.97c0-1.76,0.49-3.18,1.46-4.25
c0.97-1.07,2.34-1.6,4.11-1.6c1.86,0,3.18,0.42,3.97,1.25c0.79,0.83,1.27,1.69,1.46,2.58c0.19,0.88,0.28,1.56,0.28,2.02v7.1
c0,0.84,0.16,1.72,0.49,2.65c0.32,0.93,1.09,1.39,2.3,1.39h1.95c1.11,0,1.88-0.46,2.3-1.39c0.42-0.93,0.63-1.81,0.63-2.65v-7.1
c0-0.46,0.09-1.14,0.28-2.02c0.19-0.88,0.7-1.74,1.53-2.58c0.84-0.84,2.13-1.25,3.9-1.25c1.67,0,3.02,0.54,4.04,1.6
c1.02,1.07,1.53,2.48,1.53,4.25V75.86z"/>
<path class="st1" d="M247.08,41.61c0-1.58,0.5-2.9,1.51-3.97c1.01-1.07,2.3-1.6,3.9-1.6c1.42,0,2.66,0.54,3.71,1.6
c1.05,1.07,1.57,2.39,1.57,3.97v11.98c0,1.49,0.36,2.78,1.07,3.9c0.71,1.11,1.91,1.67,3.58,1.67H276c1.51,0,2.78,0.47,3.83,1.39
c1.05,0.93,1.57,2.28,1.57,4.04c0,1.67-0.52,3.04-1.57,4.11c-1.05,1.07-2.33,1.6-3.83,1.6h-20.87c-2.18,0-4.07-0.77-5.66-2.3
c-1.59-1.53-2.39-3.69-2.39-6.48V41.61z M297.99,75.45c0,1.76-0.48,3.2-1.45,4.32c-0.96,1.11-2.2,1.67-3.71,1.67
c-1.51,0-2.81-0.56-3.9-1.67c-1.09-1.11-1.63-2.55-1.63-4.32V38.83c0-0.46,0.15-1.14,0.44-2.02c0.29-0.88,0.84-1.74,1.63-2.58
c0.8-0.83,1.95-1.25,3.46-1.25c1.59,0,2.85,0.53,3.77,1.6c0.92,1.07,1.38,2.48,1.38,4.25V75.45z"/>
<path class="st1" d="M320.68,70.16c-1.76,0-3.18-0.51-4.25-1.53c-1.07-1.02-1.6-2.37-1.6-4.04c0-1.76,0.53-3.11,1.6-4.04
c1.07-0.93,2.48-1.39,4.25-1.39h1.67c1.39,0,2.09-0.83,2.09-2.51v-6.82c0-1.95-0.7-2.92-2.09-2.92h-1.39
c-1.67,0-3.04-0.46-4.11-1.39c-1.07-0.93-1.6-2.27-1.6-4.04c0-1.58,0.53-2.86,1.6-3.83c1.07-0.97,2.39-1.51,3.97-1.6h35.23
c1.67,0,3.04,0.51,4.11,1.53c1.07,1.02,1.6,2.32,1.6,3.9c0,1.76-0.54,3.11-1.6,4.04c-1.07,0.93-2.44,1.39-4.11,1.39h-0.98
c-0.65,0-1.25,0.21-1.81,0.63c-0.56,0.42-0.84,1.09-0.84,2.02v7.1c0,1.67,0.74,2.51,2.23,2.51h1.81c1.58,0,2.92,0.47,4.04,1.39
c1.11,0.93,1.67,2.28,1.67,4.04c0,1.67-0.56,3.02-1.67,4.04c-1.11,1.02-2.46,1.53-4.04,1.53H320.68z M342.13,50.38
c0-1.58-0.35-2.55-1.04-2.93c-0.7-0.37-1.42-0.56-2.16-0.56h-0.83c-0.74,0-1.46,0.19-2.16,0.56c-0.7,0.37-1.04,1.3-1.04,2.79v6.27
c0,0.93,0.3,1.63,0.91,2.09c0.6,0.46,1.37,0.7,2.3,0.7h0.83c0.84,0,1.58-0.21,2.23-0.63c0.65-0.42,0.97-1.18,0.97-2.3V50.38z
M349.79,117.78c-2.6,0-4.73-0.79-6.41-2.37c-1.67-1.58-2.51-3.67-2.51-6.27V93.69c0-2.6,0.84-4.69,2.51-6.27
c1.67-1.58,3.81-2.37,6.41-2.37h18.24c2.69,0,4.83,0.79,6.41,2.37c1.58,1.58,2.37,3.67,2.37,6.27v15.46c0,2.6-0.79,4.69-2.37,6.27
c-1.58,1.58-3.71,2.37-6.41,2.37H349.79z M352.71,102.88c0,1.21,0.18,2.18,0.56,2.92c0.37,0.74,1.25,1.11,2.65,1.11h5.29
c1.48,0,2.48-0.37,2.99-1.11c0.51-0.74,0.77-1.72,0.77-2.92V99.4c0-1.11-0.26-1.97-0.77-2.58c-0.51-0.6-1.56-0.91-3.13-0.91h-4.87
c-1.3,0-2.21,0.35-2.72,1.05c-0.51,0.7-0.77,1.55-0.77,2.58V102.88z M368.86,39.1c0-1.86,0.56-3.29,1.67-4.32
c1.11-1.02,2.55-1.53,4.32-1.53c1.76,0,3.04,0.42,3.83,1.25c0.79,0.84,1.32,1.7,1.6,2.58c0.28,0.88,0.42,1.56,0.42,2.02v6.96
c0,2.51,1.16,3.76,3.48,3.76h3.62c2.13,0,3.62,0.56,4.46,1.67c0.84,1.11,1.25,2.37,1.25,3.76c0,1.58-0.51,2.9-1.53,3.97
c-1.02,1.07-2.41,1.6-4.18,1.6h-3.62c-2.32,0-3.48,1.02-3.48,3.06v12.11c0,1.76-0.58,3.2-1.74,4.32c-1.16,1.11-2.53,1.67-4.11,1.67
c-1.76,0-3.2-0.56-4.32-1.67c-1.11-1.11-1.67-2.55-1.67-4.32V39.1z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

File diff suppressed because one or more lines are too long