Lincoln Gombedza Claude Sonnet 4.6 commited on
Commit
95e4355
Β·
0 Parent(s):

Initial commit: Nursing Case Study Builder (Tool #5)

Browse files

- 10 detailed clinical case studies (STEMI, Asthma, DKA, Stroke,
Sepsis, NOF fracture, Preeclampsia, Febrile convulsion,
Paracetamol OD, AKI prerenal)
- 5-tab Streamlit UI: Case Library, Full Case, ADPIE Reasoning,
Quiz Questions, Care Plan Builder
- NCLEX-style MCQs with rationales and scoring per case
- Downloadable NANDA care plan export
- GitHub Actions workflow for HF Space auto-deploy

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

.github/workflows/sync-to-hf.yml ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Sync to Hugging Face Space
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+
8
+ jobs:
9
+ sync-to-hub:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - name: Checkout repository
13
+ uses: actions/checkout@v4
14
+ with:
15
+ fetch-depth: 0
16
+ lfs: true
17
+
18
+ - name: Push to Hugging Face Space
19
+ env:
20
+ HF_TOKEN: ${{ secrets.HF_TOKEN }}
21
+ run: |
22
+ git config --global user.email "action@github.com"
23
+ git config --global user.name "GitHub Action"
24
+ git push \
25
+ https://NurseCitizenDeveloper:${HF_TOKEN}@huggingface.co/spaces/NurseCitizenDeveloper/nursing-case-studies \
26
+ main
.gitignore ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # macOS
2
+ .DS_Store
3
+ .AppleDouble
4
+ .LSOverride
5
+ ._*
6
+ .Spotlight-V100
7
+ .Trashes
8
+
9
+ # Python
10
+ __pycache__/
11
+ *.py[cod]
12
+ *$py.class
13
+ *.egg-info/
14
+ dist/
15
+ build/
16
+ .eggs/
17
+ *.egg
18
+ .env
19
+ .venv
20
+ venv/
21
+ env/
22
+
23
+ # Streamlit
24
+ .streamlit/secrets.toml
25
+
26
+ # IDE
27
+ .vscode/
28
+ .idea/
29
+ *.swp
30
+ *.swo
31
+
32
+ # Logs
33
+ *.log
README.md ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Nursing Case Studies
3
+ emoji: πŸ₯
4
+ colorFrom: blue
5
+ colorTo: indigo
6
+ sdk: streamlit
7
+ sdk_version: 1.32.0
8
+ app_file: streamlit_app.py
9
+ pinned: false
10
+ ---
11
+
12
+ # πŸ₯ Nursing Case Study Builder β€” Student Nurses
13
+
14
+ An interactive, free clinical case study tool designed to help student nurses develop critical thinking and clinical reasoning skills using the **ADPIE nursing process**.
15
+
16
+ ## Features
17
+
18
+ - **πŸ“š Case Library** β€” 10 detailed, realistic clinical scenarios across major body systems
19
+ - **πŸ” Full Case View** β€” Complete patient demographics, vitals, physical exam, investigations, and medical diagnosis
20
+ - **🧠 ADPIE Reasoning** β€” Guided Assessment β†’ Diagnosis β†’ Planning β†’ Implementation β†’ Evaluation framework with model answers
21
+ - **❓ Quiz Questions** β€” 5 NCLEX-style case-based MCQs per scenario with rationales and scoring
22
+ - **πŸ“ Care Plan Builder** β€” Structured NANDA nursing diagnosis care plan with SMART goals and downloadable output
23
+
24
+ ## Case Scenarios
25
+
26
+ | # | Case | Category | Difficulty |
27
+ |---|------|----------|------------|
28
+ | 1 | STEMI β€” Acute Chest Pain | ❀️ Cardiovascular | Intermediate |
29
+ | 2 | Acute Severe Asthma | 🫁 Respiratory | Intermediate |
30
+ | 3 | Diabetic Ketoacidosis (DKA) | 🩺 Endocrine | Intermediate |
31
+ | 4 | Ischaemic Stroke | 🧠 Neurological | Advanced |
32
+ | 5 | Septic Shock | 🦠 Multi-system | Advanced |
33
+ | 6 | NOF Fracture β€” Post-op Day 1 | 🦴 Musculoskeletal | Intermediate |
34
+ | 7 | Severe Preeclampsia | 🀰 Maternal | Advanced |
35
+ | 8 | Paediatric Febrile Convulsion | πŸ‘Ά Paediatric | Beginner |
36
+ | 9 | Paracetamol Overdose (DSH) | πŸ§ͺ Toxicology / Mental Health | Intermediate |
37
+ | 10 | Acute Kidney Injury (Prerenal AKI) | 🫘 Renal | Intermediate |
38
+
39
+ ## How to Use
40
+
41
+ 1. **Browse** the Case Library and click **Open β†’** on any scenario
42
+ 2. **Read** the Full Case to understand the clinical picture
43
+ 3. **Work through** ADPIE Reasoning β€” write your answers before revealing the model
44
+ 4. **Test yourself** with Quiz Questions and review rationales
45
+ 5. **Build** a structured Care Plan and download it as a text file
46
+
47
+ ## Tech Stack
48
+
49
+ - [Streamlit](https://streamlit.io/) β€” frontend framework
50
+ - Pure Python β€” no API keys or external services required
51
+ - All case data is locally curated for nursing education
52
+
53
+ ## Part of the Student Nurse Toolkit
54
+
55
+ This tool is part of a free suite of nursing education apps:
56
+ - [EBP Research Tool](https://huggingface.co/spaces/NurseCitizenDeveloper/nursing-ebp-tool)
57
+ - [Drug Card Generator](https://huggingface.co/spaces/NurseCitizenDeveloper/nursing-drug-cards)
58
+ - [NCLEX Prep](https://huggingface.co/spaces/NurseCitizenDeveloper/nclex-prep)
59
+ - [Medication Safety Checker](https://huggingface.co/spaces/NurseCitizenDeveloper/medication-safety)
60
+ - **Case Study Builder** ← you are here
61
+
62
+ ---
63
+ *Built for student nurses. Educational use only β€” not a substitute for clinical training or professional judgment.*
cases/__init__.py ADDED
File without changes
cases/bank.py ADDED
@@ -0,0 +1,1418 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Nursing Case Study Bank
3
+ 10 detailed patient scenarios covering major body systems.
4
+ For educational purposes only.
5
+ """
6
+
7
+ CASE_BANK = [
8
+
9
+ # ── 1. CARDIOVASCULAR β€” STEMI ──────────────────────────────────────────
10
+ {
11
+ "id": "case_001",
12
+ "title": "Crushing Chest Pain: STEMI",
13
+ "category": "Cardiovascular",
14
+ "difficulty": "Intermediate",
15
+ "tags": ["MI", "STEMI", "chest pain", "cardiovascular", "emergency"],
16
+ "learning_objectives": [
17
+ "Recognise clinical presentation of STEMI",
18
+ "Prioritise immediate nursing interventions (MONA)",
19
+ "Understand reperfusion therapy urgency (door-to-balloon < 90 min)",
20
+ "Monitor for complications: arrhythmias, cardiogenic shock",
21
+ "Provide appropriate patient and family education",
22
+ ],
23
+ "patient": {
24
+ "name": "Mr. Robert Chen",
25
+ "age": 64,
26
+ "gender": "Male",
27
+ "weight_kg": 92,
28
+ "height_cm": 176,
29
+ "allergies": ["Penicillin (rash)"],
30
+ "pmhx": ["Hypertension (10 years)", "Type 2 Diabetes Mellitus", "Hyperlipidaemia", "Ex-smoker"],
31
+ "medications": [
32
+ "Metformin 1000 mg BD",
33
+ "Atorvastatin 40 mg nocte",
34
+ "Amlodipine 5 mg daily",
35
+ "Aspirin 100 mg daily",
36
+ ],
37
+ "social": "Retired teacher. Lives with wife. Smoked 20/day for 30 years, quit 5 years ago. Occasional alcohol.",
38
+ "family_hx": "Father died of MI at age 58. Mother has T2DM.",
39
+ },
40
+ "presentation": (
41
+ "Mr. Chen is brought to ED by ambulance at 14:30. He describes sudden onset crushing "
42
+ "central chest pain radiating to his left arm and jaw, rated 9/10, starting 90 minutes ago "
43
+ "while mowing the lawn. He is diaphoretic, pale, and nauseated. Wife confirms he took one "
44
+ "GTN tablet at home with no relief."
45
+ ),
46
+ "vitals": {
47
+ "BP": "158/96 mmHg",
48
+ "HR": "104 bpm (irregular)",
49
+ "RR": "22 breaths/min",
50
+ "SpO2": "93% on room air",
51
+ "Temp": "36.8Β°C",
52
+ "Pain": "9/10",
53
+ "GCS": "15",
54
+ "BSL": "14.2 mmol/L",
55
+ },
56
+ "physical_exam": (
57
+ "Patient appears anxious and diaphoretic. Skin pale and clammy. "
58
+ "Heart sounds: S1, S2 present; no murmurs. Crackles at lung bases bilaterally. "
59
+ "JVP mildly elevated. Peripheral pulses present. No peripheral oedema."
60
+ ),
61
+ "investigations": {
62
+ "ECG": "ST elevation in leads II, III, aVF (inferior STEMI). Reciprocal ST depression in I, aVL.",
63
+ "Troponin I": "3.8 ng/mL (↑↑ normal < 0.04)",
64
+ "CK-MB": "68 U/L (↑ normal < 25)",
65
+ "BNP": "420 pg/mL (↑)",
66
+ "FBC": "Hb 138 g/L, WCC 11.2 Γ— 10⁹/L",
67
+ "UEC": "Na 138, K 4.1, Cr 102 ΞΌmol/L",
68
+ "Glucose": "14.2 mmol/L",
69
+ "Lipids": "Total cholesterol 6.8 mmol/L, LDL 4.2 mmol/L",
70
+ "CXR": "Mild cardiomegaly. Early pulmonary oedema.",
71
+ },
72
+ "medical_diagnosis": "Inferior ST-Elevation Myocardial Infarction (STEMI)",
73
+ "nursing_priorities": [
74
+ "Immediate 12-lead ECG and cardiac monitoring",
75
+ "Establish IV access Γ— 2 large-bore",
76
+ "Administer Oβ‚‚ if SpOβ‚‚ < 94% β€” target 94–98%",
77
+ "Administer MONA: Morphine, Oxygen, Nitrates, Aspirin (per protocol)",
78
+ "Prepare for urgent PCI (door-to-balloon < 90 minutes)",
79
+ "Continuous cardiac monitoring β€” watch for arrhythmias",
80
+ "Maintain patient rest β€” reduce myocardial Oβ‚‚ demand",
81
+ "Monitor haemodynamic status β€” watch for cardiogenic shock",
82
+ ],
83
+ "nursing_diagnoses": [
84
+ {
85
+ "diagnosis": "Acute Pain related to myocardial ischaemia",
86
+ "evidence": "Patient reports 9/10 crushing chest pain, diaphoresis, facial grimacing",
87
+ "goal": "Patient reports pain ≀ 3/10 within 30 minutes of intervention",
88
+ "interventions": [
89
+ "Administer GTN SL (if SBP > 90 mmHg) per protocol",
90
+ "Administer IV morphine titrated to pain per medical order",
91
+ "Position patient in semi-Fowler's to reduce preload",
92
+ "Reassess pain score every 15 minutes",
93
+ "Provide calm reassurance to reduce anxiety-induced sympathetic stimulation",
94
+ ],
95
+ },
96
+ {
97
+ "diagnosis": "Decreased Cardiac Output related to myocardial injury",
98
+ "evidence": "Tachycardia 104 bpm, SpOβ‚‚ 93%, elevated BNP, pulmonary oedema on CXR",
99
+ "goal": "Haemodynamic stability: MAP > 65 mmHg, HR 60–100 bpm, SpOβ‚‚ β‰₯ 94%",
100
+ "interventions": [
101
+ "Continuous cardiac monitoring β€” 12-lead ECG on admission",
102
+ "Monitor vital signs every 15 minutes",
103
+ "Apply Oβ‚‚ to target SpOβ‚‚ 94–98%",
104
+ "Ensure IV access β€” prepare for urgent PCI",
105
+ "Monitor for signs of cardiogenic shock: ↓ BP, ↓ UO, altered LOC",
106
+ "Restrict fluids if signs of pulmonary oedema",
107
+ ],
108
+ },
109
+ {
110
+ "diagnosis": "Anxiety related to acute illness and fear of death",
111
+ "evidence": "Patient appears anxious; high-acuity cardiac event",
112
+ "goal": "Patient verbalises reduced anxiety and understands planned treatment",
113
+ "interventions": [
114
+ "Explain all procedures clearly and calmly",
115
+ "Allow family member to stay if appropriate",
116
+ "Administer anxiolytic per protocol if needed",
117
+ "Reassure patient that team is taking immediate action",
118
+ ],
119
+ },
120
+ ],
121
+ "adpie": {
122
+ "assessment": (
123
+ "Subjective: 9/10 crushing chest pain to left arm and jaw, nausea, diaphoresis. "
124
+ "Objective: HR 104 irregular, BP 158/96, SpOβ‚‚ 93%, ECG showing inferior ST elevation, "
125
+ "Troponin I 3.8 ng/mL (markedly elevated), crackles at lung bases."
126
+ ),
127
+ "diagnosis": (
128
+ "1. Acute Pain r/t myocardial ischaemia AEB 9/10 pain, diaphoresis.\n"
129
+ "2. Decreased Cardiac Output r/t myocardial injury AEB tachycardia, low SpOβ‚‚.\n"
130
+ "3. Anxiety r/t acute illness AEB restlessness and verbalised fear."
131
+ ),
132
+ "planning": (
133
+ "Short-term: Pain ≀ 3/10 within 30 min; SpOβ‚‚ β‰₯ 94%; HR < 100 bpm.\n"
134
+ "Long-term: Patient undergoes successful PCI; understands cardiac rehab; "
135
+ "modifies risk factors (diet, exercise, medication adherence)."
136
+ ),
137
+ "implementation": (
138
+ "β€’ Applied Oβ‚‚ via Hudson mask at 6 L/min β€” SpOβ‚‚ improved to 96%.\n"
139
+ "β€’ IV access Γ— 2 established β€” bloods taken, fluids connected.\n"
140
+ "β€’ GTN 400 mcg SL given β€” partial relief; morphine 2.5 mg IV titrated to pain 4/10.\n"
141
+ "β€’ Aspirin 300 mg PO loading dose given per protocol.\n"
142
+ "β€’ Continuous cardiac monitoring applied β€” telemetry for PVCs noted.\n"
143
+ "β€’ Catheterisation lab notified β€” door-to-balloon time tracking initiated.\n"
144
+ "β€’ Family updated; patient's anxiety visibly reduced after explanation."
145
+ ),
146
+ "evaluation": (
147
+ "Pain reduced to 4/10 within 20 minutes. SpOβ‚‚ 96% on Oβ‚‚. HR 98 bpm, BP 142/88. "
148
+ "Patient transferred to catheterisation lab at 15:08 β€” door-to-balloon time 38 minutes. "
149
+ "PCI performed successfully. Post-procedure: haemodynamically stable, pain free."
150
+ ),
151
+ },
152
+ },
153
+
154
+ # ── 2. RESPIRATORY β€” ACUTE ASTHMA ─────────────────────────────────────
155
+ {
156
+ "id": "case_002",
157
+ "title": "Acute Severe Asthma Exacerbation",
158
+ "category": "Respiratory",
159
+ "difficulty": "Intermediate",
160
+ "tags": ["asthma", "respiratory", "bronchospasm", "wheeze", "emergency"],
161
+ "learning_objectives": [
162
+ "Assess severity of asthma using PEFR and clinical signs",
163
+ "Administer stepwise bronchodilator therapy",
164
+ "Recognise life-threatening asthma (silent chest, cyanosis)",
165
+ "Monitor response to treatment and escalate appropriately",
166
+ "Provide asthma action plan education",
167
+ ],
168
+ "patient": {
169
+ "name": "Ms. Aisha Patel",
170
+ "age": 28,
171
+ "gender": "Female",
172
+ "weight_kg": 62,
173
+ "height_cm": 163,
174
+ "allergies": ["NSAIDs (bronchospasm)", "Cats"],
175
+ "pmhx": ["Asthma since childhood", "Eczema", "Allergic rhinitis"],
176
+ "medications": [
177
+ "Salbutamol 100 mcg puffer PRN",
178
+ "Fluticasone/salmeterol 250/25 mcg 1 puff BD",
179
+ "Cetirizine 10 mg nocte",
180
+ ],
181
+ "social": "Schoolteacher. Non-smoker. Lives in apartment with cat. Recently started new cleaning products at work.",
182
+ "family_hx": "Mother has asthma. Father has hay fever.",
183
+ },
184
+ "presentation": (
185
+ "Ms. Patel presents to ED at 22:15 unable to complete sentences. She has been wheezing "
186
+ "for 4 hours, progressively worsening since visiting a friend's home who has two cats. "
187
+ "Used salbutamol puffer 8 times in the last 2 hours with minimal relief. Appears frightened "
188
+ "and is leaning forward in tripod position."
189
+ ),
190
+ "vitals": {
191
+ "BP": "138/82 mmHg",
192
+ "HR": "118 bpm",
193
+ "RR": "28 breaths/min",
194
+ "SpO2": "89% on room air",
195
+ "Temp": "37.0Β°C",
196
+ "Pain": "0/10 (dyspnoea 8/10)",
197
+ "GCS": "15",
198
+ "PEFR": "38% of predicted",
199
+ },
200
+ "physical_exam": (
201
+ "Patient in obvious respiratory distress. Using accessory muscles (sternocleidomastoid, intercostals). "
202
+ "Tripod position. Unable to complete full sentences. Widespread bilateral expiratory and inspiratory wheeze. "
203
+ "Prolonged expiratory phase. No cyanosis. No stridor."
204
+ ),
205
+ "investigations": {
206
+ "PEFR": "38% of predicted (severe: < 50%)",
207
+ "ABG": "pH 7.48, pCOβ‚‚ 32 mmHg, pOβ‚‚ 58 mmHg, HCO₃ 24 β€” respiratory alkalosis + hypoxaemia",
208
+ "FBC": "WCC 13.2 Γ— 10⁹/L (stress response), Eosinophils 0.8",
209
+ "CXR": "Hyperinflated lungs. No consolidation. No pneumothorax.",
210
+ "ECG": "Sinus tachycardia 118 bpm",
211
+ "Theophylline level": "Not applicable (not on theophylline)",
212
+ },
213
+ "medical_diagnosis": "Acute Severe Asthma Exacerbation",
214
+ "nursing_priorities": [
215
+ "High-flow Oβ‚‚ immediately β€” target SpOβ‚‚ 93–95%",
216
+ "Back-to-back salbutamol nebulisers (2.5–5 mg) every 20 min Γ— 3",
217
+ "Ipratropium bromide nebuliser added for severe exacerbation",
218
+ "Oral/IV prednisolone (or hydrocortisone IV) per protocol",
219
+ "Continuous SpOβ‚‚ monitoring and frequent PEFR reassessment",
220
+ "Keep patient upright (sitting forward) β€” optimise respiratory mechanics",
221
+ "Prepare for escalation: IV magnesium sulphate, HDU/ICU if no improvement",
222
+ "Reassess every 15–20 minutes",
223
+ ],
224
+ "nursing_diagnoses": [
225
+ {
226
+ "diagnosis": "Impaired Gas Exchange related to bronchospasm and mucus plugging",
227
+ "evidence": "SpOβ‚‚ 89%, RR 28, ABG shows hypoxaemia, widespread wheeze",
228
+ "goal": "SpOβ‚‚ β‰₯ 93%, RR < 20, PEFR > 50% predicted within 1 hour",
229
+ "interventions": [
230
+ "Apply Oβ‚‚ 6–8 L/min via face mask β€” titrate to SpOβ‚‚ 93–95%",
231
+ "Administer salbutamol 5 mg + ipratropium 0.5 mg via nebuliser",
232
+ "Position: high Fowler's or forward-leaning (tripod)",
233
+ "Monitor SpOβ‚‚ continuously, PEFR every 20 minutes",
234
+ "Prepare IV magnesium sulphate 2 g over 20 min if no improvement",
235
+ ],
236
+ },
237
+ {
238
+ "diagnosis": "Ineffective Breathing Pattern related to airway obstruction",
239
+ "evidence": "Accessory muscle use, prolonged expiratory phase, RR 28, PEFR 38%",
240
+ "goal": "RR 12–20, accessory muscle use reduced, patient able to speak in sentences",
241
+ "interventions": [
242
+ "Coach pursed-lip breathing to prolong exhalation",
243
+ "Ensure calm, quiet environment to reduce anxiety and Oβ‚‚ demand",
244
+ "Administer corticosteroids (prednisolone 50 mg PO / hydrocortisone 200 mg IV)",
245
+ "Repeat PEFR 15–20 minutes post-bronchodilator",
246
+ ],
247
+ },
248
+ ],
249
+ "adpie": {
250
+ "assessment": (
251
+ "Subjective: 4-hour history of worsening wheeze, dyspnoea 8/10, unable to finish sentences, "
252
+ "8 Γ— salbutamol puffs with no relief. Objective: SpOβ‚‚ 89%, RR 28, HR 118, "
253
+ "PEFR 38%, accessory muscles, bilateral wheeze."
254
+ ),
255
+ "diagnosis": (
256
+ "1. Impaired Gas Exchange r/t bronchospasm AEB SpOβ‚‚ 89%, ABG hypoxaemia.\n"
257
+ "2. Ineffective Breathing Pattern r/t airway obstruction AEB accessory muscles, RR 28.\n"
258
+ "3. Anxiety r/t breathing difficulty AEB frightened appearance."
259
+ ),
260
+ "planning": (
261
+ "SpOβ‚‚ β‰₯ 93% within 30 min; PEFR > 50% within 60 min; "
262
+ "RR < 20; patient able to speak in full sentences."
263
+ ),
264
+ "implementation": (
265
+ "β€’ Oβ‚‚ 8 L/min via face mask applied β€” SpOβ‚‚ improved to 94%.\n"
266
+ "β€’ Salbutamol 5 mg + ipratropium 0.5 mg nebulised β€” 3 doses 20 min apart.\n"
267
+ "β€’ Prednisolone 50 mg PO given.\n"
268
+ "β€’ Reassurance provided, calm environment maintained.\n"
269
+ "β€’ PEFR measured at 20 min intervals: 38% β†’ 52% β†’ 61%."
270
+ ),
271
+ "evaluation": (
272
+ "After 60 minutes: SpOβ‚‚ 96% on 4 L Oβ‚‚, PEFR 61%, RR 18, HR 96. "
273
+ "Speaking in full sentences. Wheeze reduced. Admitted to ward for observation. "
274
+ "Asthma action plan discussed before discharge."
275
+ ),
276
+ },
277
+ },
278
+
279
+ # ── 3. ENDOCRINE β€” DKA ────────────────────────────────────────────────
280
+ {
281
+ "id": "case_003",
282
+ "title": "Diabetic Ketoacidosis (DKA)",
283
+ "category": "Endocrine",
284
+ "difficulty": "Advanced",
285
+ "tags": ["DKA", "diabetes", "endocrine", "ketoacidosis", "insulin"],
286
+ "learning_objectives": [
287
+ "Identify DKA diagnostic criteria (BSL, ketones, pH)",
288
+ "Manage IV fluid resuscitation protocol",
289
+ "Administer insulin infusion safely β€” monitor potassium closely",
290
+ "Monitor for DKA complications: cerebral oedema, hypokalaemia",
291
+ "Identify and address precipitating factors",
292
+ ],
293
+ "patient": {
294
+ "name": "Ms. Emily Thornton",
295
+ "age": 19,
296
+ "gender": "Female",
297
+ "weight_kg": 58,
298
+ "height_cm": 168,
299
+ "allergies": ["NKDA"],
300
+ "pmhx": ["Type 1 Diabetes Mellitus (since age 9)"],
301
+ "medications": [
302
+ "Insulin glargine 20 units nocte",
303
+ "Insulin aspart sliding scale with meals",
304
+ ],
305
+ "social": "First-year university student. Lives in student accommodation. Recently had gastroenteritis β€” unable to eat for 2 days. Forgot to take insulin.",
306
+ "family_hx": "Nil relevant.",
307
+ },
308
+ "presentation": (
309
+ "Emily is brought to ED by her roommate at 03:00. She has been vomiting for 36 hours "
310
+ "and is confused and lethargic. Her roommate reports she has been breathing strangely "
311
+ "('like she can't catch her breath') and there is a fruity smell on her breath. "
312
+ "She omitted her insulin for 2 days as she wasn't eating."
313
+ ),
314
+ "vitals": {
315
+ "BP": "98/62 mmHg (lying)",
316
+ "HR": "124 bpm",
317
+ "RR": "28 breaths/min (Kussmaul)",
318
+ "SpO2": "97% on room air",
319
+ "Temp": "37.4Β°C",
320
+ "Pain": "5/10 (abdominal)",
321
+ "GCS": "13 (E3 V4 M6)",
322
+ "BSL": "28.4 mmol/L",
323
+ },
324
+ "physical_exam": (
325
+ "Patient is drowsy and confused. Dry mucous membranes, sunken eyes, poor skin turgor β€” "
326
+ "estimated 10% dehydration. Tachycardic. Kussmaul respirations (deep and rapid). "
327
+ "Fruity/acetone breath. Diffuse abdominal tenderness. No peritonism."
328
+ ),
329
+ "investigations": {
330
+ "BSL": "28.4 mmol/L",
331
+ "Blood ketones": "5.8 mmol/L (↑↑ normal < 0.6)",
332
+ "ABG": "pH 7.18, pCOβ‚‚ 18 mmHg, pOβ‚‚ 98 mmHg, HCO₃ 8 mmol/L β€” severe metabolic acidosis",
333
+ "Anion Gap": "30 (↑ normal 8–12)",
334
+ "UEC": "Na 132, K 5.8 (↑ β€” due to acidosis shift), Cr 118 ΞΌmol/L",
335
+ "Urine ketones": "4+ (strongly positive)",
336
+ "FBC": "WCC 18.4 (stress leucocytosis), Hb 132",
337
+ "HbA1c": "11.2% (↑↑ poor glycaemic control)",
338
+ "Lipase": "Normal",
339
+ "ECG": "Sinus tachycardia. Peaked T waves (hyperkalaemia).",
340
+ },
341
+ "medical_diagnosis": "Diabetic Ketoacidosis (DKA) β€” severe (pH < 7.2)",
342
+ "nursing_priorities": [
343
+ "URGENT IV fluid resuscitation: 0.9% NaCl 1 L over 1 hour",
344
+ "Commence insulin infusion β€” DO NOT start until K⁺ β‰₯ 3.5 mmol/L",
345
+ "Hourly potassium monitoring β€” replace aggressively as insulin drives K⁺ into cells",
346
+ "Strict fluid balance β€” IDC for accurate urine output monitoring",
347
+ "Hourly BSL, 2-hourly blood ketones and ABG",
348
+ "Continuous cardiac monitoring β€” hyperkalaemia/hypokalaemia arrhythmia risk",
349
+ "Neurological observations β€” watch for cerebral oedema (↓GCS, headache, vomiting)",
350
+ "NG tube if GCS < 13 (airway protection, vomiting)",
351
+ ],
352
+ "nursing_diagnoses": [
353
+ {
354
+ "diagnosis": "Deficient Fluid Volume related to osmotic diuresis and vomiting",
355
+ "evidence": "BP 98/62, HR 124, dry mucous membranes, estimated 10% dehydration",
356
+ "goal": "BP > 100/60, HR < 100, urine output β‰₯ 0.5 mL/kg/hr within 2 hours",
357
+ "interventions": [
358
+ "Administer 0.9% NaCl 1 L stat, then 1 L/hr Γ— 2 hours per DKA protocol",
359
+ "Insert IDC β€” monitor hourly urine output",
360
+ "Monitor vital signs every 30 minutes",
361
+ "Accurate intake/output chart",
362
+ "Assess skin turgor, mucous membranes hourly",
363
+ ],
364
+ },
365
+ {
366
+ "diagnosis": "Imbalanced Nutrition / Risk for Electrolyte Imbalance",
367
+ "evidence": "K⁺ 5.8 (acidosis shift β€” will drop rapidly with insulin), HCO₃ 8",
368
+ "goal": "K⁺ maintained 3.5–5.5 mmol/L; pH > 7.3 within 12 hours",
369
+ "interventions": [
370
+ "DO NOT start insulin until K⁺ β‰₯ 3.5 β€” risk of fatal hypokalaemia",
371
+ "Commence KCl replacement as per DKA protocol once insulin started",
372
+ "Hourly potassium levels while on insulin infusion",
373
+ "Continuous ECG monitoring for arrhythmias",
374
+ "Administer sodium bicarbonate only if pH < 7.0 per protocol",
375
+ ],
376
+ },
377
+ {
378
+ "diagnosis": "Acute Confusion related to cerebral effects of acidosis and dehydration",
379
+ "evidence": "GCS 13, confused, lethargic",
380
+ "goal": "GCS returns to 15 within 6 hours as metabolic derangement corrects",
381
+ "interventions": [
382
+ "Neurological observations hourly (GCS, pupils)",
383
+ "Reorient patient frequently",
384
+ "Raise bed rails β€” fall prevention",
385
+ "Alert medical team immediately if GCS drops β‰₯ 2 points β€” cerebral oedema risk",
386
+ "Avoid rapid fluid correction (risk of cerebral oedema)",
387
+ ],
388
+ },
389
+ ],
390
+ "adpie": {
391
+ "assessment": (
392
+ "Subjective: 36-hour vomiting, omitted insulin 2 days, abdominal pain. "
393
+ "Objective: BSL 28.4, ketones 5.8, pH 7.18, BP 98/62, HR 124, GCS 13, "
394
+ "Kussmaul respirations, fruity breath, 10% dehydration."
395
+ ),
396
+ "diagnosis": (
397
+ "1. Deficient Fluid Volume r/t osmotic diuresis AEB hypotension, tachycardia, dry mucous membranes.\n"
398
+ "2. Risk for Electrolyte Imbalance r/t insulin-potassium shift AEB K⁺ 5.8 (will drop with insulin).\n"
399
+ "3. Acute Confusion r/t acidosis and dehydration AEB GCS 13."
400
+ ),
401
+ "planning": (
402
+ "Fluid resuscitation to restore haemodynamic stability within 2 hours. "
403
+ "Safe insulin infusion with hourly K⁺ monitoring. "
404
+ "Ketones < 0.5, pH > 7.3 within 12 hours. GCS 15 within 6 hours."
405
+ ),
406
+ "implementation": (
407
+ "β€’ IV 0.9% NaCl 1 L over 1 hour commenced β€” BP improved to 108/70 after 1 hour.\n"
408
+ "β€’ Insulin infusion commenced at 0.1 units/kg/hr after K⁺ confirmed β‰₯ 3.5.\n"
409
+ "β€’ KCl replacement added to IV fluids as per DKA sliding scale.\n"
410
+ "β€’ IDC inserted β€” urine output 40 mL/hr after fluid resuscitation.\n"
411
+ "β€’ Hourly BSL, 2-hourly ketones, continuous ECG monitoring.\n"
412
+ "β€’ Family updated; patient reoriented regularly."
413
+ ),
414
+ "evaluation": (
415
+ "At 6 hours: BSL 14.2 mmol/L, ketones 1.8 mmol/L, pH 7.28, K⁺ 3.9, BP 118/76, "
416
+ "HR 98, GCS 15. At 12 hours: ketones cleared, pH 7.36, patient eating. "
417
+ "Diabetes educator consulted. Sick-day management plan provided."
418
+ ),
419
+ },
420
+ },
421
+
422
+ # ── 4. NEUROLOGICAL β€” STROKE (CVA) ────────────────────────────────────
423
+ {
424
+ "id": "case_004",
425
+ "title": "Acute Ischaemic Stroke",
426
+ "category": "Neurological",
427
+ "difficulty": "Advanced",
428
+ "tags": ["stroke", "CVA", "neurological", "tPA", "FAST", "thrombolysis"],
429
+ "learning_objectives": [
430
+ "Apply FAST/BE-FAST stroke recognition tool",
431
+ "Understand time-critical thrombolysis window (< 4.5 hours)",
432
+ "Perform accurate neurological assessment (NIH Stroke Scale)",
433
+ "Monitor for post-tPA haemorrhagic transformation",
434
+ "Prevent aspiration β€” nil by mouth until formal swallow assessment",
435
+ ],
436
+ "patient": {
437
+ "name": "Mrs. Joan McAllister",
438
+ "age": 72,
439
+ "gender": "Female",
440
+ "weight_kg": 74,
441
+ "height_cm": 161,
442
+ "allergies": ["Sulfonamides"],
443
+ "pmhx": ["Atrial Fibrillation", "Hypertension", "Hyperlipidaemia", "Previous TIA 3 years ago"],
444
+ "medications": [
445
+ "Apixaban 5 mg BD",
446
+ "Perindopril 4 mg daily",
447
+ "Rosuvastatin 20 mg nocte",
448
+ ],
449
+ "social": "Retired nurse. Widowed. Lives alone. Independent ADLs. Last seen well 1.5 hours ago by neighbour.",
450
+ "family_hx": "Sister had stroke at age 68.",
451
+ },
452
+ "presentation": (
453
+ "Mrs. McAllister is brought to ED by ambulance at 09:45. Her neighbour found her on the "
454
+ "kitchen floor at 09:30. She has right-sided facial droop, right arm weakness (cannot raise "
455
+ "arm above shoulder), and slurred speech. She appears confused about the date but knows her name. "
456
+ "Last known well: 08:15 (spoke to neighbour on phone)."
457
+ ),
458
+ "vitals": {
459
+ "BP": "186/104 mmHg",
460
+ "HR": "88 bpm (irregular β€” AF)",
461
+ "RR": "18 breaths/min",
462
+ "SpO2": "96% on room air",
463
+ "Temp": "37.1Β°C",
464
+ "Pain": "0/10 (headache 3/10)",
465
+ "GCS": "13 (E4 V3 M6)",
466
+ "BSL": "8.6 mmol/L",
467
+ },
468
+ "physical_exam": (
469
+ "Right facial droop (lower face). Right arm drift positive β€” arm falls within 10 seconds. "
470
+ "Right leg mild weakness. Speech dysarthric. No aphasia β€” comprehension intact. "
471
+ "NIHSS score: 8 (moderate stroke). Pupils equal and reactive. No neck stiffness. "
472
+ "Irregular rhythm on auscultation (AF)."
473
+ ),
474
+ "investigations": {
475
+ "CT Brain (non-contrast)": "No haemorrhage. Early ischaemic changes in left MCA territory.",
476
+ "CT Angiography": "Partial occlusion left middle cerebral artery (MCA)",
477
+ "NIHSS": "8 β€” moderate stroke",
478
+ "ECG": "Atrial fibrillation. Rate 88 bpm.",
479
+ "FBC": "Hb 128 g/L, Platelets 224 Γ— 10⁹/L",
480
+ "Coagulation": "INR 1.1 (apixaban β€” anti-Xa not routinely measured)",
481
+ "UEC": "Na 139, K 4.0, Cr 88 ΞΌmol/L",
482
+ "BSL": "8.6 mmol/L",
483
+ "Lipids": "LDL 3.4 mmol/L",
484
+ },
485
+ "medical_diagnosis": "Acute Ischaemic Stroke β€” Left MCA territory (NIHSS 8)",
486
+ "nursing_priorities": [
487
+ "TIME CRITICAL β€” establish onset-to-door time, activate stroke pathway",
488
+ "NIL BY MOUTH until formal swallow screen completed",
489
+ "Maintain BP 140–180 mmHg (do NOT lower aggressively pre-tPA)",
490
+ "Position: HOB 0Β° (flat) initially to maximise cerebral perfusion",
491
+ "Continuous neurological observations β€” NIHSS, GCS, pupils every 15 min",
492
+ "IV access Γ— 2 β€” bloods per stroke protocol",
493
+ "BSL monitoring β€” target 4–11 mmol/L (hypo/hyperglycaemia worsen outcomes)",
494
+ "Prepare for thrombolysis (tPA) or endovascular thrombectomy β€” if eligible",
495
+ ],
496
+ "nursing_diagnoses": [
497
+ {
498
+ "diagnosis": "Ineffective Cerebral Tissue Perfusion related to MCA occlusion",
499
+ "evidence": "NIHSS 8, right-sided weakness, facial droop, dysarthria, BP 186/104",
500
+ "goal": "No neurological deterioration; NIHSS improves or stabilises within 24 hours",
501
+ "interventions": [
502
+ "HOB flat (0Β°) to maintain cerebral perfusion pressure",
503
+ "Do NOT lower BP aggressively unless > 220 mmHg (or > 185 if tPA candidate)",
504
+ "15-minutely neuro obs: GCS, NIHSS, pupillary response",
505
+ "Monitor for signs of haemorrhagic transformation post-tPA: ↓GCS, new headache, vomiting",
506
+ "Maintain BSL 4–11 mmol/L",
507
+ ],
508
+ },
509
+ {
510
+ "diagnosis": "Risk for Aspiration related to dysphagia secondary to stroke",
511
+ "evidence": "Dysarthria, reduced GCS, neurological deficits β€” high aspiration risk",
512
+ "goal": "No aspiration event; formal swallow screen completed before any oral intake",
513
+ "interventions": [
514
+ "NIL BY MOUTH until speech pathology swallow assessment",
515
+ "Position: lateral/semi-prone if vomiting risk",
516
+ "NG tube for medications and hydration if swallow impaired",
517
+ "Oral suctioning available at bedside",
518
+ "Head of bed 30Β° once haemodynamic goals met",
519
+ ],
520
+ },
521
+ {
522
+ "diagnosis": "Impaired Physical Mobility related to right-sided hemiparesis",
523
+ "evidence": "Right arm weakness, right leg weakness, right facial droop",
524
+ "goal": "No skin breakdown; commence physiotherapy within 24 hours",
525
+ "interventions": [
526
+ "Pressure injury prevention: 2-hourly repositioning",
527
+ "Heel protectors applied",
528
+ "Limb positioning to prevent contractures",
529
+ "VTE prophylaxis per protocol",
530
+ "Early physiotherapy and occupational therapy referral",
531
+ ],
532
+ },
533
+ ],
534
+ "adpie": {
535
+ "assessment": (
536
+ "Subjective: Headache 3/10, confusion (knows name, not date). "
537
+ "Objective: Right facial droop, right arm/leg weakness, dysarthria, NIHSS 8, "
538
+ "BP 186/104, AF on ECG, CT β€” left MCA ischaemia, last known well 1.5 hours ago."
539
+ ),
540
+ "diagnosis": (
541
+ "1. Ineffective Cerebral Tissue Perfusion r/t MCA occlusion AEB NIHSS 8, hemiparesis.\n"
542
+ "2. Risk for Aspiration r/t dysphagia AEB dysarthria, reduced GCS.\n"
543
+ "3. Impaired Physical Mobility r/t hemiparesis AEB arm/leg weakness."
544
+ ),
545
+ "planning": (
546
+ "Activate stroke pathway β€” tPA within 4.5 hours of onset. "
547
+ "Prevent aspiration until swallow screen. "
548
+ "NIHSS monitoring every 15 min. Commence rehab within 24 hours."
549
+ ),
550
+ "implementation": (
551
+ "β€’ Stroke pathway activated β€” neurology notified at 09:48.\n"
552
+ "β€’ CT Brain completed at 10:02 β€” no haemorrhage confirmed.\n"
553
+ "β€’ tPA (alteplase) administered at 10:18 β€” door-to-needle time 33 minutes.\n"
554
+ "β€’ BP managed: avoided antihypertensives while tPA infusing.\n"
555
+ "β€’ Nil by mouth β€” NG tube inserted for medications.\n"
556
+ "β€’ Neurological observations every 15 minutes.\n"
557
+ "β€’ Speech pathology, physiotherapy, OT referrals placed."
558
+ ),
559
+ "evaluation": (
560
+ "At 24 hours: NIHSS improved to 4. Right arm strength improving. "
561
+ "Speech clearer. Swallow screen passed (modified diet). "
562
+ "No haemorrhagic transformation on repeat CT. Transferred to stroke unit."
563
+ ),
564
+ },
565
+ },
566
+
567
+ # ── 5. SEPSIS ─────────────────────────────────────────────────────────
568
+ {
569
+ "id": "case_005",
570
+ "title": "Septic Shock β€” Urinary Source",
571
+ "category": "Multi-system / Infectious",
572
+ "difficulty": "Advanced",
573
+ "tags": ["sepsis", "septic shock", "infection", "qSOFA", "Sepsis-3", "antibiotics"],
574
+ "learning_objectives": [
575
+ "Apply Sepsis-3 criteria and qSOFA screening tool",
576
+ "Implement Sepsis 1-Hour Bundle (blood cultures, antibiotics, fluids)",
577
+ "Monitor haemodynamic response to resuscitation",
578
+ "Understand vasopressor use in septic shock",
579
+ "Prevent secondary complications: AKI, ventilator-associated pneumonia",
580
+ ],
581
+ "patient": {
582
+ "name": "Mr. Harold Stevens",
583
+ "age": 78,
584
+ "gender": "Male",
585
+ "weight_kg": 68,
586
+ "height_cm": 170,
587
+ "allergies": ["Cephalosporins (anaphylaxis)"],
588
+ "pmhx": ["Benign Prostatic Hyperplasia", "Chronic Kidney Disease (Stage 3)", "Hypertension", "Type 2 Diabetes"],
589
+ "medications": [
590
+ "Tamsulosin 0.4 mg nocte",
591
+ "Metformin 500 mg BD (held β€” CKD)",
592
+ "Ramipril 5 mg daily",
593
+ "Insulin glargine 14 units nocte",
594
+ ],
595
+ "social": "Retired farmer. Lives with wife. IDC in situ (inserted 4 days ago at GP for urinary retention).",
596
+ "family_hx": "Nil relevant.",
597
+ },
598
+ "presentation": (
599
+ "Mr. Stevens is brought to ED by his wife at 16:20. She reports he has been 'not himself' "
600
+ "for 24 hours β€” drowsy, confused, not eating. He developed rigors and fever this afternoon. "
601
+ "Urine from his IDC is cloudy and malodorous. Wife says he was well last week."
602
+ ),
603
+ "vitals": {
604
+ "BP": "82/50 mmHg",
605
+ "HR": "118 bpm",
606
+ "RR": "24 breaths/min",
607
+ "SpO2": "94% on room air",
608
+ "Temp": "39.4Β°C",
609
+ "Pain": "3/10 (suprapubic)",
610
+ "GCS": "12 (E3 V3 M6)",
611
+ "BSL": "18.6 mmol/L",
612
+ "UO": "20 mL over last 2 hours (oliguria)",
613
+ },
614
+ "physical_exam": (
615
+ "Patient appears unwell, flushed and diaphoretic. Confused β€” knows name only. "
616
+ "Warm, vasodilated peripheries. Capillary refill 3 seconds. Suprapubic tenderness. "
617
+ "IDC in situ β€” bag contains 100 mL cloudy, dark urine. "
618
+ "No crepitations. Abdomen soft. No rigidity."
619
+ ),
620
+ "investigations": {
621
+ "qSOFA score": "3/3 (↓BP, ↑RR, altered mentation) β€” HIGH RISK SEPSIS",
622
+ "SOFA score": "8 β€” organ dysfunction Γ— 3 systems",
623
+ "Lactate": "4.8 mmol/L (↑↑ β€” > 4 = septic shock)",
624
+ "FBC": "WCC 24.6 Γ— 10⁹/L, Neutrophils 22.1, Hb 106 g/L",
625
+ "CRP": "348 mg/L (↑↑)",
626
+ "Procalcitonin": "28.4 ng/mL (↑↑)",
627
+ "UEC": "Na 134, K 5.2, Cr 248 ΞΌmol/L (↑ β€” baseline Cr 132), Urea 22.4",
628
+ "LFTs": "ALT mildly elevated",
629
+ "Coagulation": "PT 16.2 s, APTT 42 s, Fibrinogen 1.8 g/L (↓)",
630
+ "Blood cultures Γ— 2": "Pending (collected before antibiotics)",
631
+ "MSU/catheter urine": "WCC > 10⁸, Gram-negative rods (presumed E. coli)",
632
+ "CXR": "No consolidation. Mild cardiomegaly.",
633
+ },
634
+ "medical_diagnosis": "Septic Shock β€” catheter-associated urinary tract infection (CAUTI)",
635
+ "nursing_priorities": [
636
+ "SEPSIS PATHWAY β€” 1-HOUR BUNDLE",
637
+ "Blood cultures Γ— 2 sets BEFORE antibiotics",
638
+ "IV fluid resuscitation: 30 mL/kg crystalloid (0.9% NaCl or Hartmann's) STAT",
639
+ "IV antibiotics WITHIN 1 HOUR β€” per allergy/local protocol (avoid cephalosporins)",
640
+ "Measure serial lactates β€” target < 2 mmol/L",
641
+ "IDC output β€” strict hourly urine output (target β‰₯ 0.5 mL/kg/hr)",
642
+ "Consider vasopressors (noradrenaline) if MAP < 65 mmHg despite fluids",
643
+ "Continuous cardiac monitoring, ICU review",
644
+ ],
645
+ "nursing_diagnoses": [
646
+ {
647
+ "diagnosis": "Ineffective Tissue Perfusion (multi-organ) related to septic shock",
648
+ "evidence": "BP 82/50, lactate 4.8, oliguria 10 mL/hr, GCS 12, Cr 248",
649
+ "goal": "MAP β‰₯ 65 mmHg, lactate < 2, UO β‰₯ 0.5 mL/kg/hr within 3 hours",
650
+ "interventions": [
651
+ "IV 0.9% NaCl 30 mL/kg (2040 mL) over 3 hours β€” reassess after each 500 mL",
652
+ "Noradrenaline infusion via central line if MAP < 65 after fluids",
653
+ "2-hourly lactate clearance measurement",
654
+ "Strict hourly urine output β€” target β‰₯ 34 mL/hr",
655
+ "Continuous cardiac monitoring",
656
+ ],
657
+ },
658
+ {
659
+ "diagnosis": "Hyperthermia related to systemic infection",
660
+ "evidence": "Temp 39.4Β°C, rigors, WCC 24.6, CRP 348",
661
+ "goal": "Temperature < 38.5Β°C within 2 hours",
662
+ "interventions": [
663
+ "Administer paracetamol 1 g IV/PO per protocol",
664
+ "Cooling blanket or ice packs to axillae/groin",
665
+ "Ensure adequate hydration",
666
+ "Temperature monitoring every 1–2 hours",
667
+ "Remove IDC and replace with new IDC or suprapubic catheter",
668
+ ],
669
+ },
670
+ ],
671
+ "adpie": {
672
+ "assessment": (
673
+ "Subjective: 24-hour confusion, anorexia, rigors, 4-day IDC for urinary retention. "
674
+ "Objective: BP 82/50, HR 118, Temp 39.4, GCS 12, lactate 4.8, qSOFA 3, "
675
+ "WCC 24.6, Cr 248 (AKI), cloudy malodorous urine."
676
+ ),
677
+ "diagnosis": (
678
+ "1. Ineffective Tissue Perfusion r/t septic shock AEB BP 82/50, lactate 4.8, oliguria.\n"
679
+ "2. Hyperthermia r/t systemic infection AEB Temp 39.4, rigors, WCC 24.6.\n"
680
+ "3. Acute Confusion r/t septic encephalopathy AEB GCS 12."
681
+ ),
682
+ "planning": (
683
+ "1-hour sepsis bundle. MAP β‰₯ 65 within 3 hours. Lactate clearance β‰₯ 10%. "
684
+ "Appropriate antibiotics within 1 hour. Source control (IDC review)."
685
+ ),
686
+ "implementation": (
687
+ "β€’ Blood cultures Γ— 2 collected immediately.\n"
688
+ "β€’ Meropenem 1 g IV (avoiding cephalosporins per allergy) within 45 minutes.\n"
689
+ "β€’ IV 0.9% NaCl 2000 mL over 3 hours commenced.\n"
690
+ "β€’ Noradrenaline 0.05 mcg/kg/min commenced via central line β€” MAP improved to 68.\n"
691
+ "β€’ IDC removed; new IDC inserted; urine sent for C&S.\n"
692
+ "β€’ ICU team notified; patient transferred to ICU.\n"
693
+ "β€’ Family updated and support provided."
694
+ ),
695
+ "evaluation": (
696
+ "At 3 hours: MAP 68, HR 102, lactate 2.8 (↓ β€” clearance 42%), UO 38 mL/hr. "
697
+ "At 12 hours: lactate 1.4, UO improving, GCS 14. "
698
+ "Blood cultures: E. coli β€” sensitive to meropenem. Antibiotics rationalised."
699
+ ),
700
+ },
701
+ },
702
+
703
+ # ── 6. SURGICAL β€” POST-OP HIP FRACTURE ────────────────────────────────
704
+ {
705
+ "id": "case_006",
706
+ "title": "Post-Operative Neck of Femur Fracture",
707
+ "category": "Musculoskeletal / Surgical",
708
+ "difficulty": "Beginner",
709
+ "tags": ["hip fracture", "NOF", "orthopaedic", "post-op", "elderly", "falls"],
710
+ "learning_objectives": [
711
+ "Perform post-operative assessment using ABCDE approach",
712
+ "Manage post-operative pain using multimodal analgesia",
713
+ "Implement VTE prophylaxis and pressure injury prevention",
714
+ "Promote early mobilisation β€” key to recovery",
715
+ "Prevent delirium in elderly post-operative patients",
716
+ ],
717
+ "patient": {
718
+ "name": "Mrs. Betty Kowalski",
719
+ "age": 83,
720
+ "gender": "Female",
721
+ "weight_kg": 56,
722
+ "height_cm": 154,
723
+ "allergies": ["Codeine (nausea/vomiting)", "Latex"],
724
+ "pmhx": ["Osteoporosis", "Hypertension", "Mild cognitive impairment", "Hypothyroidism", "Urinary incontinence"],
725
+ "medications": [
726
+ "Alendronate 70 mg weekly",
727
+ "Calcium carbonate 600 mg BD",
728
+ "Vitamin D 1000 IU daily",
729
+ "Perindopril 5 mg daily",
730
+ "Levothyroxine 50 mcg daily",
731
+ ],
732
+ "social": "Widow. Lives alone in home unit. Daughter visits daily. Independent with frame. 1 previous fall this year.",
733
+ "family_hx": "Mother had hip fracture at age 85.",
734
+ },
735
+ "presentation": (
736
+ "Mrs. Kowalski returned from theatre at 14:30 following right hemiarthroplasty (hip replacement) "
737
+ "for a right neck of femur fracture sustained in a fall at home yesterday. "
738
+ "The procedure was performed under spinal anaesthesia with sedation. She is now in the "
739
+ "orthopaedic ward. She appears drowsy but rousable, and complaining of hip pain."
740
+ ),
741
+ "vitals": {
742
+ "BP": "108/66 mmHg",
743
+ "HR": "88 bpm",
744
+ "RR": "16 breaths/min",
745
+ "SpO2": "94% on room air",
746
+ "Temp": "36.2Β°C",
747
+ "Pain": "7/10 (right hip)",
748
+ "GCS": "14 (drowsy but oriented to person and place)",
749
+ "UO": "IDC in situ β€” 40 mL since returning from theatre (2 hours)",
750
+ },
751
+ "physical_exam": (
752
+ "Patient drowsy but rousable β€” responds to voice. Right hip: dressing intact, "
753
+ "wound drain in situ with 80 mL haemoserous drainage. Right leg warm, cap refill 2 sec. "
754
+ "Pedal pulses present. No distal neurovascular deficit. "
755
+ "Left leg: normal. Abdomen soft. Bowel sounds present."
756
+ ),
757
+ "investigations": {
758
+ "Post-op FBC": "Hb 86 g/L (↓ from pre-op 112 g/L β€” surgical blood loss)",
759
+ "UEC": "Na 138, K 3.8, Cr 92 ΞΌmol/L",
760
+ "Coagulation": "INR 1.2",
761
+ "CXR": "Clear. No consolidation.",
762
+ "Right hip X-ray": "Right hemiarthroplasty in situ β€” satisfactory position",
763
+ },
764
+ "medical_diagnosis": "Post-operative Day 0 β€” Right hemiarthroplasty for right NOF fracture",
765
+ "nursing_priorities": [
766
+ "ABCDE post-operative assessment on return from theatre",
767
+ "Multimodal pain management (paracetamol + NSAID + opioid PRN) β€” avoid codeine",
768
+ "VTE prophylaxis: TEDS + enoxaparin (commence Day 1) + early mobilisation",
769
+ "Pressure injury prevention: 2-hourly repositioning, heel protectors",
770
+ "Delirium prevention: reorientation, familiar objects, glasses/hearing aids",
771
+ "Wound drain monitoring β€” notify if > 200 mL/hour",
772
+ "Neurovascular observations right leg every 2 hours Γ— 12 hours",
773
+ "IDC output β€” may remove IDC at 24–48 hours to reduce UTI risk",
774
+ ],
775
+ "nursing_diagnoses": [
776
+ {
777
+ "diagnosis": "Acute Pain related to surgical trauma (right hip)",
778
+ "evidence": "Pain 7/10 right hip, facial grimacing, reluctance to move",
779
+ "goal": "Pain ≀ 3/10 at rest and ≀ 5/10 with movement within 1 hour",
780
+ "interventions": [
781
+ "Administer paracetamol 1 g QID (if not already given intra-op)",
782
+ "Administer opioid analgesia PRN per protocol (avoid codeine β€” allergy)",
783
+ "Position: supine with pillow between knees (hip precautions)",
784
+ "Apply ice pack wrapped in cloth to right hip",
785
+ "Reassess pain 30–60 minutes after analgesia",
786
+ ],
787
+ },
788
+ {
789
+ "diagnosis": "Risk for Perioperative Positioning Injury / Neurovascular Compromise",
790
+ "evidence": "Post-surgical hip β€” at risk for dislocation, DVT, neurovascular compromise",
791
+ "goal": "No distal neurovascular deficit; no signs of DVT throughout admission",
792
+ "interventions": [
793
+ "Neurovascular observations (5 Ps) right leg every 2 hours",
794
+ "Maintain hip precautions: no hip flexion > 90Β°, no adduction, no internal rotation",
795
+ "TEDS stockings (check for latex allergy β€” use non-latex TEDs)",
796
+ "Enoxaparin per protocol starting Day 1",
797
+ "Early mobilisation with physiotherapy Day 1",
798
+ ],
799
+ },
800
+ {
801
+ "diagnosis": "Risk for Acute Confusion (Delirium) related to anaesthesia, pain, unfamiliar environment",
802
+ "evidence": "Age 83, mild cognitive impairment, post-op drowsiness, pain",
803
+ "goal": "No delirium episode; patient remains oriented Γ— 3",
804
+ "interventions": [
805
+ "Ensure glasses and hearing aids are available",
806
+ "Frequent reorientation β€” name, location, date, what happened",
807
+ "Maintain normal sleep-wake cycle β€” avoid unnecessary night interventions",
808
+ "Avoid benzodiazepines and anticholinergic medications",
809
+ "Encourage family presence",
810
+ "Adequate pain management β€” uncontrolled pain is a delirium trigger",
811
+ ],
812
+ },
813
+ ],
814
+ "adpie": {
815
+ "assessment": (
816
+ "Subjective: Pain 7/10 right hip. Drowsy post-op. "
817
+ "Objective: BP 108/66, SpOβ‚‚ 94%, Hb 86 (↓), wound drain 80 mL, "
818
+ "GCS 14, right hip dressing intact, no neurovascular deficit."
819
+ ),
820
+ "diagnosis": (
821
+ "1. Acute Pain r/t surgical trauma AEB pain 7/10, facial grimacing.\n"
822
+ "2. Risk for Neurovascular Compromise r/t post-op hip surgery.\n"
823
+ "3. Risk for Delirium r/t age, cognitive impairment, anaesthesia."
824
+ ),
825
+ "planning": (
826
+ "Pain ≀ 3/10 within 1 hour. No neurovascular compromise. "
827
+ "Mobilise with physio Day 1. Delirium prevention strategy in place."
828
+ ),
829
+ "implementation": (
830
+ "β€’ Oβ‚‚ 2 L/min via nasal prongs β€” SpOβ‚‚ improved to 97%.\n"
831
+ "β€’ Paracetamol 1 g IV given; oxycodone 2.5 mg PO given β€” pain 4/10 at 60 min.\n"
832
+ "β€’ Non-latex TEDS applied. Hip precautions explained.\n"
833
+ "β€’ Glasses and hearing aid retrieved from bedside. Family contacted.\n"
834
+ "β€’ Neurovascular obs every 2 hours β€” all normal.\n"
835
+ "β€’ Wound drain output charted hourly."
836
+ ),
837
+ "evaluation": (
838
+ "Pain 4/10 at 1 hour, 3/10 at 2 hours. SpOβ‚‚ 97%. Neurovascular obs intact. "
839
+ "No delirium at 12 hours β€” patient oriented Γ— 3. "
840
+ "Day 1: mobilised to chair with physio. Day 2: walking with frame."
841
+ ),
842
+ },
843
+ },
844
+
845
+ # ── 7. MATERNAL β€” PREECLAMPSIA ─────────────────────────────────────────
846
+ {
847
+ "id": "case_007",
848
+ "title": "Severe Preeclampsia",
849
+ "category": "Maternal / Obstetric",
850
+ "difficulty": "Advanced",
851
+ "tags": ["preeclampsia", "obstetric", "maternal", "eclampsia", "magnesium", "hypertension"],
852
+ "learning_objectives": [
853
+ "Distinguish preeclampsia from gestational hypertension",
854
+ "Recognise severe features: BP > 160/110, proteinuria, headache",
855
+ "Administer magnesium sulphate safely for seizure prophylaxis",
856
+ "Monitor fetal wellbeing: CTG interpretation basics",
857
+ "Know antihypertensive options in pregnancy (labetalol, hydralazine)",
858
+ ],
859
+ "patient": {
860
+ "name": "Ms. Yara Okafor",
861
+ "age": 32,
862
+ "gender": "Female",
863
+ "weight_kg": 82,
864
+ "height_cm": 167,
865
+ "allergies": ["NKDA"],
866
+ "pmhx": ["Primigravida", "No previous hypertension", "No pre-existing medical conditions"],
867
+ "medications": ["Folic acid 500 mcg daily (ceased at 12/40)", "Iron supplements"],
868
+ "social": "32-year-old G1P0, 36 weeks gestation. Works as a nurse. Lives with partner.",
869
+ "family_hx": "Mother had preeclampsia in both pregnancies.",
870
+ },
871
+ "presentation": (
872
+ "Ms. Okafor presents to the maternity assessment unit at 11:00 with a frontal headache "
873
+ "rated 7/10, visual disturbances ('flashing lights'), and epigastric pain since this morning. "
874
+ "She is 36+2 weeks gestation. Her midwife took her BP at home and it was 170/110. "
875
+ "Her ankles have been very swollen for the past week."
876
+ ),
877
+ "vitals": {
878
+ "BP": "172/114 mmHg (severe range β€” repeated Γ— 2, 15 min apart)",
879
+ "HR": "96 bpm",
880
+ "RR": "18 breaths/min",
881
+ "SpO2": "98% on room air",
882
+ "Temp": "37.0Β°C",
883
+ "Pain": "7/10 (frontal headache + epigastric)",
884
+ "Reflexes": "Hyperreflexia 3+ bilaterally, clonus present (3 beats)",
885
+ },
886
+ "physical_exam": (
887
+ "Alert and distressed. Generalised oedema β€” face, hands, ankles. "
888
+ "Hyperreflexia with 3-beat clonus β€” eclampsia risk. "
889
+ "Epigastric tenderness on palpation. "
890
+ "Uterine fundus at 36 cm. Fetal heart rate: 148 bpm, reactive."
891
+ ),
892
+ "investigations": {
893
+ "Urine dipstick": "Protein 3+ (significant proteinuria)",
894
+ "Spot PCR": "450 mg/mmol (↑↑ severe, normal < 30)",
895
+ "BP trend": "Two readings β‰₯ 160/110, 15 min apart β€” SEVERE range",
896
+ "FBC": "Hb 112 g/L, Platelets 98 Γ— 10⁹/L (↓ β€” HELLP concern)",
897
+ "LFTs": "ALT 68 U/L (↑), AST 74 U/L (↑), LDH 420 U/L (↑)",
898
+ "UEC": "Cr 98 ΞΌmol/L, Uric acid elevated",
899
+ "Coagulation": "PT/APTT normal, fibrinogen 3.2 g/L",
900
+ "CTG": "Reactive β€” fetal wellbeing reassuring at this time",
901
+ "Ultrasound": "Fetus 36/40, estimated fetal weight 2.8 kg, reduced amniotic fluid",
902
+ },
903
+ "medical_diagnosis": "Severe Preeclampsia with severe features (36+2 weeks) Β± evolving HELLP",
904
+ "nursing_priorities": [
905
+ "URGENT β€” notify obstetric registrar/MO immediately",
906
+ "Continuous BP monitoring every 5–15 minutes",
907
+ "IV antihypertensives: labetalol IV or hydralazine IV to bring BP < 160/110",
908
+ "Magnesium sulphate: 4 g loading dose IV over 15–20 min β€” eclampsia prophylaxis",
909
+ "Strict fluid balance β€” IDC for hourly urine output",
910
+ "Continuous CTG monitoring",
911
+ "Magnesium toxicity monitoring: urine output, RR, reflexes",
912
+ "Prepare for delivery β€” discuss timing with obstetric team",
913
+ ],
914
+ "nursing_diagnoses": [
915
+ {
916
+ "diagnosis": "Risk for Maternal Injury (Seizure/Stroke) related to severe preeclampsia",
917
+ "evidence": "BP 172/114, hyperreflexia, clonus, headache, visual disturbances",
918
+ "goal": "No eclamptic seizure; BP < 160/110 within 1 hour",
919
+ "interventions": [
920
+ "Administer magnesium sulphate 4 g IV over 15–20 min loading dose",
921
+ "Maintain maintenance MgSOβ‚„ infusion 1–2 g/hr",
922
+ "Antihypertensives: labetalol IV per protocol (SBP target < 160, DBP target < 110)",
923
+ "Seizure precautions: cot sides up, suction at bedside, IV access confirmed",
924
+ "Dark quiet room β€” minimise stimulation",
925
+ "Monitor: RR β‰₯ 12, UO β‰₯ 25 mL/hr, reflexes β€” before each MgSOβ‚„ dose",
926
+ ],
927
+ },
928
+ {
929
+ "diagnosis": "Risk for Fetal Distress related to placental insufficiency",
930
+ "evidence": "Hypertension affecting uteroplacental blood flow, oligohydramnios",
931
+ "goal": "Reassuring CTG; plan for delivery within 24–48 hours",
932
+ "interventions": [
933
+ "Continuous CTG monitoring",
934
+ "Left lateral position β€” maximises placental perfusion",
935
+ "Report any late decelerations, reduced variability, or prolonged bradycardia immediately",
936
+ "Prepare for emergency LSCS if fetal compromise",
937
+ "Notify neonatal team β€” preterm delivery expected",
938
+ ],
939
+ },
940
+ ],
941
+ "adpie": {
942
+ "assessment": (
943
+ "Subjective: Frontal headache 7/10, visual disturbances, epigastric pain, facial swelling. "
944
+ "Objective: BP 172/114 (Γ—2), proteinuria 3+, platelets 98, LFTs elevated (HELLP), "
945
+ "hyperreflexia, clonus, 36+2 weeks gestation."
946
+ ),
947
+ "diagnosis": (
948
+ "1. Risk for Maternal Injury r/t severe preeclampsia AEB hypertension, hyperreflexia, clonus.\n"
949
+ "2. Risk for Fetal Distress r/t placental insufficiency AEB oligohydramnios.\n"
950
+ "3. Anxiety r/t acute illness and pregnancy AEB distress and fear for baby."
951
+ ),
952
+ "planning": (
953
+ "BP < 160/110 within 1 hour. No seizure. "
954
+ "Continuous CTG monitoring. Delivery planning with obstetric team."
955
+ ),
956
+ "implementation": (
957
+ "β€’ Obstetric registrar notified at 11:05 β€” reviewed at 11:10.\n"
958
+ "β€’ Labetalol 20 mg IV β€” BP 158/105 at 20 min. Repeat dose β†’ BP 148/98.\n"
959
+ "β€’ MgSOβ‚„ 4 g IV over 20 min loading dose; maintenance 2 g/hr.\n"
960
+ "β€’ IDC inserted β€” UO 35 mL/hr. Continuous CTG β€” reactive.\n"
961
+ "β€’ Neonatal team notified. Betamethasone for fetal lung maturity given.\n"
962
+ "β€’ Partner informed; birth plan discussed."
963
+ ),
964
+ "evaluation": (
965
+ "BP stabilised 148/96 over next 2 hours. No seizure. CTG remained reactive. "
966
+ "Decision for induction of labour at 37+0 weeks (4 days later after monitoring). "
967
+ "Delivered healthy 2.9 kg boy via vaginal delivery with epidural. "
968
+ "MgSOβ‚„ continued 24 hours post-partum."
969
+ ),
970
+ },
971
+ },
972
+
973
+ # ── 8. PAEDIATRIC β€” FEBRILE SEIZURE ───────────────────────────────────
974
+ {
975
+ "id": "case_008",
976
+ "title": "Paediatric Febrile Convulsion",
977
+ "category": "Paediatric",
978
+ "difficulty": "Beginner",
979
+ "tags": ["paediatric", "febrile seizure", "child", "fever", "convulsion", "airway"],
980
+ "learning_objectives": [
981
+ "Differentiate simple vs complex febrile seizure",
982
+ "Manage acute seizure: DRSABCD, airway positioning, benzodiazepines",
983
+ "Identify and treat the underlying febrile illness",
984
+ "Provide parent education and seizure first-aid teaching",
985
+ "Understand when to investigate for meningitis",
986
+ ],
987
+ "patient": {
988
+ "name": "Liam Nguyen",
989
+ "age": 2,
990
+ "gender": "Male",
991
+ "weight_kg": 12,
992
+ "height_cm": 88,
993
+ "allergies": ["NKDA"],
994
+ "pmhx": ["Nil significant", "No previous seizures", "Normal development"],
995
+ "medications": ["Nil regular"],
996
+ "social": "Lives with both parents and older sister. Fully vaccinated. Attends childcare 3 days/week.",
997
+ "family_hx": "Father had two febrile convulsions as a toddler.",
998
+ },
999
+ "presentation": (
1000
+ "Liam's parents call an ambulance after witnessing a 2-minute tonic-clonic seizure at home. "
1001
+ "He has had a runny nose and fever for 24 hours β€” temperature was 39.2Β°C at home. "
1002
+ "The seizure was generalised and has now stopped. Liam is in the post-ictal phase β€” "
1003
+ "drowsy but breathing. Parents are very distressed."
1004
+ ),
1005
+ "vitals": {
1006
+ "BP": "Not measured initially (crying/post-ictal)",
1007
+ "HR": "148 bpm",
1008
+ "RR": "32 breaths/min",
1009
+ "SpO2": "95% (improving β€” was 90% immediately post-seizure)",
1010
+ "Temp": "39.8Β°C (axillary)",
1011
+ "Pain": "Unable to assess (post-ictal)",
1012
+ "GCS": "11 (E3 V3 M5 β€” improving)",
1013
+ "Weight": "12 kg",
1014
+ },
1015
+ "physical_exam": (
1016
+ "Post-ictal 2-year-old. Drowsy but gradually becoming more alert over 20 minutes. "
1017
+ "Red, inflamed tympanic membranes bilaterally. Rhinorrhoea. Clear chest. "
1018
+ "No rash. No petechiae. No neck stiffness. Anterior fontanelle normal. "
1019
+ "Pupils equal and reactive. No focal neurological deficit once fully recovered."
1020
+ ),
1021
+ "investigations": {
1022
+ "Temp": "39.8Β°C",
1023
+ "BSL": "6.2 mmol/L (normal)",
1024
+ "FBC": "WCC 16.8 (↑ β€” likely viral), Hb 112 g/L",
1025
+ "CRP": "22 mg/L (mildly elevated)",
1026
+ "UEC": "Normal",
1027
+ "LP (lumbar puncture)": "NOT indicated β€” simple febrile seizure in child > 12 months, no meningism",
1028
+ "EEG": "NOT indicated for first simple febrile seizure",
1029
+ "CT Brain": "NOT indicated β€” no focal deficit, simple febrile seizure",
1030
+ },
1031
+ "medical_diagnosis": "Simple Febrile Convulsion secondary to bilateral otitis media",
1032
+ "nursing_priorities": [
1033
+ "DURING SEIZURE: DRSABCD β€” DO NOT restrain",
1034
+ "Position: lateral/recovery position β€” airway protection",
1035
+ "Timing: note seizure start time (if > 5 min β€” IV midazolam or diazepam)",
1036
+ "Post-ictal: airway positioning, Oβ‚‚ if SpOβ‚‚ < 94%, monitoring",
1037
+ "Treat fever: paracetamol 15 mg/kg PO/PR",
1038
+ "Identify fever source (bilateral OM β€” amoxicillin if bacterial)",
1039
+ "Parent education: seizure first aid, 999 criteria, recurrence risk",
1040
+ "Discharge planning: written information, follow-up",
1041
+ ],
1042
+ "nursing_diagnoses": [
1043
+ {
1044
+ "diagnosis": "Risk for Aspiration related to seizure and reduced consciousness",
1045
+ "evidence": "Post-ictal GCS 11, SpOβ‚‚ 95%, seizure just ceased",
1046
+ "goal": "Maintain patent airway; SpOβ‚‚ β‰₯ 95%; full recovery of consciousness within 30 min",
1047
+ "interventions": [
1048
+ "Position: lateral/recovery position β€” maintains airway",
1049
+ "Suction available at bedside",
1050
+ "Oβ‚‚ via face mask if SpOβ‚‚ < 94%",
1051
+ "Nil by mouth until fully alert (GCS 15)",
1052
+ "Monitor SpOβ‚‚ continuously for 30 minutes",
1053
+ ],
1054
+ },
1055
+ {
1056
+ "diagnosis": "Hyperthermia related to bilateral otitis media (infection)",
1057
+ "evidence": "Temp 39.8Β°C, inflamed tympanic membranes, rhinorrhoea, WCC 16.8",
1058
+ "goal": "Temperature < 38.5Β°C within 1 hour",
1059
+ "interventions": [
1060
+ "Paracetamol 15 mg/kg = 180 mg PO/PR",
1061
+ "Remove excess clothing, fan",
1062
+ "Tepid sponging (not cold water β€” may cause shivering, increase temp)",
1063
+ "Adequate hydration β€” oral fluids when fully alert",
1064
+ "Amoxicillin if bacterial OM suspected per medical order",
1065
+ ],
1066
+ },
1067
+ {
1068
+ "diagnosis": "Parental Anxiety related to witnessed seizure in child",
1069
+ "evidence": "Parents visibly distressed, asking 'will it happen again?'",
1070
+ "goal": "Parents verbalise understanding of febrile seizures and first aid actions",
1071
+ "interventions": [
1072
+ "Explain febrile seizures in simple, calm language",
1073
+ "Teach seizure first aid: recovery position, timing, when to call 000",
1074
+ "Reassure: simple febrile seizures do not cause brain damage",
1075
+ "Provide written information leaflet",
1076
+ "Discuss recurrence risk (~30%) and that fever does not need to be treated aggressively to prevent seizures",
1077
+ ],
1078
+ },
1079
+ ],
1080
+ "adpie": {
1081
+ "assessment": (
1082
+ "Subjective (parents): 2-min tonic-clonic seizure at home, 24-hr fever, runny nose. "
1083
+ "Father had childhood febrile seizures. "
1084
+ "Objective: Temp 39.8Β°C, GCS 11 (post-ictal, improving), bilateral OM, "
1085
+ "SpOβ‚‚ 95%, WCC 16.8, simple febrile seizure (< 15 min, generalised, single)."
1086
+ ),
1087
+ "diagnosis": (
1088
+ "1. Risk for Aspiration r/t post-ictal reduced consciousness.\n"
1089
+ "2. Hyperthermia r/t bilateral otitis media AEB Temp 39.8Β°C.\n"
1090
+ "3. Parental Anxiety r/t witnessed seizure."
1091
+ ),
1092
+ "planning": (
1093
+ "Airway safety maintained. Temperature < 38.5Β°C within 1 hour. "
1094
+ "Full neurological recovery within 30 min. Parents confident in first aid before discharge."
1095
+ ),
1096
+ "implementation": (
1097
+ "β€’ Liam positioned in lateral recovery position on arrival.\n"
1098
+ "β€’ SpOβ‚‚ improved to 98% without Oβ‚‚ within 5 minutes.\n"
1099
+ "β€’ Paracetamol 180 mg PR given β€” temp 38.6Β°C at 1 hour.\n"
1100
+ "β€’ GP called β€” amoxicillin prescribed for bilateral OM.\n"
1101
+ "β€’ GCS 15 within 25 minutes post-ictal β€” Liam smiling and sitting up.\n"
1102
+ "β€’ Parents taught seizure first aid; written information provided."
1103
+ ),
1104
+ "evaluation": (
1105
+ "Liam fully alert at 30 minutes. Temp 38.4Β°C at 1 hour. SpOβ‚‚ 99%. "
1106
+ "Discharged home after 4 hours observation. "
1107
+ "Parents demonstrated correct seizure first aid. Follow-up with GP in 2 days."
1108
+ ),
1109
+ },
1110
+ },
1111
+
1112
+ # ── 9. MENTAL HEALTH β€” OVERDOSE ───────────────────────────────────────
1113
+ {
1114
+ "id": "case_009",
1115
+ "title": "Paracetamol Overdose β€” Deliberate Self-Harm",
1116
+ "category": "Mental Health / Toxicology",
1117
+ "difficulty": "Intermediate",
1118
+ "tags": ["overdose", "paracetamol", "mental health", "self-harm", "NAC", "toxicology"],
1119
+ "learning_objectives": [
1120
+ "Manage acute paracetamol overdose using the Rumack-Matthew nomogram",
1121
+ "Administer N-acetylcysteine (NAC) safely",
1122
+ "Perform a risk assessment for deliberate self-harm",
1123
+ "Demonstrate therapeutic communication with mental health patients",
1124
+ "Understand mandatory reporting and duty of care obligations",
1125
+ ],
1126
+ "patient": {
1127
+ "name": "Mx. Alex Kim",
1128
+ "age": 22,
1129
+ "gender": "Non-binary (they/them)",
1130
+ "weight_kg": 67,
1131
+ "height_cm": 172,
1132
+ "allergies": ["NKDA"],
1133
+ "pmhx": ["Major Depressive Disorder", "Previous overdose 18 months ago"],
1134
+ "medications": ["Sertraline 100 mg daily"],
1135
+ "social": "University student. Shares house with friends. Recently broke up with partner. Support worker engaged. Family not yet notified per patient request.",
1136
+ "family_hx": "Mother has depression.",
1137
+ },
1138
+ "presentation": (
1139
+ "Alex presents to ED at 02:30 brought by a friend who found an empty paracetamol packet "
1140
+ "(30 Γ— 500 mg = 15 g) and a note. Alex is alert and cooperative. They report taking all "
1141
+ "the tablets approximately 3 hours ago with alcohol. They state 'I wanted to disappear'. "
1142
+ "Alex is tearful but not acutely agitated."
1143
+ ),
1144
+ "vitals": {
1145
+ "BP": "118/74 mmHg",
1146
+ "HR": "96 bpm",
1147
+ "RR": "16 breaths/min",
1148
+ "SpO2": "98% on room air",
1149
+ "Temp": "36.9Β°C",
1150
+ "Pain": "2/10 (mild nausea)",
1151
+ "GCS": "15",
1152
+ },
1153
+ "physical_exam": (
1154
+ "Alert and oriented Γ— 3. Tearful, cooperative. No jaundice. Abdomen soft, mild "
1155
+ "right upper quadrant tenderness. No crepitations. Pupils equal and reactive. "
1156
+ "No needle marks. Alcohol on breath."
1157
+ ),
1158
+ "investigations": {
1159
+ "Paracetamol level (4h post-ingestion)": "185 mg/L β€” ABOVE treatment line on nomogram (treat)",
1160
+ "LFTs": "ALT 42 U/L (normal β€” too early for hepatotoxicity), Bili normal",
1161
+ "INR": "1.2 (normal β€” will rise if hepatotoxicity develops)",
1162
+ "UEC": "Na 139, K 4.0, Cr 82 ΞΌmol/L",
1163
+ "FBC": "Normal",
1164
+ "Blood alcohol": "0.08% (present β€” increases hepatotoxicity risk)",
1165
+ "BSL": "5.6 mmol/L",
1166
+ "Urine drug screen": "Positive: alcohol; negative for opioids, benzodiazepines",
1167
+ },
1168
+ "medical_diagnosis": "Paracetamol overdose (15 g, 3 hours ago) above treatment line β€” commence NAC",
1169
+ "nursing_priorities": [
1170
+ "Commence N-acetylcysteine (NAC) infusion per protocol β€” do not delay",
1171
+ "LFTs, INR, creatinine monitoring every 4–8 hours",
1172
+ "Safe room environment: remove sharps, ligature risks β€” 1:1 or enhanced observation",
1173
+ "Mental health risk assessment β€” psychiatric team referral",
1174
+ "Therapeutic communication β€” non-judgemental, trauma-informed approach",
1175
+ "Activated charcoal if < 1 hour post-ingestion (not applicable here β€” 3 hours)",
1176
+ "Social work involvement, safe discharge planning",
1177
+ ],
1178
+ "nursing_diagnoses": [
1179
+ {
1180
+ "diagnosis": "Risk for Liver Failure related to paracetamol hepatotoxicity",
1181
+ "evidence": "Paracetamol 185 mg/L above nomogram treatment line, co-ingestion with alcohol",
1182
+ "goal": "LFTs and INR remain normal; NAC infusion completed",
1183
+ "interventions": [
1184
+ "Commence NAC: Bag 1 β€” 150 mg/kg in 200 mL over 60 min",
1185
+ "Bag 2 β€” 50 mg/kg in 500 mL over 4 hours; Bag 3 β€” 100 mg/kg in 1000 mL over 16 hours",
1186
+ "Monitor LFTs, INR, Cr every 4–8 hours",
1187
+ "Monitor for NAC anaphylactoid reaction (first 15 min): rash, wheeze, flushing",
1188
+ "Antiemetics for nausea",
1189
+ ],
1190
+ },
1191
+ {
1192
+ "diagnosis": "Risk for Self-Harm related to major depressive disorder",
1193
+ "evidence": "Deliberate overdose, previous overdose history, suicide note found",
1194
+ "goal": "Patient remains safe; psychiatric review completed within 4 hours",
1195
+ "interventions": [
1196
+ "1:1 nursing observation β€” do not leave patient alone",
1197
+ "Remove all potential means of self-harm from environment",
1198
+ "Therapeutic communication: non-judgemental, empathetic, use they/them pronouns",
1199
+ "Psychiatric/mental health team consulted immediately",
1200
+ "Document risk assessment (CSSRS or institutional tool)",
1201
+ "Respect patient's request regarding family notification (within duty of care limits)",
1202
+ ],
1203
+ },
1204
+ ],
1205
+ "adpie": {
1206
+ "assessment": (
1207
+ "Subjective: Intentional paracetamol 15 g ingestion 3 hours ago with alcohol, "
1208
+ "suicide note, previous overdose, MDD. Objective: GCS 15, haemodynamically stable, "
1209
+ "paracetamol level 185 mg/L above treatment line, mild RUQ tenderness."
1210
+ ),
1211
+ "diagnosis": (
1212
+ "1. Risk for Liver Failure r/t paracetamol hepatotoxicity AEB level above nomogram line.\n"
1213
+ "2. Risk for Self-Harm r/t MDD and suicidal intent AEB deliberate overdose."
1214
+ ),
1215
+ "planning": (
1216
+ "NAC infusion completed (21 hours). LFTs remain normal. "
1217
+ "Psychiatric review and safe discharge planning. "
1218
+ "Patient engaged with mental health team."
1219
+ ),
1220
+ "implementation": (
1221
+ "β€’ NAC Bag 1 commenced at 03:15 β€” no anaphylactoid reaction.\n"
1222
+ "β€’ 1:1 observation commenced. Environment cleared of hazards.\n"
1223
+ "β€’ Mental health consult at 06:00.\n"
1224
+ "β€’ Communicated using they/them pronouns throughout β€” patient acknowledged and appreciated.\n"
1225
+ "β€’ Social worker contacted at 08:00.\n"
1226
+ "β€’ LFTs and INR repeated at 8 and 16 hours β€” remained normal."
1227
+ ),
1228
+ "evaluation": (
1229
+ "NAC infusion completed at 00:15 (Day 2). LFTs, INR normal throughout. "
1230
+ "Psychiatric review at 06:00 β€” not for inpatient admission; community mental health follow-up arranged. "
1231
+ "Discharged with crisis plan, mental health team contact, and GP review within 48 hours."
1232
+ ),
1233
+ },
1234
+ },
1235
+
1236
+ # ── 10. RENAL β€” ACUTE KIDNEY INJURY ───────────────────────────────────
1237
+ {
1238
+ "id": "case_010",
1239
+ "title": "Acute Kidney Injury (AKI) β€” Prerenal",
1240
+ "category": "Renal",
1241
+ "difficulty": "Intermediate",
1242
+ "tags": ["AKI", "renal", "acute kidney injury", "fluid balance", "oliguria", "hypotension"],
1243
+ "learning_objectives": [
1244
+ "Classify AKI using KDIGO criteria (Stage 1, 2, 3)",
1245
+ "Differentiate prerenal, intrinsic, and postrenal AKI",
1246
+ "Manage fluid resuscitation in AKI",
1247
+ "Monitor for hyperkalaemia β€” most dangerous complication",
1248
+ "Avoid nephrotoxic medications and contrast in AKI",
1249
+ ],
1250
+ "patient": {
1251
+ "name": "Mr. Daniel Obi",
1252
+ "age": 55,
1253
+ "gender": "Male",
1254
+ "weight_kg": 78,
1255
+ "height_cm": 180,
1256
+ "allergies": ["Ibuprofen (worsens kidney function)"],
1257
+ "pmhx": ["Hypertension", "Type 2 Diabetes", "CKD Stage 2 (baseline Cr 110 ΞΌmol/L)"],
1258
+ "medications": [
1259
+ "Ramipril 10 mg daily",
1260
+ "Metformin 1000 mg BD",
1261
+ "Furosemide 40 mg daily",
1262
+ "Amlodipine 10 mg daily",
1263
+ ],
1264
+ "social": "Bank manager. Married, 2 children. Had gastroenteritis for 5 days β€” unable to eat or drink. Continued all medications including ramipril and furosemide.",
1265
+ "family_hx": "Father has T2DM and hypertension.",
1266
+ },
1267
+ "presentation": (
1268
+ "Mr. Obi is admitted by his GP with 5 days of gastroenteritis (vomiting and diarrhoea Γ— 8/day), "
1269
+ "poor oral intake, and dizziness on standing. His GP found BP 88/54 lying, Cr 348 on bloods. "
1270
+ "He continued taking ramipril and furosemide throughout his illness. "
1271
+ "He has not passed urine for 12 hours."
1272
+ ),
1273
+ "vitals": {
1274
+ "BP": "88/54 mmHg (lying); 72/44 mmHg (standing β€” postural drop)",
1275
+ "HR": "108 bpm",
1276
+ "RR": "18 breaths/min",
1277
+ "SpO2": "97% on room air",
1278
+ "Temp": "37.3Β°C",
1279
+ "Pain": "4/10 (abdominal cramps)",
1280
+ "GCS": "15",
1281
+ "UO": "0 mL last 12 hours",
1282
+ },
1283
+ "physical_exam": (
1284
+ "Patient appears unwell and dehydrated. Dry mucous membranes, sunken eyes, reduced skin turgor. "
1285
+ "Postural hypotension confirmed. Capillary refill 3 seconds. "
1286
+ "Abdomen: mild diffuse tenderness, no guarding. No peripheral oedema. "
1287
+ "No signs of urinary retention on palpation."
1288
+ ),
1289
+ "investigations": {
1290
+ "Creatinine": "348 ΞΌmol/L (↑↑ from baseline 110 β€” Stage 3 AKI by KDIGO: Γ— 3.17 baseline)",
1291
+ "Urea": "28.4 mmol/L (↑↑)",
1292
+ "eGFR": "16 mL/min/1.73mΒ² (critically reduced)",
1293
+ "Potassium": "6.2 mmol/L (↑↑ β€” dangerous hyperkalaemia)",
1294
+ "Sodium": "128 mmol/L (↓ β€” hyponatraemia)",
1295
+ "Bicarbonate": "14 mmol/L (↓ β€” metabolic acidosis)",
1296
+ "FBC": "Hb 122 g/L, WCC 9.8",
1297
+ "Urine": "No casts (consistent with prerenal), Urine Na < 20 mmol/L",
1298
+ "Urine osmolality": "620 mOsm/kg (concentrated β€” prerenal physiology)",
1299
+ "ECG": "Peaked T waves (hyperkalaemia). HR 108.",
1300
+ "Renal ultrasound": "Normal kidney size. No obstruction. No hydronephrosis.",
1301
+ },
1302
+ "medical_diagnosis": "Stage 3 AKI β€” prerenal (dehydration + ACE inhibitor/diuretic in gastroenteritis)",
1303
+ "nursing_priorities": [
1304
+ "URGENT: Treat hyperkalaemia (K⁺ 6.2 + ECG changes) β€” calcium gluconate IV",
1305
+ "IV fluid resuscitation: 0.9% NaCl 500 mL over 1 hour Γ— 2",
1306
+ "HOLD nephrotoxic medications: ramipril, furosemide, metformin, NSAIDs",
1307
+ "Strict fluid balance β€” IDC for hourly urine output",
1308
+ "Continuous cardiac monitoring β€” hyperkalaemia arrhythmia risk",
1309
+ "Serial K⁺ and creatinine every 2–4 hours",
1310
+ "Renal team review β€” consider dialysis if refractory (unlikely if prerenal)",
1311
+ "Dietary consult β€” low potassium, low phosphate diet",
1312
+ ],
1313
+ "nursing_diagnoses": [
1314
+ {
1315
+ "diagnosis": "Deficient Fluid Volume related to gastroenteritis and diuretic use",
1316
+ "evidence": "BP 88/54, postural hypotension, anuria Γ— 12 hours, dry mucous membranes",
1317
+ "goal": "UO β‰₯ 0.5 mL/kg/hr (β‰₯ 39 mL/hr) within 4 hours; BP > 100 systolic",
1318
+ "interventions": [
1319
+ "IV 0.9% NaCl 500 mL over 1 hour Γ— 2 β€” reassess after each bolus",
1320
+ "IDC inserted β€” strict hourly UO",
1321
+ "Hold ramipril and furosemide",
1322
+ "Vital signs every 30–60 minutes",
1323
+ ],
1324
+ },
1325
+ {
1326
+ "diagnosis": "Risk for Cardiac Arrhythmia related to hyperkalaemia (K⁺ 6.2)",
1327
+ "evidence": "K⁺ 6.2 mmol/L, peaked T waves on ECG, AKI",
1328
+ "goal": "K⁺ < 5.5 mmol/L within 4 hours; no arrhythmia",
1329
+ "interventions": [
1330
+ "Calcium gluconate 10 mL 10% IV over 10 min (cardioprotective β€” immediate effect)",
1331
+ "Insulin 10 units actrapid + 50 mL 50% dextrose IV (shifts K into cells)",
1332
+ "Salbutamol nebuliser 10–20 mg (adjunct K-lowering)",
1333
+ "Sodium bicarbonate 100 mmol IV if pH < 7.2 (treats acidosis/K shift)",
1334
+ "Resonium (kayexalate) PO/PR for K removal",
1335
+ "Continuous ECG monitoring β€” treat arrhythmias immediately",
1336
+ "Repeat K⁺ 2 hours after treatment",
1337
+ ],
1338
+ },
1339
+ ],
1340
+ "adpie": {
1341
+ "assessment": (
1342
+ "Subjective: 5-day gastroenteritis, unable to eat/drink, continued ramipril and furosemide, "
1343
+ "anuria Γ— 12 hours. Objective: BP 88/54, K⁺ 6.2, Cr 348 (Stage 3 AKI), "
1344
+ "peaked T waves on ECG, dry mucous membranes, Urine Na < 20 (prerenal)."
1345
+ ),
1346
+ "diagnosis": (
1347
+ "1. Deficient Fluid Volume r/t dehydration AEB hypotension, anuria, poor skin turgor.\n"
1348
+ "2. Risk for Cardiac Arrhythmia r/t hyperkalaemia AEB K⁺ 6.2, peaked T waves."
1349
+ ),
1350
+ "planning": (
1351
+ "Fluid resuscitation to restore UO. Treat hyperkalaemia urgently. "
1352
+ "Hold nephrotoxic medications. Cr to trend downward within 24–48 hours."
1353
+ ),
1354
+ "implementation": (
1355
+ "β€’ Calcium gluconate 10 mL 10% IV given at 10:30 β€” ECG improved (T waves less peaked).\n"
1356
+ "β€’ Actrapid 10 units + 50 mL 50% dextrose IV given.\n"
1357
+ "β€’ 0.9% NaCl 500 mL Γ— 2 over 2 hours.\n"
1358
+ "β€’ Ramipril, furosemide, metformin withheld β€” medications reviewed by team.\n"
1359
+ "β€’ IDC inserted β€” UO 15 mL/hr at 2 hours, 38 mL/hr at 4 hours.\n"
1360
+ "β€’ K⁺ repeat at 2 hours: 5.4 mmol/L (↓ from 6.2)."
1361
+ ),
1362
+ "evaluation": (
1363
+ "At 12 hours: BP 118/76, UO 44 mL/hr, K⁺ 4.8, Cr 244 (↓ from 348 β€” prerenal responding). "
1364
+ "At 48 hours: Cr 148 ΞΌmol/L (↓ improving). "
1365
+ "Ramipril and furosemide restarted at discharge with sick-day medication advice."
1366
+ ),
1367
+ },
1368
+ },
1369
+
1370
+ ]
1371
+
1372
+
1373
+ # ---------------------------------------------------------------------------
1374
+ # Helper functions
1375
+ # ---------------------------------------------------------------------------
1376
+
1377
+ def get_all_cases():
1378
+ return CASE_BANK
1379
+
1380
+
1381
+ def get_categories():
1382
+ seen = []
1383
+ for c in CASE_BANK:
1384
+ if c["category"] not in seen:
1385
+ seen.append(c["category"])
1386
+ return seen
1387
+
1388
+
1389
+ def get_difficulties():
1390
+ return ["Beginner", "Intermediate", "Advanced"]
1391
+
1392
+
1393
+ def get_by_category(category: str):
1394
+ return [c for c in CASE_BANK if c["category"] == category]
1395
+
1396
+
1397
+ def get_by_difficulty(difficulty: str):
1398
+ return [c for c in CASE_BANK if c["difficulty"] == difficulty]
1399
+
1400
+
1401
+ def get_by_id(case_id: str):
1402
+ for c in CASE_BANK:
1403
+ if c["id"] == case_id:
1404
+ return c
1405
+ return None
1406
+
1407
+
1408
+ def search_cases(query: str):
1409
+ q = query.lower()
1410
+ results = []
1411
+ for c in CASE_BANK:
1412
+ if (q in c["title"].lower()
1413
+ or q in c["category"].lower()
1414
+ or any(q in t for t in c["tags"])
1415
+ or q in c["patient"]["name"].lower()
1416
+ or q in c.get("medical_diagnosis", "").lower()):
1417
+ results.append(c)
1418
+ return results
requirements.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ streamlit>=1.32.0
streamlit_app.py ADDED
@@ -0,0 +1,679 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Nursing Case Study Builder
3
+ Streamlit app β€” Hugging Face Spaces (free CPU tier)
4
+ """
5
+
6
+ import streamlit as st
7
+ from cases.bank import (
8
+ get_all_cases, get_categories, get_by_category, get_by_difficulty,
9
+ get_by_id, search_cases, get_difficulties,
10
+ )
11
+
12
+ # ---------------------------------------------------------------------------
13
+ # Page config
14
+ # ---------------------------------------------------------------------------
15
+ st.set_page_config(
16
+ page_title="Nursing Case Studies β€” Student Nurses",
17
+ page_icon="πŸ₯",
18
+ layout="wide",
19
+ initial_sidebar_state="expanded",
20
+ )
21
+
22
+ # ---------------------------------------------------------------------------
23
+ # CSS
24
+ # ---------------------------------------------------------------------------
25
+ st.markdown("""
26
+ <style>
27
+ .case-card {
28
+ background:#f8fafc; border:1px solid #d0dae8;
29
+ border-radius:10px; padding:1.2rem 1.4rem; margin-bottom:1rem;
30
+ }
31
+ .patient-banner {
32
+ background:#e3f2fd; border-left:5px solid #1565c0;
33
+ padding:0.8rem 1.2rem; border-radius:4px; margin-bottom:0.8rem;
34
+ }
35
+ .warning-banner {
36
+ background:#fff3e0; border-left:5px solid #e65100;
37
+ padding:0.8rem 1.2rem; border-radius:4px; margin-bottom:0.8rem;
38
+ }
39
+ .critical-banner {
40
+ background:#fce4ec; border-left:5px solid #c62828;
41
+ padding:0.8rem 1.2rem; border-radius:4px; margin-bottom:0.8rem;
42
+ }
43
+ .success-banner {
44
+ background:#e8f5e9; border-left:5px solid #2e7d32;
45
+ padding:0.8rem 1.2rem; border-radius:4px; margin-bottom:0.8rem;
46
+ }
47
+ .info-banner {
48
+ background:#e8eaf6; border-left:5px solid #3949ab;
49
+ padding:0.8rem 1.2rem; border-radius:4px; margin-bottom:0.8rem;
50
+ }
51
+ .badge-beginner { background:#e8f5e9; color:#2e7d32; padding:3px 10px;
52
+ border-radius:12px; font-size:0.78em; font-weight:700; }
53
+ .badge-intermediate { background:#fff8e1; color:#f57f17; padding:3px 10px;
54
+ border-radius:12px; font-size:0.78em; font-weight:700; }
55
+ .badge-advanced { background:#fce4ec; color:#c62828; padding:3px 10px;
56
+ border-radius:12px; font-size:0.78em; font-weight:700; }
57
+ .vital-box {
58
+ background:#f5f5f5; border-radius:8px; padding:0.6rem 1rem;
59
+ text-align:center; margin-bottom:0.4rem;
60
+ }
61
+ .nd-card {
62
+ background:#fafafa; border:1px solid #e0e0e0;
63
+ border-radius:8px; padding:1rem 1.2rem; margin-bottom:0.8rem;
64
+ }
65
+ </style>
66
+ """, unsafe_allow_html=True)
67
+
68
+
69
+ # ---------------------------------------------------------------------------
70
+ # Helpers
71
+ # ---------------------------------------------------------------------------
72
+ DIFF_COLOURS = {"Beginner": "#2e7d32", "Intermediate": "#f57f17", "Advanced": "#c62828"}
73
+ CAT_ICONS = {
74
+ "Cardiovascular": "❀️",
75
+ "Respiratory": "🫁",
76
+ "Endocrine": "🩸",
77
+ "Neurological": "🧠",
78
+ "Multi-system / Infectious": "🦠",
79
+ "Musculoskeletal / Surgical": "🦴",
80
+ "Maternal / Obstetric": "🀰",
81
+ "Paediatric": "πŸ‘Ά",
82
+ "Mental Health / Toxicology": "πŸ’œ",
83
+ "Renal": "πŸ’§",
84
+ }
85
+
86
+
87
+ def diff_badge(difficulty: str) -> str:
88
+ cls = f"badge-{difficulty.lower()}"
89
+ return f'<span class="{cls}">{difficulty}</span>'
90
+
91
+
92
+ def cat_icon(category: str) -> str:
93
+ return CAT_ICONS.get(category, "πŸ“‹")
94
+
95
+
96
+ def init_state():
97
+ if "selected_case_id" not in st.session_state:
98
+ st.session_state.selected_case_id = None
99
+ if "adpie_answers" not in st.session_state:
100
+ st.session_state.adpie_answers = {}
101
+ if "quiz_answers" not in st.session_state:
102
+ st.session_state.quiz_answers = {}
103
+ if "quiz_submitted" not in st.session_state:
104
+ st.session_state.quiz_submitted = False
105
+ if "careplan_items" not in st.session_state:
106
+ st.session_state.careplan_items = {}
107
+
108
+
109
+ init_state()
110
+
111
+ # ---------------------------------------------------------------------------
112
+ # Sidebar
113
+ # ---------------------------------------------------------------------------
114
+ with st.sidebar:
115
+ st.markdown("## πŸ₯ Case Studies")
116
+ st.divider()
117
+
118
+ all_cases = get_all_cases()
119
+ categories = get_categories()
120
+ difficulties = get_difficulties()
121
+
122
+ st.markdown("**Quick Stats**")
123
+ st.markdown(f"- πŸ“‹ {len(all_cases)} clinical cases")
124
+ st.markdown(f"- 🏷️ {len(categories)} body systems")
125
+ diff_counts = {d: len(get_by_difficulty(d)) for d in difficulties}
126
+ for d, n in diff_counts.items():
127
+ colour = DIFF_COLOURS[d]
128
+ st.markdown(f'- <span style="color:{colour}">⬀</span> {d}: {n} cases', unsafe_allow_html=True)
129
+
130
+ st.divider()
131
+ st.markdown("**Cases by System**")
132
+ for cat in categories:
133
+ icon = cat_icon(cat)
134
+ n = len(get_by_category(cat))
135
+ st.markdown(f"{icon} **{cat}** β€” {n}")
136
+
137
+ st.divider()
138
+ st.markdown("**ADPIE Framework**")
139
+ st.markdown("""
140
+ - **A**ssessment
141
+ - **D**iagnosis
142
+ - **P**lanning
143
+ - **I**mplementation
144
+ - **E**valuation
145
+ """)
146
+ st.divider()
147
+ st.caption(
148
+ "Part of the [Nursing Citizen Development](https://huggingface.co/NurseCitizenDeveloper) suite"
149
+ )
150
+
151
+ # ---------------------------------------------------------------------------
152
+ # Header
153
+ # ---------------------------------------------------------------------------
154
+ st.title("πŸ₯ Nursing Case Studies")
155
+ st.caption(
156
+ "10 clinical scenarios across major body systems Β· ADPIE Framework Β· "
157
+ "Nursing Diagnoses Β· Care Planning Β· For educational purposes only"
158
+ )
159
+
160
+ # ---------------------------------------------------------------------------
161
+ # Tabs
162
+ # ---------------------------------------------------------------------------
163
+ tab_lib, tab_case, tab_adpie, tab_quiz, tab_plan = st.tabs([
164
+ "πŸ“š Case Library",
165
+ "πŸ” Full Case",
166
+ "🧠 ADPIE Reasoning",
167
+ "❓ Quiz Questions",
168
+ "πŸ“ Care Plan",
169
+ ])
170
+
171
+
172
+ # ========================= CASE LIBRARY =====================================
173
+ with tab_lib:
174
+ st.subheader("πŸ“š Clinical Case Library")
175
+ st.caption("Browse 10 evidence-based patient scenarios. Click any case to open it.")
176
+
177
+ col_search, col_diff, col_cat = st.columns([3, 2, 2])
178
+ with col_search:
179
+ lib_query = st.text_input("πŸ” Search cases", placeholder="e.g. sepsis, chest pain, stroke")
180
+ with col_diff:
181
+ diff_filter = st.selectbox("Difficulty", ["All"] + difficulties)
182
+ with col_cat:
183
+ cat_filter = st.selectbox("Body system", ["All"] + categories)
184
+
185
+ st.divider()
186
+
187
+ # Filter
188
+ if lib_query.strip():
189
+ display_cases = search_cases(lib_query)
190
+ if not display_cases:
191
+ st.info(f"No cases found for '{lib_query}'.")
192
+ elif diff_filter != "All" and cat_filter != "All":
193
+ display_cases = [c for c in get_by_category(cat_filter)
194
+ if c["difficulty"] == diff_filter]
195
+ elif diff_filter != "All":
196
+ display_cases = get_by_difficulty(diff_filter)
197
+ elif cat_filter != "All":
198
+ display_cases = get_by_category(cat_filter)
199
+ else:
200
+ display_cases = all_cases
201
+
202
+ st.markdown(f"**Showing {len(display_cases)} case(s)**")
203
+ st.markdown("")
204
+
205
+ for case in display_cases:
206
+ icon = cat_icon(case["category"])
207
+ col_a, col_b = st.columns([5, 1])
208
+ with col_a:
209
+ st.markdown(
210
+ f'<div class="case-card">'
211
+ f'<b>{icon} {case["title"]}</b> &nbsp;'
212
+ f'{diff_badge(case["difficulty"])}<br/>'
213
+ f'<small>🏷️ {case["category"]} &nbsp;·&nbsp; '
214
+ f'πŸ‘€ {case["patient"]["name"]}, {case["patient"]["age"]}yo &nbsp;Β·&nbsp; '
215
+ f'πŸ”– {", ".join(case["tags"][:4])}</small>'
216
+ f'</div>',
217
+ unsafe_allow_html=True
218
+ )
219
+ with col_b:
220
+ if st.button("Open β†’", key=f"open_{case['id']}", use_container_width=True):
221
+ st.session_state.selected_case_id = case["id"]
222
+ st.session_state.quiz_answers = {}
223
+ st.session_state.quiz_submitted = False
224
+ st.session_state.adpie_answers = {}
225
+ st.success(f"βœ… Case loaded: **{case['title']}** β€” navigate to other tabs.")
226
+
227
+
228
+ # ========================= FULL CASE ========================================
229
+ with tab_case:
230
+ st.subheader("πŸ” Full Case Study")
231
+
232
+ if not st.session_state.selected_case_id:
233
+ st.info("πŸ’‘ Select a case from the **Case Library** tab to begin.")
234
+ else:
235
+ case = get_by_id(st.session_state.selected_case_id)
236
+ if not case:
237
+ st.error("Case not found.")
238
+ else:
239
+ p = case["patient"]
240
+
241
+ # Title banner
242
+ icon = cat_icon(case["category"])
243
+ st.markdown(
244
+ f'<div class="patient-banner">'
245
+ f'<h3 style="margin:0">{icon} {case["title"]}</h3>'
246
+ f'<span>{diff_badge(case["difficulty"])}</span> &nbsp;'
247
+ f'<small>{case["category"]}</small>'
248
+ f'</div>',
249
+ unsafe_allow_html=True
250
+ )
251
+
252
+ # Learning objectives
253
+ with st.expander("🎯 Learning Objectives", expanded=False):
254
+ for lo in case["learning_objectives"]:
255
+ st.markdown(f"β€’ {lo}")
256
+
257
+ st.divider()
258
+
259
+ # Patient demographics
260
+ col1, col2 = st.columns(2)
261
+ with col1:
262
+ st.markdown("### πŸ‘€ Patient Profile")
263
+ st.markdown(f"**Name:** {p['name']}")
264
+ st.markdown(f"**Age / Gender:** {p['age']} years Β· {p['gender']}")
265
+ st.markdown(f"**Weight / Height:** {p['weight_kg']} kg Β· {p['height_cm']} cm")
266
+ st.markdown(f"**Allergies:** {', '.join(p['allergies'])}")
267
+
268
+ with col2:
269
+ st.markdown("### πŸ“‹ Medical History")
270
+ st.markdown("**Past Medical History:**")
271
+ for h in p["pmhx"]:
272
+ st.markdown(f"β€’ {h}")
273
+ st.markdown(f"**Medications:** {', '.join(p['medications'])}")
274
+ st.markdown(f"**Social:** {p['social']}")
275
+ st.markdown(f"**Family History:** {p.get('family_hx', 'Nil relevant')}")
276
+
277
+ st.divider()
278
+
279
+ # Presentation
280
+ st.markdown("### 🚨 Presentation")
281
+ st.markdown(
282
+ f'<div class="warning-banner">πŸ“‹ {case["presentation"]}</div>',
283
+ unsafe_allow_html=True
284
+ )
285
+
286
+ # Vital signs
287
+ st.markdown("### πŸ“Š Vital Signs")
288
+ vitals = case["vitals"]
289
+ v_keys = list(vitals.keys())
290
+ cols = st.columns(min(len(v_keys), 5))
291
+ for i, key in enumerate(v_keys):
292
+ with cols[i % len(cols)]:
293
+ st.markdown(
294
+ f'<div class="vital-box"><small>{key}</small><br/>'
295
+ f'<b>{vitals[key]}</b></div>',
296
+ unsafe_allow_html=True
297
+ )
298
+
299
+ # Physical exam
300
+ st.markdown("### 🩺 Physical Examination")
301
+ st.markdown(case["physical_exam"])
302
+
303
+ st.divider()
304
+
305
+ # Investigations
306
+ st.markdown("### πŸ”¬ Investigations")
307
+ inv = case["investigations"]
308
+ inv_keys = list(inv.keys())
309
+ col_a, col_b = st.columns(2)
310
+ for i, key in enumerate(inv_keys):
311
+ col = col_a if i % 2 == 0 else col_b
312
+ with col:
313
+ val = inv[key]
314
+ flag = "πŸ”΄ " if ("↑↑" in val or "CRITICAL" in val or "severe" in val.lower()) else ""
315
+ st.markdown(f"**{key}:** {flag}{val}")
316
+
317
+ st.divider()
318
+
319
+ # Medical diagnosis
320
+ st.markdown("### πŸ₯ Medical Diagnosis")
321
+ st.markdown(
322
+ f'<div class="critical-banner">βš•οΈ <b>{case["medical_diagnosis"]}</b></div>',
323
+ unsafe_allow_html=True
324
+ )
325
+
326
+ # Nursing priorities
327
+ st.markdown("### πŸ”” Nursing Priorities")
328
+ for i, priority in enumerate(case["nursing_priorities"], 1):
329
+ colour = "#c62828" if i <= 3 else "#e65100" if i <= 6 else "#2e7d32"
330
+ st.markdown(
331
+ f'<div style="padding:4px 0"><span style="color:{colour};font-weight:700">'
332
+ f'{i}.</span> {priority}</div>',
333
+ unsafe_allow_html=True
334
+ )
335
+
336
+
337
+ # ========================= ADPIE REASONING ==================================
338
+ with tab_adpie:
339
+ st.subheader("🧠 ADPIE Clinical Reasoning Framework")
340
+ st.caption("Work through the case using the ADPIE nursing process. Reveal the model answer when ready.")
341
+
342
+ if not st.session_state.selected_case_id:
343
+ st.info("πŸ’‘ Select a case from the **Case Library** tab first.")
344
+ else:
345
+ case = get_by_id(st.session_state.selected_case_id)
346
+ adpie = case["adpie"]
347
+
348
+ st.markdown(
349
+ f'<div class="patient-banner">πŸ₯ Active Case: <b>{case["title"]}</b> &nbsp;Β·&nbsp; '
350
+ f'πŸ‘€ {case["patient"]["name"]}</div>',
351
+ unsafe_allow_html=True
352
+ )
353
+
354
+ st.markdown("**Instructions:** Read the case, then write your own answers before revealing the model answers.")
355
+ st.divider()
356
+
357
+ steps = [
358
+ ("A", "Assessment", "πŸ“‹", "What are the key subjective and objective findings?", "assessment"),
359
+ ("D", "Nursing Diagnosis", "πŸ”΄", "Identify priority nursing diagnoses (NANDA format: problem r/t aetiology AEB evidence)", "diagnosis"),
360
+ ("P", "Planning", "🎯", "What are your SMART nursing goals (short and long term)?", "planning"),
361
+ ("I", "Implementation", "βš™οΈ", "What nursing interventions will you implement and why?", "implementation"),
362
+ ("E", "Evaluation", "βœ…", "How will you evaluate if goals were met? What actually happened?", "evaluation"),
363
+ ]
364
+
365
+ for letter, title, icon, prompt, key in steps:
366
+ st.markdown(f"### {icon} {letter} β€” {title}")
367
+ st.markdown(f"*{prompt}*")
368
+
369
+ # Student input
370
+ ans_key = f"adpie_{case['id']}_{key}"
371
+ student_ans = st.text_area(
372
+ f"Your {title}:",
373
+ value=st.session_state.adpie_answers.get(ans_key, ""),
374
+ height=100,
375
+ key=f"adpie_input_{case['id']}_{key}",
376
+ placeholder=f"Write your {title.lower()} here...",
377
+ label_visibility="collapsed",
378
+ )
379
+ st.session_state.adpie_answers[ans_key] = student_ans
380
+
381
+ # Reveal model answer
382
+ with st.expander(f"πŸ” Reveal Model Answer β€” {title}"):
383
+ st.markdown(adpie[key])
384
+
385
+ st.markdown("")
386
+
387
+ # Nursing diagnoses deep-dive
388
+ st.divider()
389
+ st.markdown("### πŸ”΄ Nursing Diagnoses β€” Detailed")
390
+ for nd in case["nursing_diagnoses"]:
391
+ with st.expander(f"πŸ“Œ {nd['diagnosis']}", expanded=False):
392
+ st.markdown(
393
+ f'<div class="nd-card">'
394
+ f'<b>Supporting Evidence:</b> {nd["evidence"]}<br/><br/>'
395
+ f'<b>Goal:</b> {nd["goal"]}'
396
+ f'</div>',
397
+ unsafe_allow_html=True
398
+ )
399
+ st.markdown("**Nursing Interventions:**")
400
+ for inv in nd["interventions"]:
401
+ st.markdown(f"β€’ {inv}")
402
+
403
+
404
+ # ========================= QUIZ QUESTIONS ===================================
405
+ with tab_quiz:
406
+ st.subheader("❓ Case-Based Quiz Questions")
407
+ st.caption("NCLEX-style questions based on the active case. Select answers and submit for feedback.")
408
+
409
+ if not st.session_state.selected_case_id:
410
+ st.info("πŸ’‘ Select a case from the **Case Library** tab first.")
411
+ else:
412
+ case = get_by_id(st.session_state.selected_case_id)
413
+
414
+ st.markdown(
415
+ f'<div class="patient-banner">πŸ₯ Active Case: <b>{case["title"]}</b></div>',
416
+ unsafe_allow_html=True
417
+ )
418
+
419
+ # Generate case-specific questions dynamically
420
+ nd_names = [nd["diagnosis"].split(" related to")[0] for nd in case["nursing_diagnoses"]]
421
+ priorities = case["nursing_priorities"]
422
+
423
+ # Build 5 consistent case-based questions
424
+ questions = [
425
+ {
426
+ "q": f"Based on the case of {case['patient']['name']}, which nursing diagnosis should be prioritised FIRST?",
427
+ "options": nd_names + ["Pain management only"],
428
+ "answer": 0,
429
+ "rationale": (
430
+ f"The priority nursing diagnosis is '{nd_names[0]}'. "
431
+ f"Using Maslow's hierarchy, physiological and safety needs are addressed first. "
432
+ f"The supporting evidence is: {case['nursing_diagnoses'][0]['evidence']}."
433
+ ),
434
+ },
435
+ {
436
+ "q": f"What is the FIRST priority nursing action for {case['patient']['name']}?",
437
+ "options": [
438
+ priorities[0] if len(priorities) > 0 else "Call the doctor",
439
+ priorities[2] if len(priorities) > 2 else "Reassess vitals",
440
+ "Complete full medication history",
441
+ "Discharge planning",
442
+ ],
443
+ "answer": 0,
444
+ "rationale": (
445
+ f"The immediate priority is: '{priorities[0]}'. "
446
+ "Nursing priorities are ordered by urgency β€” life-threatening physiological "
447
+ "problems must be addressed before less urgent concerns."
448
+ ),
449
+ },
450
+ {
451
+ "q": f"Which assessment finding in {case['patient']['name']}'s case is MOST concerning?",
452
+ "options": list(case["vitals"].items())[:4],
453
+ "answer": 0,
454
+ "rationale": (
455
+ "The most concerning vital sign is the first listed, which is outside normal limits. "
456
+ "Always assess using ABCDE β€” Airway, Breathing, Circulation, Disability, Exposure β€” "
457
+ "to prioritise life-threatening abnormalities."
458
+ ),
459
+ "is_vitals": True,
460
+ },
461
+ {
462
+ "q": f"The goal for the priority nursing diagnosis in this case is: '{case['nursing_diagnoses'][0]['goal']}'. Which nursing intervention BEST addresses this goal?",
463
+ "options": case["nursing_diagnoses"][0]["interventions"][:4],
464
+ "answer": 0,
465
+ "rationale": (
466
+ f"The first listed intervention directly addresses the priority goal. "
467
+ f"Rationale: {case['nursing_diagnoses'][0]['interventions'][0]}"
468
+ ),
469
+ },
470
+ {
471
+ "q": f"In evaluating the outcomes for {case['patient']['name']}, which finding would indicate the PRIORITY nursing goal has been MET?",
472
+ "options": [
473
+ case["nursing_diagnoses"][0]["goal"],
474
+ "Patient is pain-free",
475
+ "Family is satisfied with care",
476
+ "All documentation is complete",
477
+ ],
478
+ "answer": 0,
479
+ "rationale": (
480
+ f"The priority goal for this case is: '{case['nursing_diagnoses'][0]['goal']}'. "
481
+ "Goals must be patient-centred, measurable, and time-bound (SMART). "
482
+ "This outcome directly measures resolution of the priority nursing diagnosis."
483
+ ),
484
+ },
485
+ ]
486
+
487
+ if st.button("πŸ”„ Reset Quiz", use_container_width=False):
488
+ st.session_state.quiz_answers = {}
489
+ st.session_state.quiz_submitted = False
490
+ st.rerun()
491
+
492
+ st.divider()
493
+
494
+ for i, q in enumerate(questions):
495
+ st.markdown(f"**Question {i + 1}:** {q['q']}")
496
+
497
+ if q.get("is_vitals"):
498
+ opts = [f"{k}: {v}" for k, v in q["options"]]
499
+ else:
500
+ opts = q["options"]
501
+
502
+ selected = st.radio(
503
+ f"Q{i+1}",
504
+ options=opts,
505
+ key=f"quiz_{case['id']}_q{i}",
506
+ label_visibility="collapsed",
507
+ )
508
+ st.session_state.quiz_answers[i] = selected
509
+
510
+ if st.session_state.quiz_submitted:
511
+ correct_opt = opts[q["answer"]]
512
+ if selected == correct_opt:
513
+ st.markdown(
514
+ f'<div class="success-banner">βœ… <b>Correct!</b> {q["rationale"]}</div>',
515
+ unsafe_allow_html=True
516
+ )
517
+ else:
518
+ st.markdown(
519
+ f'<div class="critical-banner">❌ <b>Incorrect.</b> '
520
+ f'Correct answer: <b>{correct_opt}</b><br/>{q["rationale"]}</div>',
521
+ unsafe_allow_html=True
522
+ )
523
+
524
+ st.markdown("")
525
+
526
+ col_sub, col_score = st.columns([2, 3])
527
+ with col_sub:
528
+ if st.button("βœ… Submit Answers", type="primary", use_container_width=True):
529
+ st.session_state.quiz_submitted = True
530
+ st.rerun()
531
+
532
+ if st.session_state.quiz_submitted:
533
+ score = 0
534
+ for i, q in enumerate(questions):
535
+ if q.get("is_vitals"):
536
+ opts = [f"{k}: {v}" for k, v in q["options"]]
537
+ else:
538
+ opts = q["options"]
539
+ if st.session_state.quiz_answers.get(i) == opts[q["answer"]]:
540
+ score += 1
541
+
542
+ pct = round((score / len(questions)) * 100)
543
+ colour = "#2e7d32" if pct >= 80 else "#e65100" if pct >= 60 else "#c62828"
544
+ with col_score:
545
+ st.markdown(
546
+ f'<div style="padding:0.6rem 1rem; background:#f5f5f5; border-radius:8px; '
547
+ f'font-size:1.1em; font-weight:700; color:{colour};">'
548
+ f'Score: {score} / {len(questions)} ({pct}%)</div>',
549
+ unsafe_allow_html=True
550
+ )
551
+
552
+
553
+ # ========================= CARE PLAN ========================================
554
+ with tab_plan:
555
+ st.subheader("πŸ“ Nursing Care Plan Builder")
556
+ st.caption("Build a structured care plan for the active case using the NANDA-NIC-NOC framework.")
557
+
558
+ if not st.session_state.selected_case_id:
559
+ st.info("πŸ’‘ Select a case from the **Case Library** tab first.")
560
+ else:
561
+ case = get_by_id(st.session_state.selected_case_id)
562
+
563
+ st.markdown(
564
+ f'<div class="patient-banner">πŸ₯ <b>{case["patient"]["name"]}</b> Β· '
565
+ f'{case["patient"]["age"]} y/o Β· {case["medical_diagnosis"]}</div>',
566
+ unsafe_allow_html=True
567
+ )
568
+
569
+ st.markdown("Complete the care plan below. Toggle **Show Model Answer** to reveal guidance.")
570
+ st.divider()
571
+
572
+ for idx, nd in enumerate(case["nursing_diagnoses"]):
573
+ st.markdown(f"### πŸ“Œ Nursing Diagnosis {idx + 1}")
574
+ st.markdown(
575
+ f'<div class="nd-card"><b>{nd["diagnosis"]}</b></div>',
576
+ unsafe_allow_html=True
577
+ )
578
+
579
+ cp_key = f"cp_{case['id']}_{idx}"
580
+ if cp_key not in st.session_state.careplan_items:
581
+ st.session_state.careplan_items[cp_key] = {
582
+ "diagnosis": "", "goal": "", "interventions": "", "evaluation": ""
583
+ }
584
+
585
+ c1, c2 = st.columns(2)
586
+
587
+ with c1:
588
+ st.markdown("**Your Nursing Diagnosis (NANDA format):**")
589
+ nd_input = st.text_area(
590
+ "nd",
591
+ value=st.session_state.careplan_items[cp_key]["diagnosis"],
592
+ height=80,
593
+ placeholder="[Problem] related to [Aetiology] as evidenced by [Signs/Symptoms]",
594
+ key=f"{cp_key}_nd",
595
+ label_visibility="collapsed",
596
+ )
597
+ st.session_state.careplan_items[cp_key]["diagnosis"] = nd_input
598
+
599
+ st.markdown("**Your SMART Goal:**")
600
+ goal_input = st.text_area(
601
+ "goal",
602
+ value=st.session_state.careplan_items[cp_key]["goal"],
603
+ height=80,
604
+ placeholder="Patient will [outcome] by [time] as measured by [indicator]",
605
+ key=f"{cp_key}_goal",
606
+ label_visibility="collapsed",
607
+ )
608
+ st.session_state.careplan_items[cp_key]["goal"] = goal_input
609
+
610
+ with c2:
611
+ st.markdown("**Your Nursing Interventions (with rationale):**")
612
+ inv_input = st.text_area(
613
+ "interventions",
614
+ value=st.session_state.careplan_items[cp_key]["interventions"],
615
+ height=80,
616
+ placeholder="1. Intervention (Rationale)\n2. Intervention (Rationale)\n3. ...",
617
+ key=f"{cp_key}_inv",
618
+ label_visibility="collapsed",
619
+ )
620
+ st.session_state.careplan_items[cp_key]["interventions"] = inv_input
621
+
622
+ st.markdown("**Evaluation Criteria:**")
623
+ eval_input = st.text_area(
624
+ "evaluation",
625
+ value=st.session_state.careplan_items[cp_key]["evaluation"],
626
+ height=80,
627
+ placeholder="Goal met / partially met / not met because...",
628
+ key=f"{cp_key}_eval",
629
+ label_visibility="collapsed",
630
+ )
631
+ st.session_state.careplan_items[cp_key]["evaluation"] = eval_input
632
+
633
+ # Model answer toggle
634
+ with st.expander("πŸ” Show Model Answer"):
635
+ st.markdown(f"**Diagnosis:** {nd['diagnosis']}")
636
+ st.markdown(f"**Evidence:** {nd['evidence']}")
637
+ st.markdown(f"**Goal:** {nd['goal']}")
638
+ st.markdown("**Model Interventions:**")
639
+ for i in nd["interventions"]:
640
+ st.markdown(f"β€’ {i}")
641
+
642
+ st.divider()
643
+
644
+ # Print / export summary
645
+ if any(
646
+ any(v for v in st.session_state.careplan_items.get(f"cp_{case['id']}_{i}", {}).values())
647
+ for i in range(len(case["nursing_diagnoses"]))
648
+ ):
649
+ st.markdown("### πŸ“„ Care Plan Summary")
650
+ summary_lines = [f"# Care Plan: {case['patient']['name']}\n",
651
+ f"**Diagnosis:** {case['medical_diagnosis']}\n"]
652
+ for idx, nd in enumerate(case["nursing_diagnoses"]):
653
+ cp_key = f"cp_{case['id']}_{idx}"
654
+ item = st.session_state.careplan_items.get(cp_key, {})
655
+ summary_lines.append(f"\n## Nursing Diagnosis {idx+1}\n")
656
+ summary_lines.append(f"**Diagnosis:** {item.get('diagnosis', 'β€”')}\n")
657
+ summary_lines.append(f"**Goal:** {item.get('goal', 'β€”')}\n")
658
+ summary_lines.append(f"**Interventions:** {item.get('interventions', 'β€”')}\n")
659
+ summary_lines.append(f"**Evaluation:** {item.get('evaluation', 'β€”')}\n")
660
+
661
+ summary_text = "\n".join(summary_lines)
662
+ st.download_button(
663
+ "⬇️ Download Care Plan (.txt)",
664
+ data=summary_text,
665
+ file_name=f"care_plan_{case['id']}.txt",
666
+ mime="text/plain",
667
+ use_container_width=False,
668
+ )
669
+
670
+
671
+ # ---------------------------------------------------------------------------
672
+ # Footer
673
+ # ---------------------------------------------------------------------------
674
+ st.divider()
675
+ st.caption(
676
+ "Cases are fictional composite scenarios for educational purposes only. "
677
+ "Always follow your institution's clinical guidelines, evidence-based practice, "
678
+ "and clinical supervisor guidance in real patient care."
679
+ )