SOP for massive blood transfusion protocol for NABH inspection

Reading File
Finding Sources
Finding Sources
Searching the Web

NABH standard SOP massive blood transfusion protocol India hospital accreditation 2024

Reading File
Reading File
Reading File
Searching the Web

NABH blood bank standards transfusion service requirements COP standard 2024

Reading File
Reading File
Loading Image
Reading Web Page

https://portal.nabh.co/Announcement/Draft%20NABH%20Accredita…

Reading File
Running Command

ls -la /home/daytona/workspace/ && ls /home/daytona/skills/docx/

Running Command

mkdir -p /home/daytona/workspace/mtp-sop && ls /home/daytona/skills/docx/scripts/

Writing File

~/mtp-sop/generate_mtp_sop.js

const {
  Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell,
  HeadingLevel, AlignmentType, BorderStyle, WidthType, VerticalAlign,
  ShadingType, PageNumber, Header, Footer, PageBreak, NumberFormat,
  convertInchesToTwip
} = require('docx');
const fs = require('fs');

// ── helpers ──────────────────────────────────────────────────────────────────
const FONT = "Times New Roman";
const MONO = "Courier New";

const bold = (text, size = 22) => new TextRun({ text, bold: true, size, font: FONT });
const normal = (text, size = 22) => new TextRun({ text, size, font: FONT });
const italicRun = (text, size = 22) => new TextRun({ text, italics: true, size, font: FONT });

function heading1(text) {
  return new Paragraph({
    heading: HeadingLevel.HEADING_1,
    spacing: { before: 280, after: 140 },
    children: [new TextRun({ text, bold: true, size: 28, color: "1F3864", font: FONT, allCaps: true })]
  });
}

function heading2(text) {
  return new Paragraph({
    heading: HeadingLevel.HEADING_2,
    spacing: { before: 200, after: 100 },
    children: [new TextRun({ text, bold: true, size: 24, color: "2E4057", font: FONT })]
  });
}

function para(runs, spacing = { before: 100, after: 80 }, alignment = AlignmentType.JUSTIFIED) {
  return new Paragraph({ children: Array.isArray(runs) ? runs : [normal(runs)], spacing, alignment });
}

function bullet(text, level = 0) {
  return new Paragraph({
    bullet: { level },
    children: [normal(text)],
    spacing: { before: 60, after: 60 },
    indent: { left: convertInchesToTwip(0.25 + level * 0.25) }
  });
}

function numberedItem(text, bold_prefix = null) {
  const children = bold_prefix
    ? [bold(bold_prefix), normal(text)]
    : [normal(text)];
  return new Paragraph({
    numbering: { reference: "my-numbering", level: 0 },
    children,
    spacing: { before: 60, after: 60 }
  });
}

function shadedCell(text, bgColor = "1F3864", textColor = "FFFFFF", bold_flag = true, width = null) {
  const opts = {
    shading: { fill: bgColor, type: ShadingType.CLEAR, color: "auto" },
    verticalAlign: VerticalAlign.CENTER,
    margins: { top: 80, bottom: 80, left: 100, right: 100 }
  };
  if (width) opts.width = { size: width, type: WidthType.DXA };
  return new TableCell({
    ...opts,
    children: [new Paragraph({ alignment: AlignmentType.CENTER, children: [new TextRun({ text, bold: bold_flag, color: textColor, size: 20, font: FONT })] })]
  });
}

function plainCell(text, bgColor = null, bold_flag = false, alignment = AlignmentType.LEFT, width = null) {
  const opts = {
    verticalAlign: VerticalAlign.CENTER,
    margins: { top: 80, bottom: 80, left: 100, right: 100 }
  };
  if (bgColor) opts.shading = { fill: bgColor, type: ShadingType.CLEAR, color: "auto" };
  if (width) opts.width = { size: width, type: WidthType.DXA };
  return new TableCell({
    ...opts,
    children: [new Paragraph({ alignment, children: [new TextRun({ text, bold: bold_flag, size: 20, font: FONT })] })]
  });
}

function hdrRow(cells) { return new TableRow({ tableHeader: true, children: cells }); }
function dataRow(cells) { return new TableRow({ children: cells }); }

function sectionDivider() {
  return new Paragraph({
    spacing: { before: 160, after: 160 },
    border: { bottom: { color: "1F3864", size: 6, style: BorderStyle.SINGLE } },
    children: []
  });
}

// ── title / header block ─────────────────────────────────────────────────────
function titleBlock() {
  return [
    new Table({
      width: { size: 100, type: WidthType.PERCENTAGE },
      rows: [
        dataRow([
          new TableCell({
            columnSpan: 4,
            shading: { fill: "1F3864", type: ShadingType.CLEAR, color: "auto" },
            margins: { top: 120, bottom: 120, left: 200, right: 200 },
            children: [
              new Paragraph({ alignment: AlignmentType.CENTER, children: [new TextRun({ text: "STANDARD OPERATING PROCEDURE", bold: true, color: "FFFFFF", size: 32, font: FONT })] }),
              new Paragraph({ alignment: AlignmentType.CENTER, children: [new TextRun({ text: "MASSIVE BLOOD TRANSFUSION PROTOCOL (MTP)", bold: true, color: "FFD700", size: 28, font: FONT })] })
            ]
          })
        ]),
        dataRow([
          plainCell("Document No.", "D6E4F0", true, AlignmentType.CENTER, 2000),
          plainCell("[HOSPITAL CODE]/BB/SOP/001", null, false, AlignmentType.CENTER, 3000),
          plainCell("Version:", "D6E4F0", true, AlignmentType.CENTER, 1200),
          plainCell("1.0", null, false, AlignmentType.CENTER, 1800)
        ]),
        dataRow([
          plainCell("NABH Std. Ref.", "D6E4F0", true, AlignmentType.CENTER, 2000),
          plainCell("COP.8 | TPC.15 – TPC.20 | BSQ.11", null, false, AlignmentType.CENTER, 3000),
          plainCell("Effective Date:", "D6E4F0", true, AlignmentType.CENTER, 1200),
          plainCell("[DD/MM/YYYY]", null, false, AlignmentType.CENTER, 1800)
        ]),
        dataRow([
          plainCell("Prepared by:", "D6E4F0", true, AlignmentType.CENTER, 2000),
          plainCell("Transfusion Officer / Blood Bank In-charge", null, false, AlignmentType.CENTER, 3000),
          plainCell("Review Date:", "D6E4F0", true, AlignmentType.CENTER, 1200),
          plainCell("[DD/MM/YYYY]", null, false, AlignmentType.CENTER, 1800)
        ]),
        dataRow([
          plainCell("Approved by:", "D6E4F0", true, AlignmentType.CENTER, 2000),
          plainCell("Medical Superintendent / CMO", null, false, AlignmentType.CENTER, 3000),
          plainCell("Pages:", "D6E4F0", true, AlignmentType.CENTER, 1200),
          plainCell("All", null, false, AlignmentType.CENTER, 1800)
        ]),
        dataRow([
          plainCell("Department:", "D6E4F0", true, AlignmentType.CENTER, 2000),
          plainCell("Blood Bank / Transfusion Medicine", null, false, AlignmentType.CENTER, 3000),
          plainCell("Status:", "D6E4F0", true, AlignmentType.CENTER, 1200),
          plainCell("Controlled Document", null, false, AlignmentType.CENTER, 1800)
        ])
      ]
    }),
    new Paragraph({ spacing: { before: 160, after: 80 }, children: [] })
  ];
}

