~/clinic-protocol/generate.js
const {
Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell,
Header, Footer, AlignmentType, HeadingLevel, BorderStyle, WidthType,
ShadingType, VerticalAlign, PageNumber, PageBreak, UnderlineType,
TableOfContents
} = require('docx');
const fs = require('fs');
// ─── Colour palette ───────────────────────────────────────────────────────────
const DARK_BLUE = "1B3A6B";
const MID_BLUE = "2E6DA4";
const LIGHT_BLUE = "D6E4F0";
const HEADER_BG = "1B3A6B";
const WHITE = "FFFFFF";
const GRAY_BG = "F2F6FA";
const BORDER_CLR = "2E6DA4";
// ─── Helpers ──────────────────────────────────────────────────────────────────
const emptyPara = (size = 6) =>
new Paragraph({ children: [new TextRun({ text: "", size })] });
const heading1 = (text) =>
new Paragraph({
heading: HeadingLevel.HEADING_1,
spacing: { before: 340, after: 120 },
children: [new TextRun({ text, bold: true, color: DARK_BLUE, size: 36, font: "Calibri" })]
});
const heading2 = (text) =>
new Paragraph({
heading: HeadingLevel.HEADING_2,
spacing: { before: 240, after: 80 },
children: [new TextRun({ text, bold: true, color: MID_BLUE, size: 28, font: "Calibri" })]
});
const heading3 = (text) =>
new Paragraph({
heading: HeadingLevel.HEADING_3,
spacing: { before: 160, after: 60 },
children: [new TextRun({ text, bold: true, color: "444444", size: 24, font: "Calibri" })]
});
const bodyText = (text, { bold = false, italic = false } = {}) =>
new Paragraph({
spacing: { before: 60, after: 60 },
children: [new TextRun({ text, bold, italic, size: 22, font: "Calibri", color: "222222" })]
});
const bullet = (text, level = 0) =>
new Paragraph({
bullet: { level },
spacing: { before: 40, after: 40 },
children: [new TextRun({ text, size: 22, font: "Calibri", color: "222222" })]
});
// Coloured section label box
const sectionLabel = (text) =>
new Paragraph({
spacing: { before: 200, after: 100 },
shading: { type: ShadingType.SOLID, color: HEADER_BG, fill: HEADER_BG },
children: [new TextRun({ text: " " + text + " ", bold: true, color: WHITE, size: 28, font: "Calibri" })]
});
// ─── Table helper ─────────────────────────────────────────────────────────────
const makeCell = (text, { header = false, width = null, bg = null, bold = null } = {}) => {
const isHeader = header;
const fill = bg || (isHeader ? HEADER_BG : WHITE);
const textColor = isHeader ? WHITE : "222222";
const isBold = bold !== null ? bold : isHeader;
const cell = new TableCell({
shading: { type: ShadingType.SOLID, color: fill, fill },
verticalAlign: VerticalAlign.CENTER,
margins: { top: 80, bottom: 80, left: 120, right: 120 },
...(width ? { width: { size: width, type: WidthType.DXA } } : {}),
children: [
new Paragraph({
alignment: AlignmentType.LEFT,
children: [new TextRun({ text, bold: isBold, color: textColor, size: 20, font: "Calibri" })]
})
]
});
return cell;
};
const makeRow = (cells, isHeader = false) =>
new TableRow({ tableHeader: isHeader, children: cells });
const tableWithBorder = (rows) =>
new Table({
width: { size: 100, type: WidthType.PERCENTAGE },
borders: {
top: { style: BorderStyle.SINGLE, size: 4, color: BORDER_CLR },
bottom: { style: BorderStyle.SINGLE, size: 4, color: BORDER_CLR },
left: { style: BorderStyle.SINGLE, size: 4, color: BORDER_CLR },
right: { style: BorderStyle.SINGLE, size: 4, color: BORDER_CLR },
insideH:{ style: BorderStyle.SINGLE, size: 2, color: "AAAAAA" },
insideV:{ style: BorderStyle.SINGLE, size: 2, color: "AAAAAA" },
},
rows
});
// ─── Cover Page ───────────────────────────────────────────────────────────────
const coverPage = [
emptyPara(80),
emptyPara(80),
new Paragraph({
alignment: AlignmentType.CENTER,
spacing: { before: 0, after: 40 },
children: [new TextRun({ text: "CLINIC TREATMENT PROTOCOL", bold: true, color: DARK_BLUE, size: 72, font: "Calibri" })]
}),
new Paragraph({
alignment: AlignmentType.CENTER,
spacing: { before: 20, after: 20 },
children: [new TextRun({ text: "Standard Management Guidelines for Common OPD Conditions", color: MID_BLUE, size: 36, font: "Calibri", italics: true })]
}),
emptyPara(40),
new Paragraph({
alignment: AlignmentType.CENTER,
shading: { type: ShadingType.SOLID, color: MID_BLUE, fill: MID_BLUE },
spacing: { before: 80, after: 80 },
children: [new TextRun({ text: " General Medicine — Adult Outpatient Department ", bold: true, color: WHITE, size: 28, font: "Calibri" })]
}),
emptyPara(80),
emptyPara(80),
emptyPara(80),
emptyPara(80),
new Paragraph({
alignment: AlignmentType.CENTER,
spacing: { before: 40, after: 20 },
children: [new TextRun({ text: "Version 1.0 | July 2026", color: "555555", size: 22, font: "Calibri" })]
}),
new Paragraph({
alignment: AlignmentType.CENTER,
spacing: { before: 10, after: 10 },
children: [new TextRun({ text: "Reviewed & Approved by Clinical Governance Committee", color: "555555", size: 20, font: "Calibri", italics: true })]
}),
new Paragraph({
alignment: AlignmentType.CENTER,
spacing: { before: 10, after: 10 },
children: [new TextRun({ text: "Review Due: July 2028", color: "888888", size: 20, font: "Calibri" })]
}),
new Paragraph({ children: [new PageBreak()] }),
];
// ─── Preamble ─────────────────────────────────────────────────────────────────
const preamble = [
heading1("Introduction & Scope"),
bodyText("This document sets out the standard treatment protocols for the most frequently encountered adult outpatient conditions at our clinic. The protocols are based on current evidence-based guidelines including ACC/AHA, GINA, WHO, and major medical textbooks (Goldman-Cecil Medicine, Harrison's Principles, Tintinalli's Emergency Medicine)."),
bodyText("All clinicians are expected to follow these protocols as a minimum standard of care. Individual patient circumstances may require deviation; any such deviation must be documented in the patient record with clinical justification."),
emptyPara(),
heading2("How to Use This Document"),
bullet("Each condition section contains: Definition, Diagnostic Criteria, and Stepwise Treatment."),
bullet("Drug doses listed are for adults with normal renal and hepatic function unless stated."),
bullet("Adjust doses for renal impairment, elderly patients, and special populations."),
bullet("Refer to BNF or local formulary for full drug information."),
emptyPara(),
heading2("Abbreviations"),
tableWithBorder([
makeRow([makeCell("Abbreviation", { header: true }), makeCell("Meaning", { header: true })], true),
makeRow([makeCell("ACEi"), makeCell("Angiotensin Converting Enzyme Inhibitor")]),
makeRow([makeCell("ARB"), makeCell("Angiotensin Receptor Blocker")]),
makeRow([makeCell("BD"), makeCell("Twice daily")]),
makeRow([makeCell("CCB"), makeCell("Calcium Channel Blocker")]),
makeRow([makeCell("DM"), makeCell("Diabetes Mellitus")]),
makeRow([makeCell("GERD"), makeCell("Gastroesophageal Reflux Disease")]),
makeRow([makeCell("GLP-1 RA"), makeCell("Glucagon-Like Peptide-1 Receptor Agonist")]),
makeRow([makeCell("H2RA"), makeCell("Histamine-2 Receptor Antagonist")]),
makeRow([makeCell("HbA1c"), makeCell("Glycated Haemoglobin")]),
makeRow([makeCell("HTN"), makeCell("Hypertension")]),
makeRow([makeCell("ICS"), makeCell("Inhaled Corticosteroid")]),
makeRow([makeCell("LABA"), makeCell("Long-Acting Beta-Agonist")]),
makeRow([makeCell("NSAID"), makeCell("Non-Steroidal Anti-Inflammatory Drug")]),
makeRow([makeCell("OD"), makeCell("Once daily")]),
makeRow([makeCell("PPI"), makeCell("Proton Pump Inhibitor")]),
makeRow([makeCell("PRN"), makeCell("As needed")]),
makeRow([makeCell("SABA"), makeCell("Short-Acting Beta-Agonist")]),
makeRow([makeCell("SGLT-2i"), makeCell("Sodium-Glucose Cotransporter-2 Inhibitor")]),
makeRow([makeCell("TDS"), makeCell("Three times daily")]),
makeRow([makeCell("UTI"), makeCell("Urinary Tract Infection")]),
]),
new Paragraph({ children: [new PageBreak()] }),
];
// ─── Section 1 — Hypertension ─────────────────────────────────────────────────
const hypertension = [
sectionLabel("01 | HYPERTENSION (ESSENTIAL)"),
heading2("Definition"),
bodyText("Systolic BP ≥ 130 mmHg OR Diastolic BP ≥ 80 mmHg on two separate occasions (2017 ACC/AHA Guidelines). Diagnosis requires confirmation with at least two readings taken at two separate visits."),
heading2("Diagnostic Classification"),
tableWithBorder([
makeRow([makeCell("Stage",{header:true}),makeCell("Systolic (mmHg)",{header:true}),makeCell("Diastolic (mmHg)",{header:true})],true),
makeRow([makeCell("Normal"), makeCell("< 120"), makeCell("< 80")]),
makeRow([makeCell("Elevated"), makeCell("120–129"), makeCell("< 80")]),
makeRow([makeCell("Stage 1 HTN"), makeCell("130–139"), makeCell("80–89")]),
makeRow([makeCell("Stage 2 HTN"), makeCell("≥ 140"), makeCell("≥ 90")]),
makeRow([makeCell("Hypertensive Crisis"), makeCell("≥ 180"), makeCell("≥ 120")]),
]),
emptyPara(),
heading2("Treatment Protocol"),
heading3("Step 1: Lifestyle Modification (All Patients)"),
bullet("DASH diet: rich in fruits, vegetables, low-fat dairy; limit sodium < 2.3 g/day"),
bullet("Weight reduction: 1 mmHg BP reduction per 1 kg weight loss"),
bullet("Aerobic exercise: 150 min/week moderate intensity"),
bullet("Limit alcohol: ≤ 2 drinks/day (men), ≤ 1 drink/day (women)"),
bullet("Smoking cessation"),
emptyPara(),
heading3("Step 2: First-Line Pharmacotherapy"),
bodyText("Use one or more of the 4 preferred drug classes:"),
tableWithBorder([
makeRow([makeCell("Drug Class",{header:true}),makeCell("Examples",{header:true}),makeCell("Preferred In",{header:true}),makeCell("Avoid In",{header:true})],true),
makeRow([makeCell("Thiazide Diuretic"), makeCell("Hydrochlorothiazide 12.5–25 mg OD\nChlorthalidone 12.5–25 mg OD"), makeCell("Elderly, isolated systolic HTN, Black patients"), makeCell("Gout, hypokalemia")]),
makeRow([makeCell("ACE Inhibitor"), makeCell("Enalapril 5–40 mg OD\nLisinopril 10–40 mg OD"), makeCell("DM, CKD, Heart Failure, post-MI"), makeCell("Pregnancy, bilateral renal artery stenosis, hyperkalemia")]),
makeRow([makeCell("ARB"), makeCell("Losartan 50–100 mg OD\nValsartan 80–320 mg OD"), makeCell("ACEi-intolerant (cough), DM, CKD"), makeCell("Pregnancy")]),
makeRow([makeCell("Calcium Channel Blocker"), makeCell("Amlodipine 5–10 mg OD\nNifedipine ER 30–60 mg OD"), makeCell("Elderly, angina, isolated systolic HTN"), makeCell("Heart block (non-DHP CCBs)")]),
]),
emptyPara(),
heading3("Step 3: Resistant Hypertension (≥ 3 drugs)"),
bullet("Add aldosterone antagonist: Spironolactone 25–50 mg OD (check K+, eGFR; avoid if eGFR < 45)"),
bullet("Or Amiloride 5–10 mg OD"),
bullet("Beta-blockers (Atenolol, Bisoprolol, Carvedilol): adjunct only; especially useful if co-existing HF or IHD"),
bullet("Alpha-blockers (Doxazosin 2–8 mg OD): useful add-on; also helps BPH in men"),
emptyPara(),
heading3("Monitoring"),
bullet("BP recheck: 1 month after starting/adjusting therapy"),
bullet("Annual labs: U&E, eGFR, glucose, lipid profile"),
bullet("ECG at diagnosis and if symptoms of cardiac involvement"),
new Paragraph({ children: [new PageBreak()] }),
];
// ─── Section 2 — Type 2 Diabetes ─────────────────────────────────────────────
const diabetes = [
sectionLabel("02 | TYPE 2 DIABETES MELLITUS"),
heading2("Diagnostic Criteria (WHO/ADA)"),
tableWithBorder([
makeRow([makeCell("Test",{header:true}),makeCell("Diagnostic Value",{header:true})],true),
makeRow([makeCell("Fasting Plasma Glucose"), makeCell("≥ 7.0 mmol/L (126 mg/dL)")]),
makeRow([makeCell("2-hour Post-load Glucose (OGTT)"), makeCell("≥ 11.1 mmol/L (200 mg/dL)")]),
makeRow([makeCell("HbA1c"), makeCell("≥ 48 mmol/mol (≥ 6.5%)")]),
makeRow([makeCell("Random Glucose + symptoms"), makeCell("≥ 11.1 mmol/L (200 mg/dL)")]),
]),
emptyPara(),
heading2("Glycaemic Targets"),
bullet("HbA1c < 7.0% (53 mmol/mol): most adults"),
bullet("HbA1c < 8.0% (64 mmol/mol): elderly, limited life expectancy, hypoglycaemia-prone"),
bullet("HbA1c < 6.5% (48 mmol/mol): selected young, low CV risk, achieved without hypoglycaemia"),
emptyPara(),
heading2("Treatment Protocol (Stepwise)"),
heading3("Step 1: Lifestyle + Metformin Monotherapy"),
bodyText("Start Metformin for ALL patients unless contraindicated (eGFR < 30, lactic acidosis risk)."),
bullet("Metformin IR: start 500 mg OD with food; increase by 500 mg every 1–2 weeks"),
bullet("Target dose: 1000 mg BD (max 2550 mg/day)"),
bullet("If HbA1c > 9%: start dual therapy from the outset"),
bullet("If HbA1c > 10% or symptomatic hyperglycaemia: consider insulin from the outset"),
emptyPara(),
heading3("Step 2: Dual Therapy (if HbA1c not at target after 3 months)"),
bodyText("Add one agent to Metformin based on patient profile:"),
tableWithBorder([
makeRow([makeCell("Agent",{header:true}),makeCell("Dose",{header:true}),makeCell("Weight",{header:true}),makeCell("Hypo Risk",{header:true}),makeCell("Best For",{header:true})],true),
makeRow([makeCell("GLP-1 RA\n(Semaglutide)"), makeCell("0.5–1 mg SC weekly"), makeCell("Loss ↓↓"), makeCell("Low"), makeCell("CVD, obesity, NASH")]),
makeRow([makeCell("SGLT-2i\n(Empagliflozin)"), makeCell("10–25 mg OD"), makeCell("Loss ↓"), makeCell("Low"), makeCell("HF, CKD, CVD")]),
makeRow([makeCell("DPP-4i\n(Sitagliptin)"), makeCell("100 mg OD"), makeCell("Neutral"), makeCell("Low"), makeCell("Elderly, renal impairment")]),
makeRow([makeCell("Sulfonylurea\n(Glipizide)"), makeCell("2.5–20 mg OD/BD"), makeCell("Gain ↑"), makeCell("Moderate"), makeCell("Cost-constrained settings")]),
makeRow([makeCell("Basal Insulin\n(Glargine)"), makeCell("10 units SC nocte (titrate)"), makeCell("Gain ↑"), makeCell("High"), makeCell("Very high HbA1c, insulin deficiency")]),
]),
emptyPara(),
heading3("Step 3: Triple / Injectable Combination"),
bullet("Metformin + SGLT-2i + GLP-1 RA: preferred combination (cardiometabolic benefit)"),
bullet("Add basal insulin if HbA1c remains uncontrolled"),
bullet("Intensify to basal-bolus insulin if fasting + post-meal targets not met"),
emptyPara(),
heading2("Monitoring"),
bullet("HbA1c: every 3 months until stable, then every 6 months"),
bullet("Annual: renal function (eGFR + urine ACR), lipid profile, LFT"),
bullet("Annual: BP, BMI, foot examination, eye review (ophthalmology)"),
bullet("SMBG targets: fasting 4–7 mmol/L; 2hr post-meal < 10 mmol/L"),
new Paragraph({ children: [new PageBreak()] }),
];
// ─── Section 3 — GERD ────────────────────────────────────────────────────────
const gerd = [
sectionLabel("03 | GASTRO-OESOPHAGEAL REFLUX DISEASE (GERD)"),
heading2("Definition & Symptoms"),
bodyText("GERD is defined as troublesome symptoms or complications caused by the reflux of gastric contents into the oesophagus. Classic symptoms: heartburn, acid regurgitation. Atypical: chronic cough, laryngitis, asthma, chest pain, dental erosions."),
heading2("Treatment Protocol"),
heading3("Phase 1: Lifestyle Modification (Mandatory for All)"),
bullet("Weight loss (reduces LOS pressure)"),
bullet("Elevate head of bed 15–20 cm"),
bullet("Avoid trigger foods: fatty/fried foods, citrus, tomatoes, chocolate, coffee, alcohol"),
bullet("Eat small, frequent meals; avoid lying down within 2–3 hours of eating"),
bullet("Stop smoking"),
emptyPara(),
heading3("Phase 2: Pharmacotherapy"),
tableWithBorder([
makeRow([makeCell("Agent",{header:true}),makeCell("Drug/Dose",{header:true}),makeCell("Duration",{header:true}),makeCell("Notes",{header:true})],true),
makeRow([makeCell("Antacids"), makeCell("Aluminium/magnesium hydroxide PRN"), makeCell("As needed"), makeCell("Quick relief; not for daily use")]),
makeRow([makeCell("H2RA"), makeCell("Famotidine 20 mg BD"), makeCell("4–8 weeks"), makeCell("Mild/intermittent symptoms")]),
makeRow([makeCell("PPI (1st line)"), makeCell("Omeprazole 20–40 mg OD\nPantoprazole 40 mg OD\nLansoprazole 30 mg OD"), makeCell("4–8 weeks"), makeCell("Take 30–60 min before first meal; most effective treatment")]),
makeRow([makeCell("PPI maintenance"), makeCell("Lowest effective dose OD"), makeCell("Long-term if needed"), makeCell("Step-down or PRN dosing preferred; reassess every 6–12 months")]),
makeRow([makeCell("Prokinetic (add-on)"), makeCell("Metoclopramide 10 mg TDS (short-term only)"), makeCell("Max 5 days"), makeCell("For gastroparesis component; risk of EPS")]),
]),
emptyPara(),
heading3("Phase 3: Surgical Referral"),
bullet("Nissen fundoplication: consider if PPI-refractory, or patient intolerant of long-term PPIs"),
bullet("Confirm with 24-hr pH monitoring or impedance study before surgical referral"),
emptyPara(),
heading2("Red Flags — Refer for Endoscopy"),
bullet("Dysphagia, odynophagia, unexplained weight loss"),
bullet("GI bleeding (haematemesis, melaena)"),
bullet("Age > 55 with new-onset dyspepsia"),
bullet("Family history of oesophageal/gastric cancer"),
new Paragraph({ children: [new PageBreak()] }),
];
// ─── Section 4 — Peptic Ulcer Disease ────────────────────────────────────────
const pud = [
sectionLabel("04 | PEPTIC ULCER DISEASE (PUD)"),
heading2("Aetiology"),
bullet("H. pylori infection (60–70% of cases) — test all patients with PUD"),
bullet("NSAID/aspirin use — second most common cause"),
bullet("Stress ulcers (critically ill) — managed separately"),
bullet("Zollinger-Ellison syndrome — rare; consider if multiple/refractory ulcers"),
emptyPara(),
heading2("Treatment Protocol"),
heading3("For ALL patients: Acid Suppression"),
bullet("PPI: Omeprazole 20–40 mg BD during eradication, then OD for 4–8 weeks"),
bullet("Discontinue NSAIDs; if NSAID must be continued, maintain PPI long-term"),
emptyPara(),
heading3("H. pylori Eradication (if H. pylori positive)"),
tableWithBorder([
makeRow([makeCell("Regimen",{header:true}),makeCell("Drugs",{header:true}),makeCell("Duration",{header:true}),makeCell("Notes",{header:true})],true),
makeRow([makeCell("Standard Triple Therapy (1st line)"), makeCell("PPI BD\n+ Clarithromycin 500 mg BD\n+ Amoxicillin 1 g BD"), makeCell("14 days"), makeCell("Preferred where clarithromycin resistance < 15%")]),
makeRow([makeCell("Triple Therapy (Penicillin Allergy)"), makeCell("PPI BD\n+ Clarithromycin 500 mg BD\n+ Metronidazole 400 mg BD"), makeCell("14 days"), makeCell("Use if penicillin allergy")]),
makeRow([makeCell("Bismuth Quadruple Therapy (2nd line / high resistance areas)"), makeCell("PPI BD\n+ Bismuth subcitrate 120 mg QDS\n+ Metronidazole 400 mg TDS\n+ Tetracycline 500 mg QDS"), makeCell("10–14 days"), makeCell("Use after failed 1st line or in high-resistance regions")]),
]),
emptyPara(),
heading3("Confirm Eradication"),
bullet("Urea breath test (UBT) or stool antigen test: perform ≥ 4 weeks after completing antibiotics"),
bullet("Patient must be off PPIs for ≥ 2 weeks before testing"),
bullet("If eradication fails: switch to 2nd-line regimen; consult gastroenterology"),
emptyPara(),
heading2("Patient Education"),
bullet("Avoid NSAIDs, aspirin (unless essential for cardiovascular reasons)"),
bullet("Avoid alcohol and smoking"),
bullet("Take full course of antibiotics even if symptoms resolve"),
new Paragraph({ children: [new PageBreak()] }),
];
// ─── Section 5 — Dyslipidaemia ────────────────────────────────────────────────
const lipids = [
sectionLabel("05 | DYSLIPIDAEMIA / HYPERLIPIDAEMIA"),
heading2("Risk Stratification (Before Treatment)"),
bullet("Calculate 10-year cardiovascular risk (QRISK3 or Framingham Score)"),
bullet("Very high risk: established CVD, DM with organ damage, LDL > 4.9 mmol/L (familial hypercholesterolaemia)"),
bullet("High risk: 10-year CV risk ≥ 10%"),
bullet("Moderate risk: 10-year CV risk 5–9%"),
emptyPara(),
heading2("LDL-C Targets"),
tableWithBorder([
makeRow([makeCell("Risk Category",{header:true}),makeCell("LDL-C Target",{header:true})],true),
makeRow([makeCell("Very High Risk"), makeCell("< 1.4 mmol/L (55 mg/dL) — or ≥ 50% reduction")]),
makeRow([makeCell("High Risk"), makeCell("< 1.8 mmol/L (70 mg/dL) — or ≥ 50% reduction")]),
makeRow([makeCell("Moderate Risk"), makeCell("< 2.6 mmol/L (100 mg/dL)")]),
makeRow([makeCell("Low Risk"), makeCell("< 3.0 mmol/L (116 mg/dL)")]),
]),
emptyPara(),
heading2("Treatment Protocol"),
heading3("First-Line: Statin Therapy"),
tableWithBorder([
makeRow([makeCell("Intensity",{header:true}),makeCell("Drug & Dose",{header:true}),makeCell("Expected LDL Reduction",{header:true})],true),
makeRow([makeCell("High-intensity"), makeCell("Atorvastatin 40–80 mg OD\nRosuvastatin 20–40 mg OD"), makeCell("≥ 50%")]),
makeRow([makeCell("Moderate-intensity"), makeCell("Atorvastatin 10–20 mg OD\nSimvastatin 20–40 mg OD\nPravastatin 40–80 mg OD"), makeCell("30–49%")]),
makeRow([makeCell("Low-intensity"), makeCell("Simvastatin 10 mg OD\nPravastatin 10–20 mg OD"), makeCell("< 30%")]),
]),
bodyText("Take statins in the evening (most synthesis occurs at night). Monitor LFTs at baseline; repeat only if symptomatic."),
emptyPara(),
heading3("Second-Line: Add-On or Alternative Agents"),
bullet("Ezetimibe 10 mg OD: add if LDL target not reached on max-tolerated statin; reduces LDL by ~18–20%"),
bullet("PCSK9 inhibitors (Evolocumab, Alirocumab): for very high CV risk or statin intolerance; specialist prescription"),
bullet("Fibrates (Fenofibrate 145 mg OD): for isolated severe hypertriglyceridaemia (> 5.6 mmol/L)"),
bullet("Omega-3 fatty acids (Icosapent ethyl 4 g/day): for hypertriglyceridaemia + established CVD"),
emptyPara(),
heading2("Monitoring"),
bullet("Fasting lipid profile 4–12 weeks after starting/changing therapy, then annually"),
bullet("CK if myalgia; stop statin if CK > 10× ULN"),
bullet("Reassess CV risk annually"),
new Paragraph({ children: [new PageBreak()] }),
];
// ─── Section 6 — URTI ────────────────────────────────────────────────────────
const urti = [
sectionLabel("06 | UPPER RESPIRATORY TRACT INFECTIONS (URTI)"),
heading2("Principle"),
bodyText("The majority of URTIs are viral in origin. Antibiotics are NOT indicated for viral URTI. Judicious antibiotic use is mandatory to limit antimicrobial resistance."),
emptyPara(),
tableWithBorder([
makeRow([makeCell("Condition",{header:true}),makeCell("Likely Cause",{header:true}),makeCell("Treatment",{header:true}),makeCell("When to Prescribe Antibiotics",{header:true})],true),
makeRow([makeCell("Common Cold"), makeCell("Rhinovirus, Coronavirus"), makeCell("Rest, fluids\nParacetamol 500–1000 mg QDS PRN\nDecongestant: Pseudoephedrine 60 mg TDS (≤ 5 days)\nNasal saline irrigation"), makeCell("Never (viral)")]),
makeRow([makeCell("Viral Pharyngitis"), makeCell("Adenovirus, EBV"), makeCell("Analgesics, throat lozenges\nSteroid gargle if severe"), makeCell("Never (viral)")]),
makeRow([makeCell("Streptococcal Pharyngitis\n(+ve rapid strep test or Centor score ≥ 3)"), makeCell("Group A Strep (GAS)"), makeCell("Amoxicillin 500 mg TDS × 10 days\nOR Phenoxymethylpenicillin 500 mg QDS × 10 days\nIF ALLERGY: Azithromycin 500 mg OD × 5 days"), makeCell("Always — prevents rheumatic fever")]),
makeRow([makeCell("Acute Sinusitis (< 10 days)"), makeCell("Viral (90%)"), makeCell("Saline irrigation, decongestants, analgesics\nIntranasal corticosteroid (Mometasone) for congestion"), makeCell("Only if > 10 days duration, bilateral/frontal pain, fever > 39°C")]),
makeRow([makeCell("Bacterial Sinusitis (> 10 days / worsening)"), makeCell("S. pneumoniae, H. influenzae"), makeCell("Amoxicillin-clavulanate 875/125 mg BD × 5–7 days\nIF ALLERGY: Doxycycline 100 mg BD × 5 days"), makeCell("Indicated")]),
makeRow([makeCell("Acute Bronchitis"), makeCell("Viral (> 90%)"), makeCell("Supportive; honey, lozenges\nParacetamol PRN\nBronchodilator if wheeze"), makeCell("Only if Pertussis suspected (Azithromycin 500 mg OD × 5 days)")]),
]),
emptyPara(),
heading2("Safety Netting"),
bullet("Return if: fever > 3 days, worsening symptoms, difficulty breathing, dysphagia"),
bullet("Refer to ED if: stridor, drooling, inability to swallow, neck stiffness, severe trismus"),
new Paragraph({ children: [new PageBreak()] }),
];
// ─── Section 7 — UTI ─────────────────────────────────────────────────────────
const uti = [
sectionLabel("07 | URINARY TRACT INFECTION (UNCOMPLICATED — ADULT WOMEN)"),
heading2("Definition"),
bodyText("Uncomplicated UTI: lower urinary tract symptoms (dysuria, frequency, urgency, suprapubic pain) with no fever, flank pain, or structural/functional urinary tract abnormality. MSU for culture & sensitivity if: pregnant, recurrent UTI, treatment failure, or male."),
heading2("Antibiotic Treatment"),
tableWithBorder([
makeRow([makeCell("Drug",{header:true}),makeCell("Dose & Duration",{header:true}),makeCell("Notes",{header:true})],true),
makeRow([makeCell("Nitrofurantoin MR (1st line)"), makeCell("100 mg BD × 5 days"), makeCell("Preferred in non-pregnant women; avoid if eGFR < 30")]),
makeRow([makeCell("Trimethoprim (1st line)"), makeCell("200 mg BD × 7 days"), makeCell("Avoid in 1st trimester pregnancy; check local resistance patterns")]),
makeRow([makeCell("Pivmecillinam"), makeCell("400 mg TDS × 3–7 days"), makeCell("Low resistance; good safety profile")]),
makeRow([makeCell("Fosfomycin"), makeCell("3 g SINGLE dose"), makeCell("Convenient; useful in resistant/ESBL strains")]),
makeRow([makeCell("Co-amoxiclav (if resistant)"), makeCell("625 mg TDS × 5–7 days"), makeCell("2nd line; guided by culture")]),
makeRow([makeCell("Ciprofloxacin (reserve)"), makeCell("250 mg BD × 3 days"), makeCell("Reserve for resistant/complicated cases only; avoid as 1st line")]),
]),
emptyPara(),
heading2("Recurrent UTI (≥ 2 episodes/6 months or ≥ 3/year)"),
bullet("Identify and address risk factors: poor hygiene, post-coital voiding, oestrogen deficiency"),
bullet("Post-coital prophylaxis: single dose Nitrofurantoin 50 mg or Trimethoprim 100 mg"),
bullet("Continuous low-dose prophylaxis: Nitrofurantoin 50 mg nocte × 6 months"),
bullet("Vaginal oestrogen cream in post-menopausal women (reduces recurrence by 50%)"),
emptyPara(),
heading2("Special Situations"),
bullet("UTI in pregnancy: always treat; consult local guidelines for safe antibiotic choice"),
bullet("Pyelonephritis: requires hospital admission if systemically unwell; IV antibiotics + urine C&S"),
bullet("UTI in men: always investigate for complicated cause; treat for minimum 7 days"),
new Paragraph({ children: [new PageBreak()] }),
];
// ─── Section 8 — Asthma ──────────────────────────────────────────────────────
const asthma = [
sectionLabel("08 | ASTHMA (STABLE OUTPATIENT MANAGEMENT)"),
heading2("Diagnosis"),
bullet("Episodic wheeze, breathlessness, chest tightness, cough (worse at night/early morning)"),
bullet("Confirm with spirometry: FEV1/FVC < 0.7 with post-bronchodilator reversibility ≥ 12% and 200 mL"),
bullet("Peak flow variability > 20% supports diagnosis"),
emptyPara(),
heading2("GINA Stepwise Treatment Protocol"),
tableWithBorder([
makeRow([makeCell("Step",{header:true}),makeCell("Severity",{header:true}),makeCell("Preferred Controller",{header:true}),makeCell("Reliever",{header:true})],true),
makeRow([makeCell("1"), makeCell("Mild intermittent"), makeCell("As-needed low-dose ICS-formoterol\nOR no daily controller"), makeCell("SABA (Salbutamol 100–200 mcg) PRN\nOR ICS-formoterol PRN")]),
makeRow([makeCell("2"), makeCell("Mild persistent"), makeCell("Low-dose ICS daily\n(e.g. Budesonide 200 mcg BD, Beclomethasone 100 mcg BD)"), makeCell("SABA PRN")]),
makeRow([makeCell("3"), makeCell("Moderate persistent"), makeCell("Low-dose ICS + LABA\n(e.g. Budesonide/Formoterol 200/6 mcg BD)"), makeCell("SABA PRN")]),
makeRow([makeCell("4"), makeCell("Severe persistent"), makeCell("Medium/high-dose ICS + LABA\n(e.g. Fluticasone/Salmeterol 500/50 mcg BD)"), makeCell("SABA PRN")]),
makeRow([makeCell("5"), makeCell("Refractory"), makeCell("Step 4 + tiotropium (Spiriva Respimat 2.5 mcg OD)\nAND/OR biologics: Omalizumab, Mepolizumab (specialist)"), makeCell("SABA PRN")]),
]),
bodyText("Leukotriene receptor antagonist (Montelukast 10 mg OD) can be added at any step as an alternative or add-on controller, particularly for allergic rhinitis co-morbidity."),
emptyPara(),
heading2("Inhaler Technique & Adherence"),
bullet("Check and teach inhaler technique at every visit"),
bullet("Spacer device recommended for MDI at all ages"),
bullet("Provide written Personalised Asthma Action Plan (PAAP)"),
emptyPara(),
heading2("Step Down (if well controlled ≥ 3 months)"),
bullet("Attempt step-down every 3 months to find lowest effective dose"),
bullet("Do not step down during winter/high allergen season"),
heading2("Refer to Specialist if"),
bullet("Diagnosis uncertain; FEV1 < 60% predicted despite treatment"),
bullet("Step 4–5 required; frequent exacerbations (≥ 2/year requiring oral steroids)"),
new Paragraph({ children: [new PageBreak()] }),
];
// ─── Section 9 — Hypothyroidism ──────────────────────────────────────────────
const thyroid = [
sectionLabel("09 | HYPOTHYROIDISM"),
heading2("Diagnosis"),
tableWithBorder([
makeRow([makeCell("Type",{header:true}),makeCell("TSH",{header:true}),makeCell("Free T4",{header:true}),makeCell("Action",{header:true})],true),
makeRow([makeCell("Overt Hypothyroidism"), makeCell("↑ Elevated"), makeCell("↓ Low"), makeCell("Treat with Levothyroxine")]),
makeRow([makeCell("Subclinical Hypothyroidism"), makeCell("↑ Elevated (4–10)"), makeCell("Normal"), makeCell("Treat if TSH > 10, or symptomatic, or pregnant")]),
makeRow([makeCell("Euthyroid"), makeCell("0.4–4.0 mIU/L"), makeCell("Normal"), makeCell("No treatment")]),
]),
emptyPara(),
heading2("Treatment: Levothyroxine (T4)"),
bullet("Full replacement dose: 1.6 mcg/kg/day (ideal body weight)"),
bullet("Starting dose for elderly or cardiac disease: 25 mcg OD; increase by 12.5–25 mcg every 6–8 weeks"),
bullet("Starting dose for healthy adults < 60 years: 50–75 mcg OD"),
bullet("Take on empty stomach, 30–60 min before breakfast, or at least 4 hours after calcium, iron, or PPIs"),
emptyPara(),
heading2("Monitoring"),
bullet("TSH: check 6–8 weeks after each dose change; aim for TSH 0.4–2.5 mIU/L (tighter in pregnancy)"),
bullet("Once stable: TSH annually"),
bullet("Adjust dose in pregnancy (TSH target < 2.5 mIU/L in 1st trimester)"),
emptyPara(),
heading2("Drug Interactions Reducing Absorption"),
bullet("Calcium carbonate, iron supplements, cholestyramine, antacids, PPIs"),
bullet("Space these ≥ 4 hours from Levothyroxine"),
new Paragraph({ children: [new PageBreak()] }),
];
// ─── Section 10 — Osteoarthritis ─────────────────────────────────────────────
const oa = [
sectionLabel("10 | OSTEOARTHRITIS (OA)"),
heading2("Core Treatment (All Patients — Non-Pharmacological First)"),
bullet("Patient education: nature of OA, self-management"),
bullet("Weight reduction: every 1 kg weight loss reduces knee load by 4 kg"),
bullet("Physiotherapy: quadriceps strengthening (knee OA), hip abductor strengthening (hip OA)"),
bullet("Aerobic exercise: swimming, cycling, walking — 150 min/week"),
bullet("Assistive devices: cane (contralateral hand), knee brace, orthotics"),
emptyPara(),
heading2("Pharmacological Treatment (Stepwise)"),
tableWithBorder([
makeRow([makeCell("Tier",{header:true}),makeCell("Treatment",{header:true}),makeCell("Notes",{header:true})],true),
makeRow([makeCell("1st Line"), makeCell("Topical Diclofenac gel 1% applied TDS–QDS"), makeCell("Preferred in elderly; minimal systemic absorption; fewer GI/renal effects")]),
makeRow([makeCell("2nd Line"), makeCell("Paracetamol 500–1000 mg QDS (max 4 g/day)\nOral NSAIDs: Ibuprofen 400–600 mg TDS OR Naproxen 250–500 mg BD"), makeCell("Add PPI if GI risk; use lowest effective dose for shortest duration\nAvoid in CKD, heart failure")]),
makeRow([makeCell("COX-2 Inhibitor"), makeCell("Celecoxib 100–200 mg BD"), makeCell("Fewer GI side effects than non-selective NSAIDs; avoid in cardiovascular disease")]),
makeRow([makeCell("Adjunct"), makeCell("Duloxetine 30–60 mg OD (centrally acting)"), makeCell("Useful for neuropathic component or poor NSAID response; evidence for knee OA")]),
makeRow([makeCell("Intra-articular"), makeCell("Methylprednisolone 40 mg injection"), makeCell("Short-term pain relief (weeks); max 3–4 injections/year per joint; aseptic technique essential")]),
]),
emptyPara(),
heading2("Surgical Referral"),
bullet("Consider when: moderate-severe pain unresponsive to ≥ 3 months of conservative + pharmacological therapy"),
bullet("Total knee / hip replacement: most cost-effective intervention for advanced OA"),
bullet("Pre-referral: X-ray to confirm severity; ensure BMI optimisation if possible"),
new Paragraph({ children: [new PageBreak()] }),
];
// ─── Section 11 — Iron Deficiency Anaemia ────────────────────────────────────
const anaemia = [
sectionLabel("11 | IRON DEFICIENCY ANAEMIA (IDA)"),
heading2("Diagnosis"),
bullet("Blood count: low Hb, low MCV (microcytic), low MCH"),
bullet("Iron studies: low serum ferritin (< 12 µg/L diagnostic; < 30 µg/L with inflammation), low serum iron, high TIBC, low transferrin saturation < 20%"),
bullet("Always identify and address the CAUSE"),
emptyPara(),
heading2("Common Causes"),
bullet("Women of reproductive age: menorrhagia, pregnancy"),
bullet("GI causes: peptic ulcer, colorectal cancer, coeliac disease, gastritis"),
bullet("Dietary deficiency: vegetarian/vegan diet, malnutrition"),
emptyPara(),
heading2("Treatment"),
heading3("Oral Iron (Preferred Route)"),
bullet("Ferrous sulphate 325 mg (65 mg elemental iron) OD–TDS"),
bullet("Take on empty stomach for best absorption; with Vitamin C (ascorbic acid 200 mg) to improve absorption"),
bullet("If GI intolerance (nausea, constipation): switch to Ferrous gluconate 300 mg or Ferrous fumarate 210 mg"),
bullet("Duration: continue for 3–6 months after Hb normalises to replenish stores"),
bullet("Check Hb in 4 weeks: expect rise of ≥ 10 g/L; if not, investigate compliance/absorption"),
emptyPara(),
heading3("Parenteral Iron (IV — specific indications)"),
bullet("Oral iron not tolerated / contraindicated"),
bullet("Malabsorption (coeliac disease, post-bariatric surgery, inflammatory bowel disease)"),
bullet("Severe anaemia requiring rapid correction"),
bullet("Ongoing blood loss exceeding oral replacement capacity"),
bodyText("IV Iron options: Ferric carboxymaltose (Ferinject) — single large dose; Iron sucrose — multiple smaller doses. Monitor for hypersensitivity during infusion."),
emptyPara(),
heading2("Monitoring"),
bullet("Hb & reticulocyte count: 4 weeks after starting treatment"),
bullet("Ferritin: after completing full course (confirms stores replenished)"),
bullet("Investigate GI source in: all men, post-menopausal women, and any age with GI symptoms"),
new Paragraph({ children: [new PageBreak()] }),
];
// ─── Section 12 — Emergency Back-Up ──────────────────────────────────────────
const emergency = [
sectionLabel("12 | WHEN TO REFER / ESCALATE"),
heading2("Emergency (Call Ambulance / Transfer to ED)"),
bullet("SBP ≥ 180 mmHg with symptoms (headache, confusion, chest pain, neuro signs) — Hypertensive Emergency"),
bullet("Severe bronchospasm unresponsive to initial SABA — Status Asthmaticus"),
bullet("Anaphylaxis, stridor, acute airway compromise"),
bullet("Blood glucose > 20 mmol/L with ketones / DKA symptoms"),
bullet("Active upper or lower GI bleeding"),
emptyPara(),
heading2("Urgent Specialist Referral (within 2 weeks)"),
bullet("New diagnosis of cancer on investigation"),
bullet("Persistent haematuria after UTI treatment"),
bullet("Unexplained weight loss > 5% in 3 months"),
bullet("Uncontrolled HTN (BP > 180/120) despite 3 drugs at maximum doses"),
emptyPara(),
heading2("Routine Specialist Referral"),
bullet("Diabetic foot complications, chronic non-healing wounds"),
bullet("Asthma Step 4–5 requiring specialist biologics"),
bullet("GERD refractory to PPI — gastroenterology + endoscopy"),
bullet("Hypothyroidism not responding to Levothyroxine — endocrinology"),
bullet("OA failing conservative management — orthopaedic surgery"),
new Paragraph({ children: [new PageBreak()] }),
];
// ─── References ───────────────────────────────────────────────────────────────
const references = [
heading1("References & Evidence Base"),
bullet("Goldman-Cecil Medicine International Edition, 2-Volume Set (2023)"),
bullet("Harrison's Principles of Internal Medicine, 22nd Edition (2025, McGraw Hill)"),
bullet("Symptom to Diagnosis: An Evidence-Based Guide, 4th Edition"),
bullet("Tintinalli's Emergency Medicine: A Comprehensive Study"),
bullet("Katzung's Basic and Clinical Pharmacology, 16th Edition"),
bullet("Fuster and Hurst's The Heart, 15th Edition"),
bullet("2017 ACC/AHA Hypertension Guidelines"),
bullet("ADA Standards of Medical Care in Diabetes (2024)"),
bullet("GINA Global Initiative for Asthma Report (2024)"),
bullet("ESC/EAS Guidelines on Dyslipidaemias (2019/2024 update)"),
bullet("WHO Guidelines for Treatment of Tuberculosis, UTI, URTI"),
bullet("NICE Clinical Guidelines (CG136 Hypertension, NG28 T2DM, CG184 OA, CG64 GERD)"),
];
// ─── Document Assembly ────────────────────────────────────────────────────────
const doc = new Document({
creator: "Clinic Protocol Generator",
title: "Clinic Treatment Protocol",
description: "Standard OPD Treatment Protocols — General Medicine Adult",
styles: {
default: {
document: {
run: { font: "Calibri", size: 22 }
}
}
},
sections: [
{
headers: {
default: new Header({
children: [
new Paragraph({
alignment: AlignmentType.RIGHT,
shading: { type: ShadingType.SOLID, color: LIGHT_BLUE, fill: LIGHT_BLUE },
children: [
new TextRun({ text: "CLINIC TREATMENT PROTOCOL | General Medicine OPD | v1.0 — July 2026", size: 18, color: "444444", font: "Calibri" })
]
})
]
})
},
footers: {
default: new Footer({
children: [
new Paragraph({
alignment: AlignmentType.CENTER,
children: [
new TextRun({ text: "Page ", size: 18, color: "888888", font: "Calibri" }),
new TextRun({ children: [PageNumber.CURRENT], size: 18, color: "888888", font: "Calibri" }),
new TextRun({ text: " of ", size: 18, color: "888888", font: "Calibri" }),
new TextRun({ children: [PageNumber.TOTAL_PAGES], size: 18, color: "888888", font: "Calibri" }),
new TextRun({ text: " | For internal clinic use only. Review: July 2028.", size: 18, color: "AAAAAA", font: "Calibri" }),
]
})
]
})
},
children: [
...coverPage,
...preamble,
...hypertension,
...diabetes,
...gerd,
...pud,
...lipids,
...urti,
...uti,
...asthma,
...thyroid,
...oa,
...anaemia,
...emergency,
...references,
]
}
]
});
Packer.toBuffer(doc).then(buffer => {
fs.writeFileSync("/home/daytona/workspace/clinic-protocol/Clinic_Treatment_Protocol.docx", buffer);
console.log("SUCCESS: Document written.");
}).catch(err => {
console.error("ERROR:", err);
process.exit(1);
});