feat: 항생제/항구토제 마스터 JSON 추가 + 템플릿 레이아웃
This commit is contained in:
67
data/master/enrofloxacin.json
Normal file
67
data/master/enrofloxacin.json
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
{
|
||||||
|
"product_id": "MASTER-003",
|
||||||
|
"apc_code": "0519-ENROFLOXACIN",
|
||||||
|
"name": "아시엔로 50",
|
||||||
|
"english_name": "Enrofloxacin 50mg",
|
||||||
|
"manufacturer": "아시아제약",
|
||||||
|
"category": "antibiotic",
|
||||||
|
"category_display": "항생제 (퀴놀론계)",
|
||||||
|
"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정"}
|
||||||
|
],
|
||||||
|
|
||||||
|
"warnings": [
|
||||||
|
"⚠️ 고양이: 5mg/kg 초과 금지 (망막 독성 위험!)",
|
||||||
|
"⚠️ 성장기 동물: 연골 손상 가능성 (1세 미만 주의)",
|
||||||
|
"⚠️ 간질/경련 병력 동물 주의",
|
||||||
|
"⚠️ 제산제(알루미늄, 마그네슘)와 2시간 간격 투여"
|
||||||
|
],
|
||||||
|
|
||||||
|
"contraindications": [
|
||||||
|
"1세 미만 강아지 (대형견은 18개월 미만)",
|
||||||
|
"임신/수유 중",
|
||||||
|
"간질/경련 병력",
|
||||||
|
"퀴놀론 과민반응 이력"
|
||||||
|
],
|
||||||
|
|
||||||
|
"side_effects": {
|
||||||
|
"common": ["구토", "설사", "식욕부진"],
|
||||||
|
"serious": ["고양이 망막 독성 (고용량)", "연골 손상 (성장기)", "경련 (드묾)"]
|
||||||
|
},
|
||||||
|
|
||||||
|
"cat_warning": {
|
||||||
|
"max_dose": "5mg/kg/day",
|
||||||
|
"max_duration": "21일",
|
||||||
|
"risk": "망막 변성 → 실명 가능",
|
||||||
|
"source": "다수 문헌 보고"
|
||||||
|
},
|
||||||
|
|
||||||
|
"storage": "실온 보관, 습기 피할 것",
|
||||||
|
|
||||||
|
"source": {
|
||||||
|
"guidelines": ["ISCAID Antimicrobial Guidelines"],
|
||||||
|
"notes": "고양이 망막 독성 관련 다수 증례 보고"
|
||||||
|
}
|
||||||
|
}
|
||||||
73
data/master/serenia_maropitant.json
Normal file
73
data/master/serenia_maropitant.json
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
{
|
||||||
|
"product_id": "MASTER-004",
|
||||||
|
"apc_code": "0519-SERENIA",
|
||||||
|
"name": "세레니아 정",
|
||||||
|
"english_name": "Serenia (Maropitant citrate)",
|
||||||
|
"manufacturer": "조에티스 (Zoetis)",
|
||||||
|
"category": "antiemetic",
|
||||||
|
"category_display": "항구토제",
|
||||||
|
"target_animal": ["개", "고양이"],
|
||||||
|
"administration": "경구 (정제)",
|
||||||
|
"image_url": "/images/serenia.png",
|
||||||
|
|
||||||
|
"indication": "급성 구토, 멀미(차멀미) 예방 및 치료",
|
||||||
|
|
||||||
|
"mechanism": {
|
||||||
|
"drug_class": "NK1 수용체 길항제",
|
||||||
|
"action": "구토중추의 NK1 수용체 차단 → 구토 억제",
|
||||||
|
"feature": "중추 및 말초 모두 작용"
|
||||||
|
},
|
||||||
|
|
||||||
|
"dosage": {
|
||||||
|
"acute_vomiting": {
|
||||||
|
"dose": "2mg/kg 1일 1회",
|
||||||
|
"duration": "최대 5일 연속"
|
||||||
|
},
|
||||||
|
"motion_sickness": {
|
||||||
|
"dose": "8mg/kg",
|
||||||
|
"timing": "이동 최소 2시간 전 투여",
|
||||||
|
"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"}
|
||||||
|
],
|
||||||
|
|
||||||
|
"available_strengths": ["16mg", "24mg", "60mg", "160mg"],
|
||||||
|
|
||||||
|
"warnings": [
|
||||||
|
"⚠️ 16주(4개월) 미만 강아지 금지",
|
||||||
|
"⚠️ 고양이: 급성 구토에만 사용 (멀미 적응증 없음)",
|
||||||
|
"⚠️ 5일 이상 연속 투여 금지 (급성 구토)",
|
||||||
|
"⚠️ 차멀미 예방 시 공복 상태에서 효과적"
|
||||||
|
],
|
||||||
|
|
||||||
|
"contraindications": [
|
||||||
|
"16주 미만 강아지",
|
||||||
|
"위장관 폐색 의심 시 (구토 억제가 위험)",
|
||||||
|
"독소 섭취 후 (구토 유도 필요 시)"
|
||||||
|
],
|
||||||
|
|
||||||
|
"side_effects": {
|
||||||
|
"common": ["침흘림 (일시적)", "무기력"],
|
||||||
|
"rare": ["설사", "식욕부진"]
|
||||||
|
},
|
||||||
|
|
||||||
|
"clinical_notes": [
|
||||||
|
"구토 원인 파악 필수 (단순 증상 억제 아님)",
|
||||||
|
"위장관 폐색, 독소 섭취 시에는 구토 유도가 필요할 수 있음",
|
||||||
|
"멀미 예방: 이동 2시간 전 + 공복 = 최대 효과"
|
||||||
|
],
|
||||||
|
|
||||||
|
"storage": "실온 보관",
|
||||||
|
|
||||||
|
"source": {
|
||||||
|
"product_info": "Zoetis Serenia Product Information",
|
||||||
|
"notes": "FDA 승인 수의용 항구토제"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -471,6 +471,70 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% elif drug.category == 'antibiotic' %}
|
||||||
|
<!-- 항생제 레이아웃 -->
|
||||||
|
<div class="dosing-section">
|
||||||
|
<div class="dosing-title">📋 적응증</div>
|
||||||
|
<div class="dosing-main">{{ drug.indication }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="dosage-table-section">
|
||||||
|
<div class="coverage-title">⚖️ 체중별 용량 ({{ drug.dosage.standard }})</div>
|
||||||
|
<div class="dosage-grid">
|
||||||
|
{% for row in drug.dosage_table %}
|
||||||
|
<div class="dosage-cell">
|
||||||
|
<div class="dosage-weight">{{ row.weight }}</div>
|
||||||
|
<div class="dosage-amount">{{ row.tablets }}</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div class="dosing-note" style="margin-top:2mm;">
|
||||||
|
투약 기간: {{ drug.dosage.duration }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if drug.cat_warning %}
|
||||||
|
<div class="contraindication-box">
|
||||||
|
<div class="contraindication-title">🐱 고양이 특별 주의</div>
|
||||||
|
<ul class="contraindication-list">
|
||||||
|
<li>❌ 최대 용량: {{ drug.cat_warning.max_dose }}</li>
|
||||||
|
<li>❌ 위험: {{ drug.cat_warning.risk }}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% elif drug.category == 'antiemetic' %}
|
||||||
|
<!-- 항구토제 레이아웃 -->
|
||||||
|
<div class="dosing-section">
|
||||||
|
<div class="dosing-title">📋 적응증</div>
|
||||||
|
<div class="dosing-main">{{ drug.indication }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="coverage-section">
|
||||||
|
<div class="coverage-title">💊 용법용량</div>
|
||||||
|
<div class="coverage-table" style="grid-template-columns: 1fr 1fr;">
|
||||||
|
<div class="coverage-item covered">
|
||||||
|
<span class="coverage-name" style="font-weight:700;">급성 구토</span>
|
||||||
|
<span style="font-size:8pt;">{{ drug.dosage.acute_vomiting.dose }}</span>
|
||||||
|
<span style="font-size:6pt;">최대 {{ drug.dosage.acute_vomiting.duration }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="coverage-item covered">
|
||||||
|
<span class="coverage-name" style="font-weight:700;">멀미 예방</span>
|
||||||
|
<span style="font-size:8pt;">{{ drug.dosage.motion_sickness.dose }}</span>
|
||||||
|
<span style="font-size:6pt;">{{ drug.dosage.motion_sickness.timing }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if drug.clinical_notes %}
|
||||||
|
<div class="gap-warning">
|
||||||
|
<div class="gap-warning-title">💡 임상 참고</div>
|
||||||
|
{% for note in drug.clinical_notes %}
|
||||||
|
<div class="gap-solution">• {{ note }}</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<!-- 기본 레이아웃 -->
|
<!-- 기본 레이아웃 -->
|
||||||
<div class="dosing-section">
|
<div class="dosing-section">
|
||||||
|
|||||||
70
test_v2_4drugs.py
Normal file
70
test_v2_4drugs.py
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
v2 API 테스트 - 4개 약품 (2페이지)
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
sys.path.insert(0, os.path.dirname(__file__))
|
||||||
|
|
||||||
|
from animal_med import AnimalMedRendererV2
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print("=" * 60)
|
||||||
|
print("v2 API 테스트 - 4개 약품 (2페이지)")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
renderer = AnimalMedRendererV2()
|
||||||
|
|
||||||
|
# 마스터 약품 목록
|
||||||
|
print("\n[1] 마스터 약품 목록:")
|
||||||
|
for drug in renderer.list_drugs():
|
||||||
|
print(f" {drug['product_id']} - {drug['name']} ({drug['category_display']})")
|
||||||
|
|
||||||
|
# 4개 약품 모두 사용
|
||||||
|
test_ids = ["MASTER-001", "MASTER-002", "MASTER-003", "MASTER-004"]
|
||||||
|
|
||||||
|
print(f"\n[2] PDF 렌더링 ({len(test_ids)}개 약품)")
|
||||||
|
for pid in test_ids:
|
||||||
|
drug = renderer.get_drug(pid)
|
||||||
|
if drug:
|
||||||
|
print(f" - {drug['name']} ({drug['category_display']})")
|
||||||
|
|
||||||
|
# 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_4drugs_test.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="7세"
|
||||||
|
)
|
||||||
|
|
||||||
|
if result['success']:
|
||||||
|
print(f" ✅ 성공!")
|
||||||
|
print(f" 📄 PDF: {result['pdf_path']}")
|
||||||
|
print(f" 약품: {', '.join(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()
|
||||||
Reference in New Issue
Block a user