feat: 7개 마스터 JSON 추가 (총 16개) + 면역조절제/진통제 레이아웃

This commit is contained in:
청춘약국
2026-03-18 23:35:39 +09:00
parent 43c85d43e6
commit 233c520578
9 changed files with 441 additions and 0 deletions

49
data/master/antelmin.json Normal file
View File

@@ -0,0 +1,49 @@
{
"product_id": "MASTER-014",
"apc_code": "0519-ANTELMIN",
"name": "안텔민 플러스",
"english_name": "Antelmin Plus (Praziquantel + Pyrantel + Febantel)",
"manufacturer": "바이엘",
"category": "antiparasitic",
"category_display": "광범위 내부구충제",
"target_animal": ["개", "고양이"],
"administration": "경구 (정제)",
"indication": "조충(촌충), 회충, 구충, 편충 구제",
"coverage_summary": {
"covered": ["조충(촌충)", "회충", "구충", "편충", "십이지장충"],
"not_covered": ["벼룩", "진드기", "심장사상충"],
"gap_solution": "넥스가드/브라벡토의 조충 갭 보완용"
},
"dosing": {
"interval": "3개월마다 또는 필요시",
"interval_reason": "조충 감염 주기 + 올인원 구충제 보완",
"minimum_age": "3주 이상",
"minimum_weight": "제한 없음"
},
"dosage_table": [
{"weight": "2.5kg", "tablets": "0.5정"},
{"weight": "5kg", "tablets": "1정"},
{"weight": "10kg", "tablets": "2정"},
{"weight": "15kg", "tablets": "3정"},
{"weight": "20kg", "tablets": "4정"},
{"weight": "25kg", "tablets": "5정"}
],
"warnings": [
"⚠️ 임신 초기 투여 주의",
"⚠️ 심한 감염 시 대량 충체 배출 가능",
"⚠️ 공복 투여 권장 (효과 증가)"
],
"clinical_notes": [
"넥스가드 스펙트라/심파리카 트리오와 병용 가능",
"조충 감염원 (벼룩, 생고기) 관리 필요",
"3개월 간격 정기 투여 권장"
],
"storage": "실온 보관"
}

50
data/master/apoquel.json Normal file
View File

@@ -0,0 +1,50 @@
{
"product_id": "MASTER-011",
"apc_code": "0519-APOQUEL",
"name": "아포퀠",
"english_name": "Apoquel (Oclacitinib)",
"manufacturer": "조에티스 (Zoetis)",
"category": "immunomodulator",
"category_display": "아토피/알러지 치료제",
"target_animal": ["개"],
"administration": "경구 (정제)",
"indication": "개 아토피성 피부염, 알러지성 가려움증 완화",
"mechanism": {
"drug_class": "JAK 억제제 (Janus Kinase Inhibitor)",
"action": "JAK1/JAK3 억제 → 가려움/염증 사이토카인 차단",
"onset": "4시간 내 가려움 감소 시작"
},
"dosage": {
"standard": "0.4~0.6mg/kg 1일 2회",
"maintenance": "0.4~0.6mg/kg 1일 1회",
"note": "처음 14일간 1일 2회 → 이후 1일 1회 유지"
},
"dosage_table": [
{"weight": "4.5~6kg", "tablets": "3.6mg 1정"},
{"weight": "6.1~9kg", "tablets": "5.4mg 1정"},
{"weight": "9.1~13.5kg", "tablets": "3.6mg + 5.4mg"},
{"weight": "13.6~20kg", "tablets": "16mg 1정"},
{"weight": "20.1~27kg", "tablets": "16mg + 5.4mg"},
{"weight": "27.1~40kg", "tablets": "16mg 2정"}
],
"warnings": [
"⚠️ 12개월 미만 강아지 금지",
"⚠️ 중증 감염 시 사용 주의",
"⚠️ 장기 투여 시 혈액검사 권장",
"⚠️ 면역 억제 → 종양 발생 모니터링",
"⚠️ 번식용 개 안전성 미확립"
],
"contraindications": [
"12개월 미만",
"중증 감염",
"면역결핍"
],
"storage": "실온 보관"
}

49
data/master/bravecto.json Normal file
View File