// ── Amendment history table ──────────────────────────────────────────────────
function amendmentTable() {
  return [
    heading1("1. Amendment History"),
    new Table({
      width: { size: 100, type: WidthType.PERCENTAGE },
      rows: [
        hdrRow([
          shadedCell("Version"),
          shadedCell("Date"),
          shadedCell("Section(s) Amended"),
          shadedCell("Reason for Change"),
          shadedCell("Approved by")
        ]),
        dataRow([
          plainCell("1.0"),
          plainCell("[Date]"),
          plainCell("All – First Issue"),
          plainCell("New SOP"),
          plainCell("[Name/Designation]")
        ])
      ]
    }),
    new Paragraph({ spacing: { before: 120, after: 80 }, children: [] })
  ];
}

// ── Signature block ──────────────────────────────────────────────────────────
function signatureTable() {
  return [
    heading1("2. Signature & Authorization"),
    new Table({
      width: { size: 100, type: WidthType.PERCENTAGE },
      rows: [
        hdrRow([
          shadedCell("Role"),
          shadedCell("Name"),
          shadedCell("Designation"),
          shadedCell("Signature"),
          shadedCell("Date")
        ]),
        dataRow([
          plainCell("Prepared by", "EBF5FB"),
          plainCell(""),
          plainCell("Blood Bank In-charge / Transfusion Officer"),
          plainCell(""),
          plainCell("")
        ]),
        dataRow([
          plainCell("Reviewed by", "EBF5FB"),
          plainCell(""),
          plainCell("Quality Manager / HOD – Pathology"),
          plainCell(""),
          plainCell("")
        ]),
        dataRow([
          plainCell("Approved by", "EBF5FB"),
          plainCell(""),
          plainCell("Medical Superintendent / CMO"),
          plainCell(""),
          plainCell("")
        ])
      ]
    }),
    new Paragraph({ spacing: { before: 120, after: 80 }, children: [] })
  ];
}

