45 Year old female. With a past history of undifferentiated... Arthritis. Arthritis, she was on 3 months. DMARDS. Then, completely recovered. During that time, ANA was two plus positive. And now, here with the complaints of... Uh, right-sided. Uh, pulsating pain associated with swelling of the... Uh, and then, uh... Right sided pain. Associated with swelling. Uh, pain is mild, pulsate. Uh, spelling on the right eye, on the right, uh, beside the eye also. Swelling is aggravated. Swelling, swelling is aggravated, uh, by... Chewing. Subsidised with, uh, taking rest and the pain lasted for 15 minutes, uh. What are the differentials?
| Cause | Key Feature |
|---|---|
| Parotitis (infectious/viral - e.g., mumps) | Bilateral swelling, fever, pain worse on chewing - Cummings Otolaryngology |
| Parotid duct obstruction (sialolithiasis) | Episodic swelling triggered by eating/chewing, colicky pain, resolves spontaneously |
| Parotid tumor | Painless mass typically, but inflammatory tumors can be painful |
| Priority | Diagnosis | Reason |
|---|---|---|
| #1 - Rule out urgently | Giant Cell Arteritis | Risk of permanent vision loss; elevated ESR/CRP + temporal artery US needed STAT |
| #2 - Highly likely | Sjogren's Syndrome (evolving UCTD) | ANA+, prior arthritis, parotid swelling + periocular features |
| #3 - Likely | Sialolithiasis / Parotid duct stone | Episodic chewing-triggered unilateral swelling, self-resolving |
| #4 - Consider | TMJ arthritis | Autoimmune arthritis history, chewing-aggravated joint pain |
Generate a diagnostic flowchart for acute periorbital facial pain in autoimmune patients
A clean, professional medical diagnostic flowchart titled "Acute Periorbital/Facial Pain in Autoimmune Patients". The flowchart starts at the top with a patient box: "Autoimmune Patient with Acute Periorbital/Facial Pain + Swelling". It then branches into two main arms based on a diamond decision node: "Associated with CHEWING?" YES and NO paths. YES path leads to another diamond: "Systemic features? (fever, weight loss, elevated ESR/CRP, age >50)". This branches into: - YES → "Giant Cell Arteritis (URGENT)" box in red with sub-text "Jaw claudication, temporal headache, visual risk → ESR, CRP, Temporal Artery Ultrasound, Ophthalmology STAT" - NO → branches into two boxes: "Sialolithiasis / Parotid Duct Stone" (episodic, self-resolving, salivary gland US) and "TMJ Arthritis" (preauricular, joint tenderness, autoimmune overlap) NO path from main diamond leads to: "Visual symptoms present? (diplopia, vision loss, proptosis)" diamond. - YES → "Orbital Pseudotumor / Orbital Myositis" box in orange, with sub-text "ANA+, inflammatory orbitopathy → MRI orbit, steroids" - NO → another diamond "Parotid region swelling?" - YES → "Sjogren's Syndrome / Parotitis" box in blue, sub-text "Anti-Ro/SSA, anti-La/SSB, salivary gland biopsy" - NO → "Trigeminal Neuralgia / Dental Pathology" box in grey At the bottom, a unified "Initial Workup" box in green: "All patients: ESR, CRP, ANA panel, Anti-Ro/SSA, Temporal Artery US, Salivary Gland US, Ophthalmology review". Use color coding: red for urgent/GCA, orange for eye-related, blue for Sjogren's/parotid, grey for less urgent. Clean white background, sans-serif fonts, professional medical style with clear arrows connecting all boxes.