@@ -0,0 +1,49 @@
{
"product_id": "MASTER-012",
"apc_code": "0519-BRAVECTO",
"name": "브라벡토",
"english_name": "Bravecto (Fluralaner)",
"manufacturer": "MSD동물약품",
"category": "antiparasitic",
"category_display": "장기 지속 구충제",
"target_animal": ["개", "고양이"],
"administration": "경구 (츄어블) / 스팟온",
"indication": "벼룩·진드기 12주 지속 구제",
"coverage_summary": {
"covered": ["벼룩", "진드기", "모낭충", "개선충"],
"not_covered": ["심장사상충", "내부기생충"],
"gap_solution": "심장사상충: 셀라리드/하트가드 / 내부기생충: 안텔민"
},
"dosing": {
"interval": "12주(3개월) 1회",
"interval_reason": "Fluralaner 반감기 12~15일, 12주간 유효 혈중 농도 유지",
"minimum_age": "8주(개) / 11주(고양이)",
"minimum_weight": "2kg 이상"
},
"weight_products": [
{"size": "XS", "weight_range": "2~4.5kg", "dose": "112.5mg"},
{"size": "S", "weight_range": "4.5~10kg", "dose": "250mg"},
{"size": "M", "weight_range": "10~20kg", "dose": "500mg"},
{"size": "L", "weight_range": "20~40kg", "dose": "1000mg"},
{"size": "XL", "weight_range": "40~56kg", "dose": "1400mg"}
],
"warnings": [
"⚠️ 경련/간질 이력 주의 (이소자졸린 계열)",
"⚠️ 8주/2kg 미만 금지",
"⚠️ 심장사상충 별도 예방 필수",
"⚠️ MDR1 유전자 변이 품종 주의"
],
"clinical_notes": [
"3개월 1회 투여 → 보호자 편의성 높음",
"넥스가드 대비: 심장사상충 미커버, 주기 길음",
"음식과 함께 투여 시 흡수율 증가"
],
"storage": "실온 보관"
}

View File

@@ -0,0 +1,41 @@
{
"product_id": "MASTER-015",
"apc_code": "0519-GABAPENTIN",
"name": "가바펜틴",
"english_name": "Gabapentin",
"manufacturer": "일반의약품",
"category": "analgesic",
"category_display": "신경병증성 진통제",
"target_animal": ["개", "고양이"],
"administration": "경구 (캡슐/정제)",
"indication": "신경병증성 통증, 만성 통증, 수술 전 진정, 불안 완화",
"mechanism": {
"drug_class": "GABA 유사체",
"action": "칼슘 채널 α2δ 서브유닛 결합 → 신경 흥분 억제",
"feature": "진통 + 항경련 + 진정 작용"
},
"dosage": {
"dog_pain": "5~10mg/kg 1일 2~3회",
"cat_pain": "5~10mg/kg 1일 1~2회",
"cat_anxiety": "50~100mg/cat 내원 2~3시간 전",
"note": "용량은 효과에 따라 점진적 증량"
},
"warnings": [
"⚠️ 신장 기능 저하 시 감량 필요",
"⚠️ 급격한 중단 금지 (점진적 감량)",
"⚠️ 졸음/운동실조 발생 가능",
"⚠️ 액상 제제 중 자일리톨 함유 주의 (개)"
],
"clinical_notes": [
"NSAIDs와 병용 시 시너지 (multimodal analgesia)",
"고양이 내원 스트레스 감소에 효과적",
"만성 관절염 장기 통증 관리에 유용"
],
"storage": "실온 보관"
}

View File

@@ -0,0 +1,43 @@
{
"product_id": "MASTER-016",
"apc_code": "0519-METRONIDAZOLE",
"name": "메트로니다졸",
"english_name": "Metronidazole",
"manufacturer": "일반의약품",
"category": "antibiotic",
"category_display": "항생제/항원충제",
"target_animal": ["개", "고양이"],
"administration": "경구 (정제)",
"indication": "지아르디아, 클로스트리디움, 염증성 장질환, 혐기성 감염",
"mechanism": {
"drug_class": "니트로이미다졸계",
"action": "DNA 합성 억제 → 혐기성균/원충 사멸",
"spectrum": "혐기성균, 지아르디아, 트리코모나스"
},
"dosage": {
"standard": "10~25mg/kg 1일 2회",
"giardia": "25mg/kg 1일 2회, 5~7일",
"ibd": "10~15mg/kg 1일 2회",
"duration": "5~14일 (적응증에 따라)"
},
"warnings": [
"⚠️ 장기 투여 시 신경독성 주의 (운동실조, 경련)",
"⚠️ 임신 중 금기 (기형 유발 가능성)",
"⚠️ 쓴맛 → 고양이 투약 어려움 (캡슐 권장)",
"⚠️ 음식과 함께 투여 (위장 자극 감소)"
],
"side_effects": ["식욕부진", "구토", "설사", "신경독성(고용량/장기)"],
"clinical_notes": [
"지아르디아: 펜벤다졸과 병용 시 효과 증가",
"IBD: 면역조절 효과로 장기 사용 가능",
"투약 어려운 고양이: 트랜스더말 제제 고려"
],
"storage": "차광 보관"
}