// ── Main content sections ─────────────────────────────────────────────────────
function mainContent() {
  const items = [];

  // 3 PURPOSE
  items.push(heading1("3. Purpose"));
  items.push(para([
    normal("This Standard Operating Procedure (SOP) establishes a standardised, institution-specific protocol for the rapid identification, activation, and execution of Massive Blood Transfusion (MBT) in patients with life-threatening haemorrhage. The aim is to deliver blood and blood components safely, promptly, and in physiologically appropriate ratios while preventing the lethal triad of hypothermia, acidosis, and coagulopathy. This SOP fulfils the requirements of NABH standards "),
    bold("COP.8, TPC.15–TPC.20,"),
    normal(" and "),
    bold("BSQ.11"),
    normal(" and aligns with the NABH Accreditation Standards for Blood Centres and Transfusion Services (4th Edition, 2024).")
  ]));

  // 4 SCOPE
  items.push(heading1("4. Scope"));
  items.push(para("This SOP applies to:"));
  items.push(bullet("All clinical areas including Emergency Department, Operation Theatre, ICU, Labour & Delivery, and all inpatient wards."));
  items.push(bullet("Blood Bank / Transfusion Medicine Department."));
  items.push(bullet("All authorised clinical staff (physicians, surgeons, anaesthesiologists, obstetricians, nurses, and paramedics) involved in blood product ordering or administration."));
  items.push(bullet("Blood Bank technicians and officers responsible for component preparation and issue."));

  // 5 DEFINITIONS
  items.push(heading1("5. Definitions"));
  const defTable = new Table({
    width: { size: 100, type: WidthType.PERCENTAGE },
    rows: [
      hdrRow([shadedCell("Term", "1F3864", "FFFFFF", true, 2800), shadedCell("Definition", "1F3864", "FFFFFF", true)]),
      dataRow([plainCell("Massive Transfusion (MT)", "EBF5FB", true), plainCell("Transfusion of ≥ 10 units of packed red blood cells (PRBC) within 24 hours; OR replacement of the patient's entire blood volume within 24 hours; OR transfusion of ≥ 4 units of any blood component within 1 hour with ongoing haemorrhage.")]),
      dataRow([plainCell("Massive Transfusion Protocol (MTP)", "EBF5FB", true), plainCell("A pre-planned, standardised institutional protocol that triggers the release of blood components in predetermined ratios when massive haemorrhage is anticipated or confirmed.")]),
      dataRow([plainCell("ABC Score", "EBF5FB", true), plainCell("Assessment of Blood Consumption score — a validated bedside tool to predict need for MTP. Score ≥ 2 triggers MTP activation.")]),
      dataRow([plainCell("PRBC", "EBF5FB", true), plainCell("Packed Red Blood Cells.")]),
      dataRow([plainCell("FFP", "EBF5FB", true), plainCell("Fresh Frozen Plasma.")]),
      dataRow([plainCell("SDP / RDP", "EBF5FB", true), plainCell("Single Donor Platelets / Random Donor Platelets.")]),
      dataRow([plainCell("Cryo", "EBF5FB", true), plainCell("Cryoprecipitate — rich in fibrinogen, Factor VIII, vWF, Factor XIII.")]),
      dataRow([plainCell("TXA", "EBF5FB", true), plainCell("Tranexamic Acid — an antifibrinolytic agent.")]),
      dataRow([plainCell("TEG / ROTEM", "EBF5FB", true), plainCell("Thromboelastography / Rotational Thromboelastometry — point-of-care viscoelastic tests to guide goal-directed transfusion.")]),
      dataRow([plainCell("Lethal Triad", "EBF5FB", true), plainCell("The combination of hypothermia (<35 °C), acidosis (pH < 7.35), and coagulopathy — each potentiates the others in massive haemorrhage.")]),
      dataRow([plainCell("O-negative Blood", "EBF5FB", true), plainCell("Universal donor red cells; used when patient's blood group is unknown. Rh(D)-negative preferred for females of childbearing potential.")])
    ]
  });
  items.push(defTable);
  items.push(new Paragraph({ spacing: { before: 120, after: 80 }, children: [] }));

  // 6 RESPONSIBILITIES
  items.push(heading1("6. Responsibilities"));
  const respTable = new Table({
    width: { size: 100, type: WidthType.PERCENTAGE },
    rows: [
      hdrRow([shadedCell("Designation", "1F3864", "FFFFFF", true, 3000), shadedCell("Responsibility", "1F3864", "FFFFFF", true)]),
      dataRow([plainCell("Medical Superintendent / CMO", null, true), plainCell("Overall approval and periodic review of SOP; chairs Hospital Transfusion Committee.")]),
      dataRow([plainCell("HOD – Blood Bank / Transfusion Medicine", null, true), plainCell("Ensures 24/7 readiness of blood products; trains blood bank staff; maintains MTP kits.")]),
      dataRow([plainCell("Blood Bank Technician (On duty)", null, true), plainCell("Issues pre-packed MTP bundles on activation; performs emergency cross-match; communicates with clinical team.")]),
      dataRow([plainCell("Treating Physician / Surgeon / Anaesthesiologist", null, true), plainCell("Activates MTP; prescribes components; monitors patient response; deactivates MTP when appropriate.")]),
      dataRow([plainCell("Nursing In-charge (Clinical Area)", null, true), plainCell("Confirms dual-identity check before administration; monitors patient during transfusion; documents all units administered; reports adverse reactions.")]),
      dataRow([plainCell("Quality Manager", null, true), plainCell("Reviews MTP audit data; presents indicators to Hospital Transfusion Committee; initiates corrective actions.")]),
    ]
  });
  items.push(respTable);
  items.push(new Paragraph({ spacing: { before: 120, after: 80 }, children: [] }));

  // 7 ACTIVATION CRITERIA
  items.push(heading1("7. MTP Activation Criteria"));
  items.push(heading2("7.1  Clinical Triggers (any ONE of the following)"));
  const trigTable = new Table({
    width: { size: 100, type: WidthType.PERCENTAGE },
    rows: [
      hdrRow([shadedCell("Criterion", "C0392B", "FFFFFF", true, 3000), shadedCell("Details", "C0392B", "FFFFFF", true)]),
      dataRow([plainCell("≥ 10 units PRBC in 24 h", null, true), plainCell("Traditional definition of massive transfusion.")]),
      dataRow([plainCell("≥ 4 units PRBC in 1 hour with ongoing haemorrhage", null, true), plainCell("More practical trigger for early activation.")]),
      dataRow([plainCell("ABC Score ≥ 2", null, true), plainCell("Penetrating mechanism + SBP < 90 mmHg + HR > 120 bpm + positive FAST — any 2 of 4 criteria (sensitivity 76–90%, specificity 67–87%).")]),
      dataRow([plainCell("Clinical judgement", null, true), plainCell("Physician anticipates life-threatening haemorrhage: ruptured AAA, major hepatic trauma, PPH, exsanguinating pelvic fracture, etc.")])
    ]
  });
  items.push(trigTable);
  items.push(new Paragraph({ spacing: { before: 100, after: 60 }, children: [] }));

  items.push(heading2("7.2  Haemorrhage Class for Context"));
  const classTable = new Table({
    width: { size: 100, type: WidthType.PERCENTAGE },
    rows: [
      hdrRow([shadedCell("Class"), shadedCell("Blood Loss (mL)"), shadedCell("% EBV"), shadedCell("HR (bpm)"), shadedCell("SBP"), shadedCell("Action")]),
      dataRow([plainCell("I"), plainCell("< 750"), plainCell("< 15%"), plainCell("< 100"), plainCell("Normal"), plainCell("Crystalloid only")]),
      dataRow([plainCell("II"), plainCell("750–1500"), plainCell("15–30%"), plainCell("100–120"), plainCell("Normal"), plainCell("Crystalloid / Colloid")]),
      dataRow([plainCell("III", "FDECEA"), plainCell("1500–2000", "FDECEA"), plainCell("30–40%", "FDECEA"), plainCell("120–140", "FDECEA"), plainCell("Decreased", "FDECEA"), plainCell("Blood + Crystalloid", "FDECEA")]),
      dataRow([plainCell("IV", "F1948A"), plainCell("> 2000", "F1948A"), plainCell("> 40%", "F1948A"), plainCell("> 140", "F1948A"), plainCell("Very Low", "F1948A"), plainCell("ACTIVATE MTP", "F1948A")])
    ]
  });
  items.push(classTable);
  items.push(new Paragraph({ spacing: { before: 120, after: 80 }, children: [] }));

  // 8 PROCEDURE
  items.push(heading1("8. Procedure"));

  items.push(heading2("8.1  MTP Activation (STEP 1)"));
  items.push(bullet("Any authorised physician / surgeon / anaesthesiologist can activate MTP."));
  items.push(bullet("Call Blood Bank directly: [BLOOD BANK EMERGENCY EXT: ______]. State clearly: \"MTP ACTIVATION for [Patient Name], [Ward/OT/ED], [Blood Group if known].\""));
  items.push(bullet("Simultaneously notify the Nursing In-charge and On-call Anaesthesiologist."));
  items.push(bullet("Send blood sample (EDTA tube + clot tube) to Blood Bank IMMEDIATELY for: ABO/Rh grouping, crossmatch, CBC, PT, APTT, fibrinogen, ionised calcium, blood glucose, LFT, RFT."));
  items.push(bullet("Document time of MTP activation in the patient's medical record."));

  items.push(heading2("8.2  Blood Bank Response (STEP 2)"));
  items.push(bullet("Blood Bank technician receives call and starts MTP clock."));
  items.push(bullet("Issue MTP Pack 1 STAT (see Section 8.3). Target release time: ≤ 10 minutes from activation."));
  items.push(bullet("If patient's group is unknown: issue 2 units O-negative PRBC immediately (do NOT wait for crossmatch)."));
  items.push(bullet("Automatically prepare MTP Pack 2 upon issue of Pack 1 — continue preparing successive packs until MTP is deactivated."));
  items.push(bullet("Notify Blood Bank Officer / Pathologist on-call."));

  items.push(heading2("8.3  MTP Packs — Component Composition"));
  items.push(para([normal("The following standard MTP packs ensure a "), bold("1 : 1 : 1 ratio (PRBC : FFP : Platelets)"), normal(" — evidence supports this approach for reducing 24-hour exsanguination mortality (PROPPR Trial).")], { before: 100, after: 80 }));

  const packTable = new Table({
    width: { size: 100, type: WidthType.PERCENTAGE },
    rows: [
      hdrRow([
        shadedCell("Pack No.", "1F3864", "FFFFFF", true, 1200),
        shadedCell("PRBC (units)", "1F3864", "FFFFFF", true),
        shadedCell("FFP (units)", "1F3864", "FFFFFF", true),
        shadedCell("SDP / Platelets", "1F3864", "FFFFFF", true),
        shadedCell("Cryoprecipitate", "1F3864", "FFFFFF", true),
        shadedCell("Notes", "1F3864", "FFFFFF", true)
      ]),
      dataRow([
        plainCell("Pack 1", "EBF5FB", true),
        plainCell("4 units", null),
        plainCell("4 units (thaw on activation)", null),
        plainCell("—", null),
        plainCell("—", null),
        plainCell("Issue immediately; empirical before lab results")
      ]),
      dataRow([
        plainCell("Pack 2", "EBF5FB", true),
        plainCell("4 units", null),
        plainCell("4 units", null),
        plainCell("1 SDP (or 6 RDP)", null),
        plainCell("10 units", null),
        plainCell("Issue after Pack 1 administered")
      ]),
      dataRow([
        plainCell("Pack 3+", "EBF5FB", true),
        plainCell("4 units", null),
        plainCell("4 units", null),
        plainCell("1 SDP (or 6 RDP)", null),
        plainCell("As per labs", null),
        plainCell("Continue until MTP deactivated; guided by TEG/labs from Pack 2 onwards")
      ])
    ]
  });
  items.push(packTable);
  items.push(new Paragraph({ spacing: { before: 80, after: 60 }, children: [] }));
  items.push(para([
    bold("Note: "),
    normal("FFP requires "),
    bold("30 minutes to thaw"),
    normal(". Pre-thaw FFP (Group AB or group-specific) must be prepared immediately on MTP activation. If thawed FFP not immediately available, use crystalloid as bridge ONLY — do NOT delay PRBC.")
  ]));

  items.push(heading2("8.4  Adjunct Therapies"));
  const adjTable = new Table({
    width: { size: 100, type: WidthType.PERCENTAGE },
    rows: [
      hdrRow([shadedCell("Agent"), shadedCell("Dose"), shadedCell("Indication / Timing"), shadedCell("Notes")]),
      dataRow([plainCell("Tranexamic Acid (TXA)"), plainCell("1 g IV over 10 min; then 1 g IV over 8 h"), plainCell("Give within 3 hours of haemorrhage onset (CRASH-2 Trial)"), plainCell("Do NOT give > 3 h after injury — may increase thrombotic risk")]),
      dataRow([plainCell("Calcium Chloride (10%)"), plainCell("1 g (10 mL) IV per 4 units PRBC"), plainCell("Hypocalcaemia due to citrate in banked blood"), plainCell("Maintain ionised Ca²⁺ ≥ 0.9 mmol/L. Preferred over calcium gluconate in shocked patients")]),
      dataRow([plainCell("Fibrinogen Concentrate"), plainCell("3–4 g IV"), plainCell("Fibrinogen < 1.5 g/L"), plainCell("Alternative to cryoprecipitate; faster to administer")]),
      dataRow([plainCell("Prothrombin Complex Concentrate (PCC)"), plainCell("25–50 IU/kg IV"), plainCell("INR > 1.5, anticoagulated patient, factor deficiency"), plainCell("Only on haematologist / specialist advice")]),
      dataRow([plainCell("Vitamin K"), plainCell("10 mg IV slowly"), plainCell("Warfarin reversal"), plainCell("Takes 6–12 h for full effect; combine with FFP/PCC for urgent reversal")]),
      dataRow([plainCell("rFVIIa (recombinant Factor VIIa)"), plainCell("90–120 mcg/kg IV"), plainCell("Refractory coagulopathy after conventional MTP failure"), plainCell("Expensive; use only after surgical haemostasis attempted; haematologist guidance")]),
    ]
  });
  items.push(adjTable);
  items.push(new Paragraph({ spacing: { before: 80, after: 60 }, children: [] }));

  items.push(heading2("8.5  Monitoring & Laboratory Targets During MTP"));
  items.push(para("Repeat labs every 30–60 minutes or after every 4 units of PRBC:"));
  const labTable = new Table({
    width: { size: 100, type: WidthType.PERCENTAGE },
    rows: [
      hdrRow([shadedCell("Parameter"), shadedCell("Target"), shadedCell("Action if Below Target")]),
      dataRow([plainCell("Haemoglobin"), plainCell("≥ 7 g/dL (≥ 10 g/dL in ACS, elderly)"), plainCell("Transfuse PRBC")]),
      dataRow([plainCell("Platelet Count"), plainCell("≥ 50 × 10⁹/L (≥ 100 × 10⁹/L in CNS / eye injury)"), plainCell("Transfuse SDP / RDP")]),
      dataRow([plainCell("PT / INR"), plainCell("INR < 1.5"), plainCell("Transfuse FFP")]),
      dataRow([plainCell("APTT"), plainCell("< 45 sec (< 1.5× control)"), plainCell("Transfuse FFP")]),
      dataRow([plainCell("Fibrinogen"), plainCell("≥ 1.5 g/L"), plainCell("Cryoprecipitate (10 units) or Fibrinogen Concentrate (3–4 g)")]),
      dataRow([plainCell("Ionised Calcium"), plainCell("≥ 0.9 mmol/L"), plainCell("Calcium Chloride 1 g IV")]),
      dataRow([plainCell("Potassium"), plainCell("3.5–5.5 mEq/L"), plainCell("Correct with IV fluids / insulin-dextrose as appropriate")]),
      dataRow([plainCell("Temperature"), plainCell("≥ 35 °C"), plainCell("Blood warmer, warm blankets, warm IV fluids, warming mattress")]),
      dataRow([plainCell("pH"), plainCell("≥ 7.35"), plainCell("Optimise ventilation; correct underlying cause; sodium bicarbonate if refractory")]),
      dataRow([plainCell("MAP"), plainCell("≥ 60 mmHg (permissive hypotension SBP 80–90 in penetrating trauma until haemostasis)"), plainCell("Vasopressors only as bridge; target MAP ≥ 65 after haemostasis")]),
    ]
  });
  items.push(labTable);
  items.push(new Paragraph({ spacing: { before: 80, after: 60 }, children: [] }));

  items.push(heading2("8.6  Prevent the Lethal Triad"));
  items.push(bullet("Hypothermia prevention: Use blood warmers (target all blood products to 37 °C). Maintain ambient temperature. Cover patient with warm blankets. Warm all IV fluids."));
  items.push(bullet("Acidosis correction: Optimise oxygen delivery. Correct haemodynamics. Avoid excess crystalloid. Do NOT administer bicarbonate empirically."));
  items.push(bullet("Coagulopathy correction: Follow 1:1:1 ratio. Use TXA early. Correct fibrinogen with cryo/concentrate. Replenish calcium. Monitor with TEG/ROTEM if available."));

  items.push(heading2("8.7  Permissive Hypotension (Damage Control Resuscitation)"));
  items.push(para("In penetrating trauma patients prior to surgical haemostasis, target SBP 80–90 mmHg. This strategy limits haemodilution and reduces ongoing haemorrhage. Once surgical haemostasis is achieved, restore normal perfusion pressures. This strategy is NOT applicable to patients with head injury (maintain CPP)."));

  items.push(heading2("8.8  Transfusion Safety Checks (MANDATORY at bedside)"));
  items.push(bullet("Verify patient identity using two identifiers: Full Name AND Hospital ID (UHID) on wristband AND blood bag label AND crossmatch card AND prescription order."));
  items.push(bullet("Two-nurse / physician verification required for each unit."));
  items.push(bullet("Check: blood group, product type, unit number, expiry date, appearance (no clots, discolouration)."));
  items.push(bullet("Any mismatch → do NOT transfuse → return to blood bank immediately → inform senior physician."));
  items.push(bullet("Administer through a standard blood giving set with in-line filter (170–260 micron)."));

  items.push(heading2("8.9  Administration Rate"));
  const rateTable = new Table({
    width: { size: 100, type: WidthType.PERCENTAGE },
    rows: [
      hdrRow([shadedCell("Phase"), shadedCell("Rate"), shadedCell("Monitoring Interval")]),
      dataRow([plainCell("Active haemorrhage / MTP"), plainCell("As fast as clinically indicated (pressure bag if necessary)"), plainCell("Every 5–10 min: HR, BP, SpO₂, temperature, consciousness")]),
      dataRow([plainCell("Stabilisation"), plainCell("PRBC: 1 unit over 1–2 hours. FFP: 1 unit over 20–30 min"), plainCell("Every 15 min")]),
      dataRow([plainCell("Each unit must be completed within"), plainCell("4 hours of issue from blood bank"), plainCell("Document start and end time for each unit")])
    ]
  });
  items.push(rateTable);
  items.push(new Paragraph({ spacing: { before: 80, after: 60 }, children: [] }));

  items.push(heading2("8.10  MTP Deactivation"));
  items.push(para("MTP should be deactivated when:"));
  items.push(bullet("Haemostasis is achieved (surgical, procedural, or spontaneous)."));
  items.push(bullet("Patient is haemodynamically stable for > 30 minutes."));
  items.push(bullet("No further clinical or laboratory evidence of active haemorrhage."));
  items.push(bullet("Treating physician explicitly communicates MTP deactivation to blood bank."));
  items.push(para([bold("Procedure on deactivation:"), normal(" Return all unused blood products to blood bank within 20 minutes of issue (if temperature-maintained). Document time of deactivation. Complete all documentation (see Section 9).")], { before: 80, after: 80 }));

  // 9 DOCUMENTATION
  items.push(heading1("9. Documentation Requirements (NABH TPC.19 f & COP.8)"));
  const docTable = new Table({
    width: { size: 100, type: WidthType.PERCENTAGE },
    rows: [
      hdrRow([shadedCell("Document", "1F3864", "FFFFFF", true, 3000), shadedCell("Recorded by"), shadedCell("Location"), shadedCell("Retention")]),
      dataRow([plainCell("MTP Activation Form (time, indication, activating physician)", null, true), plainCell("Physician"), plainCell("Patient case sheet + Blood Bank register"), plainCell("10 years")]),
      dataRow([plainCell("Blood Bank Issue Register (unit-wise)"), plainCell("Blood Bank Tech"), plainCell("Blood Bank"), plainCell("10 years")]),
      dataRow([plainCell("Blood Product Administration Record (start time, stop time, volume, dual verification, vital signs, transfusion reaction Y/N)"), plainCell("Nurse"), plainCell("Patient bedside chart"), plainCell("10 years")]),
      dataRow([plainCell("Lab monitoring sheet (CBC, coagulation, metabolic parameters — timestamped)"), plainCell("Physician / Lab"), plainCell("Case sheet"), plainCell("10 years")]),
      dataRow([plainCell("Transfusion Reaction Form (if any)"), plainCell("Nurse + Physician"), plainCell("Case sheet + Blood Bank"), plainCell("10 years")]),
      dataRow([plainCell("MTP Deactivation Record (time, reason, units used, outcome)"), plainCell("Physician"), plainCell("Case sheet + Blood Bank"), plainCell("10 years")]),
      dataRow([plainCell("Blood bag with transfusion tag (retain for 24 h post-transfusion)"), plainCell("Nurse"), plainCell("Ward / Blood Bank"), plainCell("24 h post-transfusion")])
    ]
  });
  items.push(docTable);
  items.push(new Paragraph({ spacing: { before: 120, after: 80 }, children: [] }));

  // 10 ADVERSE REACTIONS
  items.push(heading1("10. Management of Adverse Transfusion Reactions During MTP (NABH TPC.20)"));
  items.push(para("Even during MTP, adverse reactions must be managed. Stop transfusion of the suspect unit. Do NOT stop all transfusions if life-threatening haemorrhage is ongoing — switch to a different unit while investigating."));
  const rxTable = new Table({
    width: { size: 100, type: WidthType.PERCENTAGE },
    rows: [
      hdrRow([shadedCell("Reaction Type"), shadedCell("Features"), shadedCell("Immediate Action")]),
      dataRow([plainCell("Acute Haemolytic (AHTR)", null, true), plainCell("Fever, chills, back/flank pain, haemoglobinuria, hypotension"), plainCell("STOP unit. Recheck identity. IV fluids. Notify blood bank. Send post-reaction sample + unit to blood bank.")]),
      dataRow([plainCell("Febrile Non-Haemolytic (FNHTR)"), plainCell("Fever ≥ 1°C rise, chills (no haemolysis)"), plainCell("Slow or stop transfusion. Paracetamol. Rule out AHTR.")]),
      dataRow([plainCell("Allergic / Anaphylactic"), plainCell("Urticaria, bronchospasm, hypotension, angioedema"), plainCell("Stop transfusion. Adrenaline 0.5 mg IM for anaphylaxis. Antihistamine + steroids for mild reactions.")]),
      dataRow([plainCell("TRALI"), plainCell("Acute dyspnoea, hypoxia, bilateral pulmonary infiltrates within 6 h"), plainCell("Stop transfusion. Oxygen / mechanical ventilation. Report to blood bank and regulatory authority.")]),
      dataRow([plainCell("TACO"), plainCell("Dyspnoea, hypertension, elevated JVP within 6 h"), plainCell("Slow/stop transfusion. Diuretics. Oxygen.")]),
      dataRow([plainCell("Bacterial Contamination"), plainCell("High fever, rigors, rapid hypotension, septic shock"), plainCell("Stop transfusion. Blood cultures (patient + bag). IV antibiotics STAT. Inform blood bank immediately.")])
    ]
  });
  items.push(rxTable);
  items.push(new Paragraph({ spacing: { before: 80, after: 60 }, children: [] }));
  items.push(para([bold("Post-reaction steps:"), normal(" Complete Transfusion Reaction Investigation Form. Return suspect unit to blood bank. Blood bank to repeat ABO/Rh on donor unit and patient sample, direct Coombs test, and urinalysis. Report to appropriate regulatory authority as per statutory requirements.")]));

  // 11 SPECIAL POPULATIONS
  items.push(heading1("11. Special Populations"));
  items.push(heading2("11.1  Obstetric / Postpartum Haemorrhage (PPH)"));
  items.push(bullet("MTP trigger: Blood loss > 1500 mL or any clinical shock with active bleeding."));
  items.push(bullet("Use Rh(D)-negative PRBC for all females of childbearing potential if group unknown."));
  items.push(bullet("Oxytocin + uterotonic agents + TXA alongside MTP."));
  items.push(bullet("Target fibrinogen ≥ 2 g/L in PPH (higher threshold than general MTP)."));
  items.push(bullet("Coordinate with Obstetrics, Anaesthesiology, and Blood Bank team simultaneously."));
  items.push(heading2("11.2  Paediatric Patients"));
  items.push(bullet("MTP trigger: ≥ 40 mL/kg blood products in 2 hours or ≥ 3 units blood products in 1 hour."));
  items.push(bullet("Component volumes are weight-based: PRBC 10–15 mL/kg; FFP 10–20 mL/kg; Platelets 10–15 mL/kg."));
  items.push(bullet("Use paediatric-specific blood products (irradiated, CMV-negative as per clinical indication)."));
  items.push(heading2("11.3  Patients on Anticoagulants"));
  items.push(bullet("Warfarin: FFP + Vitamin K + consider PCC."));
  items.push(bullet("NOAC (Dabigatran): Idarucizumab if available; otherwise PCC."));
  items.push(bullet("NOAC (Rivaroxaban / Apixaban): Andexanet alfa or PCC (50 IU/kg)."));
  items.push(bullet("Heparin: Protamine sulphate (1 mg per 100 units of heparin administered in preceding 2–3 h)."));

  // 12 BLOOD BANK PREPAREDNESS
  items.push(heading1("12. Blood Bank Preparedness & Stock Management"));
  items.push(bullet("Maintain a minimum emergency stock: 6 units O-negative PRBC, 6 units AB-positive FFP (thawed or as liquid plasma), 2 units SDP or 12 units RDP at all times."));
  items.push(bullet("FFP thawing protocol: 30 minutes in validated water bath at 37 °C. Document thaw time."));
  items.push(bullet("Cryoprecipitate: Thaw in validated water bath; use within 4 hours of thawing."));
  items.push(bullet("All blood products must be stored at validated temperatures: PRBC 2–6 °C; FFP -18 °C or below; Platelets 20–24 °C with gentle agitation; Cryo -18 °C or below."));
  items.push(bullet("Use blood warmers (validated to 37–42 °C) for all products during MTP — never use unvalidated heating devices."));
  items.push(bullet("Pressure infusers / rapid infusion devices must be available in ED, OT, and ICU."));
  items.push(bullet("Blood Bank must have a dedicated 24/7 emergency contact number displayed in all clinical areas."));

  // 13 TRAINING
  items.push(heading1("13. Training & Competency"));
  const trainTable = new Table({
    width: { size: 100, type: WidthType.PERCENTAGE },
    rows: [
      hdrRow([shadedCell("Staff Category"), shadedCell("Training Content"), shadedCell("Frequency"), shadedCell("Record Maintained by")]),
      dataRow([plainCell("Physicians / Surgeons / Anaesthesiologists"), plainCell("MTP activation criteria, ABC score, blood product ratios, lab targets, deactivation"), plainCell("Annual + on new joining"), plainCell("Medical Education / QM")]),
      dataRow([plainCell("Nursing Staff"), plainCell("Patient identity checks, administration, vital monitoring, reaction recognition"), plainCell("Annual + on new joining"), plainCell("Nursing In-charge / QM")]),
      dataRow([plainCell("Blood Bank Technicians"), plainCell("MTP pack assembly, emergency crossmatch, rapid thawing, communication protocol"), plainCell("Annual + on new joining"), plainCell("Blood Bank HOD")]),
      dataRow([plainCell("All Clinical Staff"), plainCell("Transfusion reaction recognition and management, TXA administration"), plainCell("Annual"), plainCell("QM")])
    ]
  });
  items.push(trainTable);
  items.push(new Paragraph({ spacing: { before: 80, after: 60 }, children: [] }));

  // 14 QUALITY INDICATORS
  items.push(heading1("14. Quality Indicators & Audit (NABH BSQ.7 & BSQ.11)"));
  const qiTable = new Table({
    width: { size: 100, type: WidthType.PERCENTAGE },
    rows: [
      hdrRow([shadedCell("Indicator"), shadedCell("Target"), shadedCell("Review Frequency")]),
      dataRow([plainCell("Time from MTP activation to first blood product issue"), plainCell("≤ 10 minutes"), plainCell("Monthly")]),
      dataRow([plainCell("Completion of MTP documentation (all fields)"), plainCell("100%"), plainCell("Monthly")]),
      dataRow([plainCell("Rate of wasted blood products (returned > 20 min after issue)"), plainCell("< 5%"), plainCell("Monthly")]),
      dataRow([plainCell("Adverse transfusion reaction rate during MTP"), plainCell("Monitor & trend"), plainCell("Monthly")]),
      dataRow([plainCell("MTP activations with ABC Score documented"), plainCell("100%"), plainCell("Monthly")]),
      dataRow([plainCell("Staff trained in MTP per year"), plainCell("100%"), plainCell("Annually")]),
      dataRow([plainCell("Hospital Transfusion Committee meeting frequency"), plainCell("Quarterly"), plainCell("Quarterly")])
    ]
  });
  items.push(qiTable);
  items.push(new Paragraph({ spacing: { before: 80, after: 60 }, children: [] }));

  // 15 REFERENCES
  items.push(heading1("15. References & Regulatory Basis"));
  items.push(bullet("NABH Accreditation Standards for Blood Centres and Transfusion Services, 4th Edition, November 2024 — Standards TPC.15–TPC.20, BSQ.7, BSQ.9, BSQ.11."));
  items.push(bullet("NABH Hospital Accreditation Standards (5th Edition) — COP.8 (Use of Blood and Blood Products)."));
  items.push(bullet("Drugs and Cosmetics Act 1940 and Rules 1945 (Schedule F, Part XII-B) — Blood Bank Licensing."));
  items.push(bullet("Schwartz's Principles of Surgery (11th Ed.) — Denver Health Medical Center MTP Flowchart (Fig. 7-33)."));
  items.push(bullet("Henry's Clinical Diagnosis and Management by Laboratory Methods (23rd Ed.) — Massive Transfusion Chapter."));
  items.push(bullet("Tintinalli's Emergency Medicine (9th Ed.) — Massive Transfusion Protocol; ABC Score."));
  items.push(bullet("Rosen's Emergency Medicine (9th Ed.) — Massive Transfusion Protocols; 1:1:1 ratio evidence."));
  items.push(bullet("PROPPR Trial: Holcomb JB et al. Transfusion of plasma, platelets, and red blood cells in a 1:1:1 vs a 1:1:2 ratio and mortality in patients with severe trauma. JAMA. 2015;313(5):471–482."));
  items.push(bullet("CRASH-2 Trial: Effects of tranexamic acid on death, vascular occlusive events, and blood transfusion. Lancet. 2010;376(9734):23–32."));
  items.push(bullet("Indian Journal of Anaesthesia — Massive transfusion and MTP review (PMID: 25535421)."));
  items.push(bullet("National Blood Transfusion Council of India — National Blood Policy and Operational Guidelines."));
  items.push(new Paragraph({ spacing: { before: 120, after: 80 }, children: [] }));

  // 16 APPENDICES
  items.push(heading1("16. Appendices"));
  items.push(heading2("Appendix A: MTP Activation Quick Reference Card"));
  const qrcTable = new Table({
    width: { size: 100, type: WidthType.PERCENTAGE },
    rows: [
      dataRow([
        new TableCell({
          columnSpan: 2,
          shading: { fill: "C0392B", type: ShadingType.CLEAR, color: "auto" },
          margins: { top: 100, bottom: 100, left: 150, right: 150 },
          children: [new Paragraph({ alignment: AlignmentType.CENTER, children: [new TextRun({ text: "🚨  MTP ACTIVATION QUICK REFERENCE", bold: true, color: "FFFFFF", size: 24, font: FONT })] })]
        })
      ]),
      dataRow([
        new TableCell({
          width: { size: 50, type: WidthType.PERCENTAGE },
          shading: { fill: "FDECEA", type: ShadingType.CLEAR, color: "auto" },
          margins: { top: 100, bottom: 100, left: 150, right: 150 },
          children: [
            new Paragraph({ children: [new TextRun({ text: "STEP 1: RECOGNISE", bold: true, size: 22, font: FONT, color: "C0392B" })] }),
            new Paragraph({ children: [new TextRun({ text: "• ABC Score ≥ 2  OR", size: 20, font: FONT })] }),
            new Paragraph({ children: [new TextRun({ text: "• ≥ 4 PRBC in 1 h  OR", size: 20, font: FONT })] }),
            new Paragraph({ children: [new TextRun({ text: "• Clinical judgment (ruptured AAA, PPH, major trauma)", size: 20, font: FONT })] })
          ]
        }),
        new TableCell({
          width: { size: 50, type: WidthType.PERCENTAGE },
          shading: { fill: "EBF5FB", type: ShadingType.CLEAR, color: "auto" },
          margins: { top: 100, bottom: 100, left: 150, right: 150 },
          children: [
            new Paragraph({ children: [new TextRun({ text: "STEP 2: ACTIVATE", bold: true, size: 22, font: FONT, color: "1A5276" })] }),
            new Paragraph({ children: [new TextRun({ text: "• Call Blood Bank: Ext ______", size: 20, font: FONT })] }),
            new Paragraph({ children: [new TextRun({ text: "• Say: \"MTP ACTIVATION — [Name] [Location]\"", size: 20, font: FONT })] }),
            new Paragraph({ children: [new TextRun({ text: "• Send EDTA + clot tube to Blood Bank STAT", size: 20, font: FONT })] })
          ]
        })
      ]),
      dataRow([
        new TableCell({
          width: { size: 50, type: WidthType.PERCENTAGE },
          shading: { fill: "EAFAF1", type: ShadingType.CLEAR, color: "auto" },
          margins: { top: 100, bottom: 100, left: 150, right: 150 },
          children: [
            new Paragraph({ children: [new TextRun({ text: "STEP 3: TRANSFUSE (1:1:1 RATIO)", bold: true, size: 22, font: FONT, color: "1E8449" })] }),
            new Paragraph({ children: [new TextRun({ text: "Pack 1: 4 PRBC + 4 FFP", size: 20, font: FONT })] }),
            new Paragraph({ children: [new TextRun({ text: "Pack 2: 4 PRBC + 4 FFP + 1 SDP + 10 Cryo", size: 20, font: FONT })] }),
            new Paragraph({ children: [new TextRun({ text: "+ TXA 1g IV + CaCl₂ 1g per 4 PRBC", size: 20, font: FONT })] })
          ]
        }),
        new TableCell({
          width: { size: 50, type: WidthType.PERCENTAGE },
          shading: { fill: "FDF2F8", type: ShadingType.CLEAR, color: "auto" },
          margins: { top: 100, bottom: 100, left: 150, right: 150 },
          children: [
            new Paragraph({ children: [new TextRun({ text: "STEP 4: MONITOR & DEACTIVATE", bold: true, size: 22, font: FONT, color: "6C3483" })] }),
            new Paragraph({ children: [new TextRun({ text: "• Labs every 30–60 min (CBC, PT, APTT, Fib, Ca²⁺)", size: 20, font: FONT })] }),
            new Paragraph({ children: [new TextRun({ text: "• Prevent lethal triad: warm blood, no excess crystalloid", size: 20, font: FONT })] }),
            new Paragraph({ children: [new TextRun({ text: "• Deactivate when haemostasis achieved + stable", size: 20, font: FONT })] })
          ]
        })
      ])
    ]
  });
  items.push(qrcTable);
  items.push(new Paragraph({ spacing: { before: 120, after: 80 }, children: [] }));

  items.push(heading2("Appendix B: ABC Score Calculator"));
  const abcTable = new Table({
    width: { size: 100, type: WidthType.PERCENTAGE },
    rows: [
      hdrRow([shadedCell("Criterion"), shadedCell("Present (1 point)"), shadedCell("Absent (0 points)")]),
      dataRow([plainCell("Penetrating mechanism of injury"), plainCell("Yes = 1"), plainCell("No = 0")]),
      dataRow([plainCell("SBP ≤ 90 mmHg on arrival"), plainCell("Yes = 1"), plainCell("No = 0")]),
      dataRow([plainCell("Heart Rate ≥ 120 bpm on arrival"), plainCell("Yes = 1"), plainCell("No = 0")]),
      dataRow([plainCell("Positive FAST (free fluid on ultrasound)"), plainCell("Yes = 1"), plainCell("No = 0")]),
      dataRow([plainCell("TOTAL SCORE", "FDECEA"), plainCell("≥ 2: ACTIVATE MTP (Sensitivity 76–90%)", "FDECEA"), plainCell("< 2: MTP not indicated (but use clinical judgment)", "FDECEA")])
    ]
  });
  items.push(abcTable);
  items.push(new Paragraph({ spacing: { before: 120, after: 80 }, children: [] }));

  items.push(heading2("Appendix C: Cryoprecipitate Dose Calculation"));
  items.push(para([
    normal("Use the following formula when targeting fibrinogen replacement:"),
    new TextRun({ break: 1 }),
    new TextRun({ text: "Units of Cryo = (Desired Fibrinogen − Initial Fibrinogen) × Patient Plasma Volume (dL) ÷ 250 mg/unit", bold: true, size: 22, font: MONO })
  ]));
  items.push(para("Patient plasma volume (mL) = 0.07 × weight (kg) × 1000 × (1 - Hct)  [Hct expressed as decimal]"));
  items.push(para("Typically 10 units of pooled cryoprecipitate raises fibrinogen by approximately 1 g/L in a 70-kg adult."));

  items.push(heading2("Appendix D: Contact Directory for MTP (fill institution-specific numbers)"));
  const contactTable = new Table({
    width: { size: 100, type: WidthType.PERCENTAGE },
    rows: [
      hdrRow([shadedCell("Service"), shadedCell("Extension / Number"), shadedCell("On-call Availability")]),
      dataRow([plainCell("Blood Bank Emergency"), plainCell("Ext: ________"), plainCell("24/7")]),
      dataRow([plainCell("Blood Bank Officer / Pathologist"), plainCell("Ext: ________"), plainCell("24/7")]),
      dataRow([plainCell("Anaesthesiology On-call"), plainCell("Ext: ________"), plainCell("24/7")]),
      dataRow([plainCell("Surgery On-call"), plainCell("Ext: ________"), plainCell("24/7")]),
      dataRow([plainCell("Haematologist / Transfusion Specialist"), plainCell("Ext: ________"), plainCell("24/7")]),
      dataRow([plainCell("ICU In-charge"), plainCell("Ext: ________"), plainCell("24/7")]),
      dataRow([plainCell("Medical Superintendent"), plainCell("Ext: ________"), plainCell("24/7")])
    ]
  });
  items.push(contactTable);

  return items;
}

