From a6725dace4d30c1007f0cd12f338aa570e250fd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B2=AD=EC=B6=98=EC=95=BD=EA=B5=AD?= Date: Wed, 18 Mar 2026 22:12:52 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=ED=95=AD=EC=83=9D=EC=A0=9C/=ED=95=AD?= =?UTF-8?q?=EA=B5=AC=ED=86=A0=EC=A0=9C=20=EB=A7=88=EC=8A=A4=ED=84=B0=20JSO?= =?UTF-8?q?N=20=EC=B6=94=EA=B0=80=20+=20=ED=85=9C=ED=94=8C=EB=A6=BF=20?= =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/master/enrofloxacin.json | 67 ++++++++++++++++++++++++++ data/master/serenia_maropitant.json | 73 +++++++++++++++++++++++++++++ templates/medication_guide_v2.html | 64 +++++++++++++++++++++++++ test_v2_4drugs.py | 70 +++++++++++++++++++++++++++ 4 files changed, 274 insertions(+) create mode 100644 data/master/enrofloxacin.json create mode 100644 data/master/serenia_maropitant.json create mode 100644 test_v2_4drugs.py diff --git a/data/master/enrofloxacin.json b/data/master/enrofloxacin.json new file mode 100644 index 0000000..e714bdf --- /dev/null +++ b/data/master/enrofloxacin.json @@ -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": "고양이 망막 독성 관련 다수 증례 보고" + } +} diff --git a/data/master/serenia_maropitant.json b/data/master/serenia_maropitant.json new file mode 100644 index 0000000..f827982 --- /dev/null +++ b/data/master/serenia_maropitant.json @@ -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 승인 수의용 항구토제" + } +} diff --git a/templates/medication_guide_v2.html b/templates/medication_guide_v2.html index 3a1ea8a..3046749 100644 --- a/templates/medication_guide_v2.html +++ b/templates/medication_guide_v2.html @@ -471,6 +471,70 @@ {% endif %} + {% elif drug.category == 'antibiotic' %} + +
+
📋 적응증
+
{{ drug.indication }}
+
+ +
+
⚖️ 체중별 용량 ({{ drug.dosage.standard }})
+
+ {% for row in drug.dosage_table %} +
+
{{ row.weight }}
+
{{ row.tablets }}
+
+ {% endfor %} +
+
+ 투약 기간: {{ drug.dosage.duration }} +
+
+ + {% if drug.cat_warning %} +
+
🐱 고양이 특별 주의
+ +
+ {% endif %} + + {% elif drug.category == 'antiemetic' %} + +
+
📋 적응증
+
{{ drug.indication }}
+
+ +
+
💊 용법용량
+
+
+ 급성 구토 + {{ drug.dosage.acute_vomiting.dose }} + 최대 {{ drug.dosage.acute_vomiting.duration }} +
+
+ 멀미 예방 + {{ drug.dosage.motion_sickness.dose }} + {{ drug.dosage.motion_sickness.timing }} +
+
+
+ + {% if drug.clinical_notes %} +
+
💡 임상 참고
+ {% for note in drug.clinical_notes %} +
• {{ note }}
+ {% endfor %} +
+ {% endif %} + {% else %}
diff --git a/test_v2_4drugs.py b/test_v2_4drugs.py new file mode 100644 index 0000000..1784307 --- /dev/null +++ b/test_v2_4drugs.py @@ -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()