44
data/master/selarid.json Normal file
View File

@@ -0,0 +1,44 @@
{
"product_id": "MASTER-010",
"apc_code": "0519-SELARID",
"name": "셀라리드",
"english_name": "Selarid (Selamectin)",
"manufacturer": "노바텍",
"category": "antiparasitic",
"category_display": "스팟온 구충제",
"target_animal": ["개", "고양이"],
"administration": "경피 도포 (스팟온)",
"indication": "벼룩 + 심장사상충 예방 + 귀진드기 + 개선충",
"coverage_summary": {
"covered": ["벼룩", "심장사상충", "귀진드기", "개선충", "회충(고양이)"],
"not_covered": ["진드기", "내부기생충(개)"],
"gap_solution": "진드기: 프로닐 추가 / 내부기생충: 안텔민 추가"
},
"dosing": {
"interval": "매월 1회",
"interval_reason": "심장사상충 예방 + 벼룩 라이프사이클 30일",
"minimum_age": "6주 이상",
"minimum_weight": "제한 없음"
},
"weight_products": [
{"size": "퍼피/키튼", "weight_range": "~2.5kg", "dose": "15mg"},
{"size": "고양이S", "weight_range": "2.6~7.5kg", "dose": "45mg"},
{"size": "개S", "weight_range": "2.6~5kg", "dose": "30mg"},
{"size": "개M", "weight_range": "5.1~10kg", "dose": "60mg"},
{"size": "개L", "weight_range": "10.1~20kg", "dose": "120mg"},
{"size": "개XL", "weight_range": "20.1~40kg", "dose": "240mg"}
],
"warnings": [
"⚠️ 도포 후 2시간 목욕/수영 금지",
"⚠️ 도포 부위 완전 건조 후 접촉",
"⚠️ 아이버멕틴 민감 품종 주의 (콜리 등)",
"⚠️ 피부 상처 부위 도포 금지"
],
"storage": "실온 보관"
}

View File

@@ -0,0 +1,48 @@
{
"product_id": "MASTER-013",
"apc_code": "0519-SIMPARICA",
"name": "심파리카 트리오",
"english_name": "Simparica Trio (Sarolaner+Moxidectin+Pyrantel)",
"manufacturer": "조에티스 (Zoetis)",
"category": "antiparasitic",
"category_display": "올인원 구충제",
"target_animal": ["개"],
"administration": "경구 (츄어블)",
"indication": "벼룩·진드기 + 심장사상충 예방 + 회충/구충 구제",
"coverage_summary": {
"covered": ["벼룩", "진드기", "심장사상충", "회충", "구충"],
"not_covered": ["편충", "조충"],
"gap_solution": "편충: 넥스가드 스펙트라 / 조충: 안텔민 추가"
},
"dosing": {
"interval": "매월 1회",
"interval_reason": "심장사상충 예방 주기 + 벼룩 라이프사이클",
"minimum_age": "8주 이상",
"minimum_weight": "1.25kg 이상"
},
"weight_products": [
{"size": "XS", "weight_range": "1.25~2.5kg", "dose": "3/0.06/12.5mg"},
{"size": "S", "weight_range": "2.6~5kg", "dose": "6/0.12/25mg"},
{"size": "M", "weight_range": "5.1~10kg", "dose": "12/0.25/50mg"},
{"size": "L", "weight_range": "10.1~20kg", "dose": "24/0.5/100mg"},
{"size": "XL", "weight_range": "20.1~40kg", "dose": "48/1/200mg"}
],
"warnings": [
"⚠️ 경련/간질 이력 주의 (이소자졸린 계열)",
"⚠️ 8주/1.25kg 미만 금지",
"⚠️ 투약 전 심장사상충 검사 필수",
"⚠️ MDR1 유전자 변이 품종 주의"
],
"comparison": {
"vs_nexgard_spectra": "편충 미커버, 최소 체중 더 낮음 (1.25kg)",
"vs_bravecto": "심장사상충 커버, 월 1회 투여"
},
"storage": "실온 보관"
}