Create a management and treatment protocol document for GCA in autoimmune patients
mkdir -p /tmp/workspace/gca-protocol && ls /tmp/workspace/gca-protocol/
~/gca-protocol/build_gca_protocol.py
from docx import Document
from docx.shared import Pt, Inches, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.oxml.ns import qn
from docx.oxml import OxmlElement
import datetime
doc = Document()
# ── Page margins
for section in doc.sections:
section.top_margin = Inches(1.0)
section.bottom_margin = Inches(1.0)
section.left_margin = Inches(1.2)
section.right_margin = Inches(1.2)
# ── Default Normal style
normal = doc.styles["Normal"]
normal.font.name = "Arial"
normal.font.size = Pt(11)
# ── Heading helper colours
RED = RGBColor(0xC0, 0x00, 0x00)
DARK_RED = RGBColor(0x7B, 0x00, 0x00)
NAVY = RGBColor(0x1F, 0x39, 0x64)
TEAL = RGBColor(0x00, 0x70, 0x70)
ORANGE = RGBColor(0xBF, 0x60, 0x00)
BLACK = RGBColor(0x00, 0x00, 0x00)
WHITE = RGBColor(0xFF, 0xFF, 0xFF)
LIGHT_GREY = RGBColor(0xF2, 0xF2, 0xF2)
def set_cell_bg(cell, hex_color_str):
"""Set table cell background colour via XML shading."""
tc = cell._tc
tcPr = tc.get_or_add_tcPr()
shd = OxmlElement("w:shd")
shd.set(qn("w:val"), "clear")
shd.set(qn("w:color"), "auto")
shd.set(qn("w:fill"), hex_color_str)
tcPr.append(shd)
def add_heading(doc, text, level=1, color=NAVY):
h = doc.add_heading(text, level=level)
h.alignment = WD_ALIGN_PARAGRAPH.LEFT
for run in h.runs:
run.font.color.rgb = color
run.font.name = "Arial"
return h
def add_para(doc, text, bold=False, color=BLACK, size=11, left_indent=0):
p = doc.add_paragraph()
p.paragraph_format.left_indent = Inches(left_indent)
p.paragraph_format.space_after = Pt(4)
run = p.add_run(text)
run.bold = bold
run.font.color.rgb = color
run.font.name = "Arial"
run.font.size = Pt(size)
return p
def add_bullet(doc, text, level=0, bold_prefix=None):
p = doc.add_paragraph(style="List Bullet")
p.paragraph_format.left_indent = Inches(0.3 + level * 0.25)
p.paragraph_format.space_after = Pt(3)
if bold_prefix:
run = p.add_run(bold_prefix)
run.bold = True
run.font.name = "Arial"
run.font.size = Pt(11)
rest = p.add_run(text)
rest.font.name = "Arial"
rest.font.size = Pt(11)
else:
run = p.add_run(text)
run.font.name = "Arial"
run.font.size = Pt(11)
def add_alert_box(doc, label, text, bg="FF0000", fg="FFFFFF"):
"""Single-row coloured alert banner."""
tbl = doc.add_table(rows=1, cols=1)
tbl.style = "Table Grid"
cell = tbl.cell(0, 0)
set_cell_bg(cell, bg)
p = cell.paragraphs[0]
p.alignment = WD_ALIGN_PARAGRAPH.LEFT
r1 = p.add_run(f"{label} ")
r1.bold = True
r1.font.name = "Arial"
r1.font.size = Pt(11)
r1.font.color.rgb = RGBColor(int(fg[0:2],16), int(fg[2:4],16), int(fg[4:6],16))
r2 = p.add_run(text)
r2.font.name = "Arial"
r2.font.size = Pt(11)
r2.font.color.rgb = RGBColor(int(fg[0:2],16), int(fg[2:4],16), int(fg[4:6],16))
doc.add_paragraph()
# ════════════════════════════════════════════════
# COVER / TITLE
# ════════════════════════════════════════════════
title_p = doc.add_paragraph()
title_p.alignment = WD_ALIGN_PARAGRAPH.CENTER
r = title_p.add_run("Giant Cell Arteritis (GCA)")
r.bold = True; r.font.size = Pt(24); r.font.color.rgb = DARK_RED; r.font.name = "Arial"
sub_p = doc.add_paragraph()
sub_p.alignment = WD_ALIGN_PARAGRAPH.CENTER
r2 = sub_p.add_run("Management and Treatment Protocol in Autoimmune Patients")
r2.bold = True; r2.font.size = Pt(16); r2.font.color.rgb = NAVY; r2.font.name = "Arial"
doc.add_paragraph()
info_p = doc.add_paragraph()
info_p.alignment = WD_ALIGN_PARAGRAPH.CENTER
r3 = info_p.add_run(f"Version 1.0 | Issued: {datetime.date.today().strftime('%B %Y')} | Department of Rheumatology")
r3.font.size = Pt(10); r3.font.color.rgb = RGBColor(0x80,0x80,0x80); r3.font.name = "Arial"
doc.add_paragraph()
doc.add_paragraph()
# ════════════════════════════════════════════════
# SECTION 1 – SCOPE AND PURPOSE
# ════════════════════════════════════════════════
add_heading(doc, "1. Scope and Purpose", 1, NAVY)
add_para(doc,
"This protocol provides a standardised framework for the diagnosis, immediate management, "
"pharmacological treatment, monitoring, and follow-up of Giant Cell Arteritis (GCA) — "
"also known as temporal arteritis — with particular reference to patients who have an "
"existing autoimmune background (e.g., ANA positivity, undifferentiated connective tissue disease, "
"Sjögren's syndrome, or prior inflammatory arthritis).",
size=11)
add_para(doc,
"GCA is the most common primary systemic vasculitis in adults. Irreversible visual loss remains "
"its most feared complication; prompt recognition and treatment are mandatory.",
bold=False, size=11)
doc.add_paragraph()
# ════════════════════════════════════════════════
# SECTION 2 – BACKGROUND
# ════════════════════════════════════════════════
add_heading(doc, "2. Background and Pathophysiology", 1, NAVY)
add_para(doc,
"GCA is a granulomatous vasculitis primarily affecting medium- and large-sized arteries "
"— particularly the extracranial branches of the carotid artery (temporal, ophthalmic, "
"posterior ciliary arteries) and the thoracic aorta. Inflammatory infiltrates of CD4+ T-cells, "
"macrophages, and multinucleated giant cells cause arterial wall damage, intimal hyperplasia, "
"and luminal narrowing.",
size=11)
doc.add_paragraph()
add_para(doc, "Key epidemiological facts:", bold=True, size=11)
add_bullet(doc, "Occurs almost exclusively in patients aged >50 years (peak incidence 70-80 years).")
add_bullet(doc, "Women affected 2-3x more frequently than men.")
add_bullet(doc, "Strong association with HLA-DR4 haplotype.")
add_bullet(doc, "18x increased risk of thoracic aortic aneurysm vs. general population (Harrison's, 2025).")
add_bullet(doc, "In autoimmune patients: ANA positivity, prior undifferentiated CTD, or Sjögren's syndrome "
"may overlap; vigilance is required as serological markers from the background disease can "
"obscure interpretation of inflammatory markers.")
doc.add_paragraph()
# ════════════════════════════════════════════════
# SECTION 3 – DIAGNOSIS
# ════════════════════════════════════════════════
add_heading(doc, "3. Diagnostic Criteria and Work-up", 1, NAVY)
add_heading(doc, "3.1 ACR/EULAR 2022 Classification Criteria", 2, TEAL)
add_para(doc,
"The updated 2022 ACR/EULAR classification requires age ≥50 years at symptom onset. "
"The following weighted criteria are then applied (total ≥6 = GCA classification):",
size=11)
# Criteria table
tbl = doc.add_table(rows=9, cols=3)
tbl.style = "Table Grid"
headers = ["Criterion", "Threshold", "Score"]
for i, h in enumerate(headers):
cell = tbl.cell(0, i)
set_cell_bg(cell, "1F3964")
p = cell.paragraphs[0]
r = p.add_run(h)
r.bold = True; r.font.name = "Arial"; r.font.size = Pt(10)
r.font.color.rgb = WHITE
rows_data = [
("New temporal headache", "New onset or new type of localised head pain", "+2"),
("Jaw or tongue claudication", "Pain/fatigue in jaw muscles on chewing", "+2"),
("Sudden visual loss", "Acute or subacute monocular visual loss", "+3"),
("Scalp tenderness", "Tenderness on palpation of scalp", "+2"),
("Abnormal temporal artery exam", "Tenderness or decreased pulsation", "+2"),
("ESR ≥50 mm/hr or CRP ≥10 mg/L", "Peak acute-phase reactant elevation", "+3"),
("Positive TAB or halo sign on US", "Biopsy vasculitis or ultrasound halo", "+5"),
("Morning stiffness in shoulders/neck", "PMR-like symptom overlap", "+2"),
]
for i, (c1, c2, c3) in enumerate(rows_data):
row = tbl.rows[i+1]
bg = "F2F2F2" if i % 2 == 0 else "FFFFFF"
for j, txt in enumerate([c1, c2, c3]):
cell = row.cells[j]
set_cell_bg(cell, bg)
p = cell.paragraphs[0]
r = p.add_run(txt)
r.font.name = "Arial"; r.font.size = Pt(10)
if j == 2:
r.bold = True; r.font.color.rgb = RED
doc.add_paragraph()
add_heading(doc, "3.2 Mandatory Immediate Work-up", 2, TEAL)
add_para(doc, "Initiate ALL of the following before or simultaneously with empirical treatment:", size=11)
workup_tbl = doc.add_table(rows=8, cols=3)
workup_tbl.style = "Table Grid"
for i, h in enumerate(["Investigation", "Rationale", "Urgency"]):
cell = workup_tbl.cell(0, i)
set_cell_bg(cell, "007070")
p = cell.paragraphs[0]
r = p.add_run(h)
r.bold = True; r.font.name = "Arial"; r.font.size = Pt(10); r.font.color.rgb = WHITE
wu_rows = [
("ESR + CRP + Platelet count", "Elevated in >95% of active GCA; guide taper", "STAT"),
("FBC, LFTs, renal function", "Baseline before steroids; detect haematological malignancy", "Same day"),
("Temporal artery ultrasound (halo sign)", "Non-invasive; included in 2022 ACR criteria", "Within 24 hrs"),
("Temporal artery biopsy (TAB)", "Gold standard; do NOT delay treatment for result", "Within 1 week"),
("Ophthalmology referral", "Visual field, fundus, RAPD; prevent irreversible loss", "SAME DAY if visual Sx"),
("ANA panel, Anti-dsDNA, complement", "Characterise autoimmune background; rule out SLE flare", "Same day"),
("Anti-Ro/SSA, Anti-La/SSB", "Rule out Sjögren's overlap", "Same day"),
]
for i, (c1, c2, c3) in enumerate(wu_rows):
row = workup_tbl.rows[i+1]
bg = "F2F2F2" if i % 2 == 0 else "FFFFFF"
for j, txt in enumerate([c1, c2, c3]):
cell = row.cells[j]
set_cell_bg(cell, bg)
p = cell.paragraphs[0]
r = p.add_run(txt)
r.font.name = "Arial"; r.font.size = Pt(10)
if j == 2 and "SAME" in txt:
r.bold = True; r.font.color.rgb = RED
elif j == 2 and "STAT" in txt:
r.bold = True; r.font.color.rgb = ORANGE
doc.add_paragraph()
# ALERT BOX
add_alert_box(doc,
"CRITICAL:",
"Do NOT wait for biopsy results before starting corticosteroids when clinical suspicion is high. "
"Histological changes persist for up to 2 weeks after steroid initiation.",
bg="C00000", fg="FFFFFF")
# ════════════════════════════════════════════════
# SECTION 4 – TREATMENT
# ════════════════════════════════════════════════
add_heading(doc, "4. Pharmacological Treatment Protocol", 1, NAVY)
add_heading(doc, "4.1 First-Line: Glucocorticoids", 2, TEAL)
add_para(doc,
"Corticosteroids remain the cornerstone of GCA treatment. Both GCA and its symptoms are "
"highly responsive to glucocorticoid therapy. (Goldman-Cecil Medicine, 2024)",
size=11)
doc.add_paragraph()
# Treatment table
tx_tbl = doc.add_table(rows=5, cols=3)
tx_tbl.style = "Table Grid"
for i, h in enumerate(["Clinical Scenario", "Agent & Dose", "Duration / Notes"]):
cell = tx_tbl.cell(0, i)
set_cell_bg(cell, "1F3964")
p = cell.paragraphs[0]
r = p.add_run(h)
r.bold = True; r.font.name = "Arial"; r.font.size = Pt(10); r.font.color.rgb = WHITE
tx_rows = [
("Standard GCA (no visual symptoms)",
"Prednisone 40-60 mg/day orally in divided doses",
"Maintain for ~1 month; then taper by 5-10 mg every 7-10 days"),
("GCA with visual loss or amaurosis fugax",
"IV Methylprednisolone 500 mg-1 g/day for 3 days, then oral prednisone 60 mg/day",
"Intravenous pulse to protect remaining vision; follow with oral taper"),
("GCA with high glucocorticoid toxicity risk",
"Prednisone 40-60 mg + Tocilizumab 162 mg SC weekly",
"Superior sustained remission at 12 months (GIACTA trial); allows faster taper"),
("Polymyalgia rheumatica co-existing with GCA",
"Prednisone 15-20 mg/day (PMR component)",
"GCA dose takes precedence; do not under-treat"),
]
for i, (c1, c2, c3) in enumerate(tx_rows):
row = tx_tbl.rows[i+1]
bg = "FFF2CC" if i % 2 == 0 else "FFFFFF"
for j, txt in enumerate([c1, c2, c3]):
cell = row.cells[j]
set_cell_bg(cell, bg)
p = cell.paragraphs[0]
r = p.add_run(txt)
r.font.name = "Arial"; r.font.size = Pt(10)
doc.add_paragraph()
add_heading(doc, "4.2 Steroid Taper Protocol", 2, TEAL)
add_para(doc,
"Symptom recurrence during prednisone tapering occurs in 60-85% of GCA patients. "
"Taper MUST be guided by clinical response, NOT ESR/CRP alone. (Harrison's 2025)",
size=11)
add_bullet(doc, "Weeks 1-4: Maintain starting dose (40-60 mg/day). ESR, CRP, Hb, and platelets should normalise.", bold_prefix="Phase 1 – Induction: ")
add_bullet(doc, "Reduce by 5-10 mg every 7-10 days until reaching 20 mg/day.", bold_prefix="Phase 2 – Initial taper: ")
add_bullet(doc, "Reduce by 2.5 mg every 2-4 weeks until reaching 10 mg/day.", bold_prefix="Phase 3 – Slow taper: ")
add_bullet(doc, "Reduce by 1 mg every 4-8 weeks. Total duration usually ≥2 years.", bold_prefix="Phase 4 – Maintenance taper: ")
add_bullet(doc, "Alternate-day regimens are NOT recommended in GCA (higher failure rate).", bold_prefix="Important: ")
doc.add_paragraph()
add_heading(doc, "4.3 Steroid-Sparing / Adjunct Therapy", 2, TEAL)
adj_tbl = doc.add_table(rows=5, cols=4)
adj_tbl.style = "Table Grid"
for i, h in enumerate(["Agent", "Dose", "Indication", "Evidence Level"]):
cell = adj_tbl.cell(0, i)
set_cell_bg(cell, "007070")
p = cell.paragraphs[0]
r = p.add_run(h)
r.bold = True; r.font.name = "Arial"; r.font.size = Pt(10); r.font.color.rgb = WHITE
adj_rows = [
("Tocilizumab (IL-6 receptor inhibitor)", "162 mg SC weekly OR 6 mg/kg IV q4 weeks",
"FDA-approved for GCA; first-line steroid-sparer; reduce cumulative steroid dose",
"RCT (GIACTA) — High"),
("Sarilumab (IL-6 inhibitor)", "200 mg SC q2 weeks",
"Approved for refractory PMR; off-label GCA consideration",
"RCT — Moderate"),
("Methotrexate", "7.5-15 mg weekly (+ folate)",
"Second-line steroid-sparer; conflicting RCT results; use if tocilizumab intolerant",
"RCT — Low-Moderate"),
("Low-dose Aspirin", "75-100 mg daily",
"Reduce ischaemic complications; adjunctive only — marginal evidence",
"Observational — Low"),
]
for i, row_data in enumerate(adj_rows):
row = adj_tbl.rows[i+1]
bg = "F2F2F2" if i % 2 == 0 else "FFFFFF"
for j, txt in enumerate(row_data):
cell = row.cells[j]
set_cell_bg(cell, bg)
p = cell.paragraphs[0]
r = p.add_run(txt)
r.font.name = "Arial"; r.font.size = Pt(10)
doc.add_paragraph()
add_heading(doc, "4.4 Special Considerations in Autoimmune Patients", 2, TEAL)
add_para(doc,
"Patients with a background autoimmune disease (ANA+, prior UCTD, Sjögren's, SLE) require "
"additional vigilance during GCA treatment:",
size=11)
add_bullet(doc, "Background ANA/anti-dsDNA serology may remain elevated independently of GCA activity — use clinical symptoms and ESR/CRP trends together.", bold_prefix="Serological interpretation: ")
add_bullet(doc, "Prior DMARD use (e.g., hydroxychloroquine, methotrexate) does NOT confer protection against GCA; do not reduce vigilance.", bold_prefix="Prior DMARD history: ")
add_bullet(doc, "Tocilizumab may suppress ESR/CRP even in the presence of ongoing vascular inflammation — rely on imaging (PET-CT or MRA) when markers are suppressed.", bold_prefix="Tocilizumab masking effect: ")
add_bullet(doc, "Screen for drug interactions between tocilizumab and existing DMARDs (particularly methotrexate — monitoring of LFTs/FBC required).", bold_prefix="Drug interactions: ")
add_bullet(doc, "Patients on long-term hydroxychloroquine for UCTD: continue this therapy; it does not interfere with GCA management.", bold_prefix="Hydroxychloroquine: ")
doc.add_paragraph()
# ════════════════════════════════════════════════
# SECTION 5 – MONITORING
# ════════════════════════════════════════════════
add_heading(doc, "5. Monitoring Protocol", 1, NAVY)
add_heading(doc, "5.1 Monitoring Schedule", 2, TEAL)
mon_tbl = doc.add_table(rows=7, cols=3)
mon_tbl.style = "Table Grid"
for i, h in enumerate(["Time Point", "Investigations", "Clinical Assessment"]):
cell = mon_tbl.cell(0, i)
set_cell_bg(cell, "1F3964")
p = cell.paragraphs[0]
r = p.add_run(h)
r.bold = True; r.font.name = "Arial"; r.font.size = Pt(10); r.font.color.rgb = WHITE
mon_rows = [
("Week 1-2", "ESR, CRP, FBC, glucose", "Symptom response; visual acuity check; blood pressure"),
("Month 1", "ESR, CRP, HbA1c, LFTs, bone profile", "Steroid side-effect screen; ophthalmology review if visual Sx"),
("Months 2-6 (during taper)", "ESR, CRP monthly; FBC, LFTs q6-8 weeks", "Relapse symptoms; weight, BP, glucose; bone density baseline (DEXA)"),
("Months 6-12", "ESR, CRP every 6-8 weeks", "Taper progress; screen for aortic complications"),
("Year 1-2", "Annual ESR, CRP, DEXA; ANA recheck", "Monitor for evolving CTD in autoimmune patients; osteoporosis"),
("If on Tocilizumab", "FBC, LFTs q4-8 weeks; lipid profile q6 months", "Monitor for neutropenia, hepatotoxicity, hyperlipidaemia"),
]
for i, row_data in enumerate(mon_rows):
row = mon_tbl.rows[i+1]
bg = "F2F2F2" if i % 2 == 0 else "FFFFFF"
for j, txt in enumerate(row_data):
cell = row.cells[j]
set_cell_bg(cell, bg)
p = cell.paragraphs[0]
r = p.add_run(txt)
r.font.name = "Arial"; r.font.size = Pt(10)
doc.add_paragraph()
add_heading(doc, "5.2 Interpreting Inflammatory Markers During Taper", 2, TEAL)
add_para(doc,
"ESR and CRP are useful but imperfect markers. Minor rises during taper do not automatically "
"indicate relapse — particularly if the patient is asymptomatic. (Harrison's 2025)",
size=11)
add_bullet(doc, "Symptomatic relapse + rising ESR/CRP → increase prednisone by 5-10 mg to the last effective dose.")
add_bullet(doc, "Asymptomatic ESR/CRP rise → continue taper with caution; recheck in 2-4 weeks; rule out infection.")
add_bullet(doc, "In tocilizumab-treated patients: ESR/CRP are suppressed regardless of disease activity. Rely on PET-CT or MRA for imaging-based disease assessment in refractory or suspected relapsing cases.")
doc.add_paragraph()
# ════════════════════════════════════════════════
# SECTION 6 – COMPLICATION PREVENTION
# ════════════════════════════════════════════════
add_heading(doc, "6. Complication Prevention and Supportive Measures", 1, NAVY)
add_para(doc, "Glucocorticoid toxicity occurs in 35-65% of GCA patients. (Goldman-Cecil, 2024)", size=11, bold=True)
doc.add_paragraph()
comp_tbl = doc.add_table(rows=7, cols=3)
comp_tbl.style = "Table Grid"
for i, h in enumerate(["Complication", "Prevention Strategy", "Threshold"]):
cell = comp_tbl.cell(0, i)
set_cell_bg(cell, "BF6000")
p = cell.paragraphs[0]
r = p.add_run(h)
r.bold = True; r.font.name = "Arial"; r.font.size = Pt(10); r.font.color.rgb = WHITE
comp_rows = [
("Osteoporosis", "Calcium 1000-1200 mg/day + Vitamin D 800 IU/day; bisphosphonate (alendronate/risedronate) if DEXA T-score <-1.5", "Start at initiation of steroids"),
("Peptic ulcer disease", "PPI (omeprazole 20 mg/day) particularly if on aspirin", "If aspirin co-prescribed or GI risk factors"),
("Hyperglycaemia", "Monitor fasting glucose weekly initially; intensify diabetes management if needed", "Fasting glucose >7.0 mmol/L"),
("Hypertension", "BP monitoring; ACE inhibitor or ARB if indicated", "BP >140/90 mmHg"),
("Infections", "Pneumocystis prophylaxis (co-trimoxazole) if on >20 mg/day prednisone >1 month; annual influenza + pneumococcal vaccine", "Ongoing high-dose steroids"),
("Aortic aneurysm", "Annual thoracic aorta imaging (CT or MRA) in long-standing GCA", "Patients with GCA for >2 years"),
]
for i, row_data in enumerate(comp_rows):
row = comp_tbl.rows[i+1]
bg = "FFF2CC" if i % 2 == 0 else "FFFFFF"
for j, txt in enumerate(row_data):
cell = row.cells[j]
set_cell_bg(cell, bg)
p = cell.paragraphs[0]
r = p.add_run(txt)
r.font.name = "Arial"; r.font.size = Pt(10)
doc.add_paragraph()
# ════════════════════════════════════════════════
# SECTION 7 – RELAPSE MANAGEMENT
# ════════════════════════════════════════════════
add_heading(doc, "7. Relapse Recognition and Management", 1, NAVY)
add_para(doc,
"Relapse occurs in 60-85% of GCA patients during steroid tapering. Distinguish true "
"relapse from steroid dependence and background autoimmune disease flare.",
size=11)
add_heading(doc, "7.1 Relapse Criteria", 2, TEAL)
add_bullet(doc, "Return or worsening of GCA symptoms (new headache, jaw claudication, visual symptoms, scalp tenderness).")
add_bullet(doc, "Rise in ESR ≥30 mm/hr above nadir OR CRP ≥2x upper limit of normal.")
add_bullet(doc, "New ischaemic event (vision loss, stroke) attributable to GCA.")
add_heading(doc, "7.2 Relapse Treatment", 2, TEAL)
add_bullet(doc, "Minor relapse (symptoms only, no visual threat): increase to the last effective prednisone dose.", bold_prefix="Minor relapse: ")
add_bullet(doc, "Major relapse (new visual symptoms): IV methylprednisolone 500 mg-1 g/day for 3 days → re-escalate oral prednisone 60 mg/day.", bold_prefix="Major relapse: ")
add_bullet(doc, "Recurrent relapses: add or escalate tocilizumab; consider methotrexate if tocilizumab not tolerated.", bold_prefix="Refractory GCA: ")
doc.add_paragraph()
# ════════════════════════════════════════════════
# SECTION 8 – PATIENT EDUCATION
# ════════════════════════════════════════════════
add_heading(doc, "8. Patient Education and Red-Flag Counselling", 1, NAVY)
add_para(doc, "All GCA patients must be educated to report the following IMMEDIATELY:", bold=True, color=RED, size=11)
add_bullet(doc, "Any sudden or new visual disturbance (blurring, double vision, transient vision loss).")
add_bullet(doc, "Worsening jaw pain on eating.")
add_bullet(doc, "New severe headache.")
add_bullet(doc, "Scalp tenderness or scalp ulceration.")
add_bullet(doc, "Arm pain on exertion (large-vessel GCA).")
doc.add_paragraph()
add_para(doc, "General steroid education:", bold=True, size=11)
add_bullet(doc, "Never stop steroids abruptly — risk of adrenal insufficiency.")
add_bullet(doc, "Carry a steroid alert card.")
add_bullet(doc, "Report any infection promptly — immune suppression risk.")
add_bullet(doc, "Weight-bearing exercise and calcium-rich diet to support bone health.")
doc.add_paragraph()
# ════════════════════════════════════════════════
# SECTION 9 – FLOWCHART SUMMARY
# ════════════════════════════════════════════════
add_heading(doc, "9. Algorithmic Summary", 1, NAVY)
algo_steps = [
("STEP 1", "Clinical suspicion of GCA (headache + jaw claudication + periorbital swelling + autoimmune background)", "C00000", "FFFFFF"),
("STEP 2", "STAT ESR, CRP, FBC → Temporal artery ultrasound within 24 hrs → Ophthalmology same day if visual symptoms", "BF6000", "FFFFFF"),
("STEP 3", "Start Prednisone 40-60 mg/day IMMEDIATELY — do not wait for biopsy results", "C00000", "FFFFFF"),
("STEP 4", "Temporal artery biopsy within 1 week (histological confirmation)", "1F3964", "FFFFFF"),
("STEP 5", "Assess tocilizumab candidacy: high steroid toxicity risk, recurrent relapse, or severe disease", "007070", "FFFFFF"),
("STEP 6", "Steroid taper protocol (Sections 4.2); monitor ESR/CRP monthly during taper", "1F3964", "FFFFFF"),
("STEP 7", "Complication prevention: bone protection, PPI, glucose, BP, infection prophylaxis (Section 6)", "007070", "FFFFFF"),
("STEP 8", "Annual imaging of thoracic aorta after year 1; ongoing monitoring for evolving CTD in autoimmune patients", "BF6000", "FFFFFF"),
]
for step, text, bg, fg in algo_steps:
tbl = doc.add_table(rows=1, cols=2)
tbl.style = "Table Grid"
# Step label
c1 = tbl.cell(0, 0)
set_cell_bg(c1, bg)
c1.width = Inches(1.2)
p1 = c1.paragraphs[0]
p1.alignment = WD_ALIGN_PARAGRAPH.CENTER
r1 = p1.add_run(step)
r1.bold = True; r1.font.name = "Arial"; r1.font.size = Pt(11)
r1.font.color.rgb = RGBColor(int(fg[0:2],16), int(fg[2:4],16), int(fg[4:6],16))
# Content
c2 = tbl.cell(0, 1)
set_cell_bg(c2, "FAFAFA")
p2 = c2.paragraphs[0]
r2 = p2.add_run(text)
r2.font.name = "Arial"; r2.font.size = Pt(10)
doc.add_paragraph().paragraph_format.space_after = Pt(2)
doc.add_paragraph()
# ════════════════════════════════════════════════
# SECTION 10 – REFERENCES
# ════════════════════════════════════════════════
add_heading(doc, "10. References and Evidence Base", 1, NAVY)
refs = [
"Firestein & Kelley's Textbook of Rheumatology (11th ed., 2023). Chapter 89: Giant Cell Arteritis and Polymyalgia Rheumatica. Elsevier.",
"Harrison's Principles of Internal Medicine (22nd ed., 2025). Chapter: Giant Cell Arteritis and Polymyalgia Rheumatica. McGraw-Hill.",
"Goldman-Cecil Medicine (27th ed., 2024). Chapter 250: Giant Cell Arteritis and Polymyalgia Rheumatica. Elsevier.",
"Kanski's Clinical Ophthalmology (10th ed., 2024). Chapter: Giant Cell Arteritis — Ocular Manifestations. Elsevier.",
"Stone JH et al. (2017). Trial of Tocilizumab in Giant-Cell Arteritis (GiACTA). N Engl J Med, 377:317-328. (PMID: 28745999)",
"ACR/EULAR 2022 Classification Criteria for Giant Cell Arteritis. Arthritis & Rheumatology, 2022.",
"Bradley and Daroff's Neurology in Clinical Practice (8th ed., 2022). Chapter: Giant Cell Arteritis — Neurological Aspects. Elsevier.",
]
for i, ref in enumerate(refs):
p = doc.add_paragraph()
p.paragraph_format.left_indent = Inches(0.25)
p.paragraph_format.space_after = Pt(4)
r = p.add_run(f"{i+1}. {ref}")
r.font.name = "Arial"; r.font.size = Pt(10); r.font.color.rgb = RGBColor(0x40,0x40,0x40)
doc.add_paragraph()
# ════════════════════════════════════════════════
# FOOTER NOTE
# ════════════════════════════════════════════════
footer_p = doc.add_paragraph()
footer_p.alignment = WD_ALIGN_PARAGRAPH.CENTER
rf = footer_p.add_run(
"This protocol is for clinical guidance only. Individual patient management decisions must be made by a qualified clinician. "
"Review annually or when new guidelines are published.")
rf.italic = True; rf.font.size = Pt(9); rf.font.name = "Arial"
rf.font.color.rgb = RGBColor(0x80, 0x80, 0x80)
# ── Save
output_path = "/tmp/workspace/gca-protocol/GCA_Management_Protocol.docx"
doc.save(output_path)
print(f"Saved: {output_path}")
cd /tmp/workspace/gca-protocol && python3 build_gca_protocol.py
python3 -c " from docx import Document doc = Document('/tmp/workspace/gca-protocol/GCA_Management_Protocol.docx') for p in doc.paragraphs[:30]: if p.text.strip(): print(f'[{p.style.name}] {p.text[:80]}') "
GCA Management Protocol
Word Document · DOCX