// ── Build document ────────────────────────────────────────────────────────────
const doc = new Document({
  numbering: {
    config: [
      {
        reference: "my-numbering",
        levels: [
          {
            level: 0,
            format: "decimal",
            text: "%1.",
            alignment: AlignmentType.LEFT,
            style: { paragraph: { indent: { left: convertInchesToTwip(0.5), hanging: convertInchesToTwip(0.25) } } }
          }
        ]
      }
    ]
  },
  styles: {
    default: {
      document: { run: { font: FONT, size: 22 } }
    }
  },
  sections: [
    {
      properties: {
        page: {
          margin: { top: convertInchesToTwip(1), bottom: convertInchesToTwip(1), left: convertInchesToTwip(1.25), right: convertInchesToTwip(1) }
        }
      },
      headers: {
        default: new Header({
          children: [
            new Paragraph({
              border: { bottom: { color: "1F3864", size: 6, style: BorderStyle.SINGLE } },
              spacing: { after: 80 },
              children: [
                new TextRun({ text: "[HOSPITAL NAME] | Standard Operating Procedure | ", bold: true, size: 18, color: "1F3864", font: FONT }),
                new TextRun({ text: "Massive Blood Transfusion Protocol (MTP)", italics: true, size: 18, color: "666666", font: FONT })
              ]
            })
          ]
        })
      },
      footers: {
        default: new Footer({
          children: [
            new Paragraph({
              border: { top: { color: "1F3864", size: 6, style: BorderStyle.SINGLE } },
              spacing: { before: 80 },
              alignment: AlignmentType.CENTER,
              children: [
                new TextRun({ text: "NABH Std. Ref: COP.8 | TPC.15–TPC.20 | BSQ.7 | BSQ.11   |   Doc. No: [HOSPITAL CODE]/BB/SOP/001   |   Page ", size: 16, font: FONT }),
                new TextRun({ children: [PageNumber.CURRENT], size: 16, font: FONT }),
                new TextRun({ text: " of ", size: 16, font: FONT }),
                new TextRun({ children: [PageNumber.TOTAL_PAGES], size: 16, font: FONT }),
                new TextRun({ text: "   |   Version 1.0   |   CONTROLLED DOCUMENT", size: 16, font: FONT })
              ]
            })
          ]
        })
      },
      children: [
        ...titleBlock(),
        ...amendmentTable(),
        ...signatureTable(),
        ...mainContent()
      ]
    }
  ]
});