View File

@@ -443,6 +443,49 @@
</div> </div>
{% endif %} {% endif %}
{% elif drug.category == 'immunomodulator' %}
<!-- 면역조절제 (아포퀠 등) -->
<div class="dosing-section">
<div class="dosing-title">📋 {{ drug.indication }}</div>
{% if drug.mechanism %}
<div class="dosing-note">{{ drug.mechanism.action }}</div>
{% endif %}
</div>
<div class="coverage-title">⚖️ 체중별 용량</div>
<div class="dosage-grid">
{% for row in drug.dosage_table[:6] %}
<div class="dosage-cell">
<div class="dosage-weight">{{ row.weight }}</div>
<div class="dosage-amount">{{ row.tablets }}</div>
</div>
{% endfor %}
</div>
<div class="gap-warning">
<span class="gap-warning-title">💊 투약법</span><br>
<span class="gap-solution">• {{ drug.dosage.note }}</span>
</div>
{% elif drug.category == 'analgesic' %}
<!-- 진통제 (가바펜틴 등) -->
<div class="dosing-section">
<div class="dosing-title">📋 {{ drug.indication }}</div>
</div>
<div class="usage-box">
{% if drug.dosage.dog_pain %}<b>🐕 개:</b> {{ drug.dosage.dog_pain }}<br>{% endif %}
{% if drug.dosage.cat_pain %}<b>🐱 고양이:</b> {{ drug.dosage.cat_pain }}<br>{% endif %}
{% if drug.dosage.cat_anxiety %}<b>🐱 불안:</b> {{ drug.dosage.cat_anxiety }}{% endif %}
</div>
{% if drug.clinical_notes %}
<div class="gap-warning">
<span class="gap-warning-title">💡 임상 참고</span><br>
{% for note in drug.clinical_notes %}<span class="gap-solution">• {{ note }}</span><br>{% endfor %}
</div>
{% endif %}
{% else %} {% else %}
<!-- 기타 (외용제 등) --> <!-- 기타 (외용제 등) -->
<div class="dosing-section"> <div class="dosing-section">

74
test_v2_16drugs.py Normal file
View File

@@ -0,0 +1,74 @@
# -*- coding: utf-8 -*-
"""
v2 API 테스트 - 16개 약품 (4페이지)
"""
import os
import sys
sys.path.insert(0, os.path.dirname(__file__))
from animal_med import AnimalMedRendererV2
def main():
print("=" * 60)
print("v2 API 테스트 - 16개 약품 (4페이지)")
print("=" * 60)
renderer = AnimalMedRendererV2()
# 마스터 약품 목록
print("\n[1] 마스터 약품 목록:")
drugs = renderer.list_drugs()
for drug in drugs:
print(f" {drug['product_id']} - {drug['name']} ({drug['category']})")
print(f"\n{len(drugs)}개 약품")
# 16개 약품 사용 (2x2 x 4페이지)
test_ids = [
"MASTER-001", "MASTER-002", "MASTER-003", "MASTER-004",
"MASTER-005", "MASTER-006", "MASTER-007", "MASTER-008",
"MASTER-010", "MASTER-011", "MASTER-012", "MASTER-013",
"MASTER-014", "MASTER-015", "MASTER-016", "MASTER-009"
]
print(f"\n[2] PDF 렌더링 ({len(test_ids)}개 약품)")
# PDF 생성
output_dir = os.path.join(os.path.dirname(__file__), 'output')
os.makedirs(output_dir, exist_ok=True)
pdf_path = os.path.join(output_dir, 'v2_16drugs_4pages.pdf')
print(f"\n[3] PDF 생성 중...")
result = renderer.render_to_pdf(
product_ids=test_ids,
output_path=pdf_path,
patient_name="김보호자",
pet_name="뽀삐",
pet_species="푸들",
pet_age="3세"
)
if result['success']:
print(f" ✅ 성공!")
print(f" 📄 PDF: {result['pdf_path']}")
print(f" 약품: {len(result['drugs'])}")
size = os.path.getsize(pdf_path)
print(f" 크기: {size / 1024:.1f} KB")
import fitz
doc = fitz.open(pdf_path)
print(f" 페이지 수: {len(doc)}")
doc.close()
else:
print(f" ❌ 실패: {result.get('error')}")
print("\n" + "=" * 60)
if __name__ == "__main__":
main()