Packer.toBuffer(doc).then(buf => {
  fs.writeFileSync("/home/daytona/workspace/mtp-sop/MTP_SOP_NABH.docx", buf);
  console.log("✅ Document written.");
}).catch(e => { console.error(e); process.exit(1); });
Running Command

cd /home/daytona/workspace/mtp-sop && node generate_mtp_sop.js 2>&1

Running Command

python3 /home/daytona/skills/docx/scripts/office/validate.py /home/daytona/workspace/mtp-sop/MTP_SOP_NABH.docx 2>&1

Running Command

cd /home/daytona/workspace/mtp-sop && python3 -c " import zipfile, os z = zipfile.ZipFile('MTP_SOP_NABH.docx') names = z.namelist() print('Files in docx:', names[:10]) # check word/document.xml exists and has content doc_xml = z.read('word/document.xml') print('document.xml size:', len(doc_xml), 'bytes') print('First 200 chars:', doc_xml[:200]) "

The document is valid - 268 KB, complete XML structure. The file is ready.

Here is your complete, NABH-ready SOP for the Massive Blood Transfusion Protocol:

MTP SOP NABH

Word Document · DOCX


What the SOP Contains

The document is a fully formatted, print-ready Word file with header/footer, page numbers, and colour-coded tables throughout. Here is a summary of all sections:

Document Control Block

  • Document number field (fill your hospital code), NABH standard references (COP.8, TPC.15–TPC.20, BSQ.7, BSQ.11), version, effective date, prepared/approved by, and status as "Controlled Document."
  • Amendment history table and signature/authorization table for Prepared by / Reviewed by / Approved by.

Section-by-Section Summary

SectionContent
3. PurposeRationale, NABH standard alignment, lethal triad prevention
4. ScopeAll clinical departments + blood bank; all relevant staff
5. Definitions12 terms: MT, MTP, ABC Score, PRBC, FFP, Cryo, TXA, TEG/ROTEM, Lethal Triad, O-negative blood
6. ResponsibilitiesRole-wise table: MS/CMO, Blood Bank HOD, Technician, Physician, Nursing, Quality Manager
7. MTP Activation CriteriaABC Score ≥ 2, ≥ 4 PRBC/h, clinical judgement; haemorrhage class I–IV table
8. Procedure10 sub-steps: activation, blood bank response, MTP packs (Pack 1/2/3+), adjuncts (TXA, CaCl₂, fibrinogen, PCC, rFVIIa), lab monitoring targets, lethal triad prevention, permissive hypotension, bedside safety checks, administration rate, deactivation
9. Documentation7 document types, responsible person, location, 10-year retention
10. Adverse Reactions6 reaction types (AHTR, FNHTR, allergic, TRALI, TACO, bacterial) with immediate action
11. Special PopulationsObstetric/PPH, paediatric (weight-based dosing), anticoagulated patients (NOAC reversal)
12. Blood Bank PreparednessMinimum stock levels, storage temperatures, validated warmers, pressure infusers
13. TrainingBy staff category, frequency, record keeper
14. Quality Indicators7 KPIs including time to first issue ≤ 10 min; Hospital Transfusion Committee quarterly review
15. ReferencesNABH 4th Ed. 2024, PROPPR Trial, CRASH-2, Indian Journal of Anaesthesia, NBTC guidelines
Appendix AMTP Quick Reference Card (colour-coded 4-step card for clinical areas)
Appendix BABC Score Calculator table
Appendix CCryoprecipitate dose calculation formula
Appendix DContact directory template (fill hospital extensions)

Key Clinical Standards Embedded (Evidence-Based)

  • 1:1:1 ratio (PRBC : FFP : Platelets) - PROPPR Trial basis
  • TXA within 3 hours - CRASH-2 Trial
  • Ionised Ca²⁺ ≥ 0.9 mmol/L - Calcium supplementation per 4 PRBC
  • Fibrinogen target ≥ 1.5 g/L (≥ 2 g/L in PPH)
  • O-negative blood for unknown group / females of childbearing age
  • Permissive hypotension (SBP 80–90 mmHg) only in penetrating trauma before haemostasis

Customisation Needed Before Inspection

Replace all [HOSPITAL CODE], [DD/MM/YYYY], Ext: ________, and [Name/Designation] fields with your institution's actual details before submission.
This is a shared conversation. Sign in to Orris to start your own chat.