I want to make a report for my patient to show his consultant doctor. So how to do it give me a example
As a physiotherapist
mkdir -p /home/daytona/workspace/physio-report && ls /home/daytona/workspace/phy…
~/physio-report/generate_report.js
const {
Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell,
AlignmentType, HeadingLevel, LevelFormat, BorderStyle, WidthType,
ShadingType, VerticalAlign, PageNumber, Header, Footer
} = require('docx');
const fs = require('fs');
// ─── Helpers ────────────────────────────────────────────────────────────────
function label(text) {
return new TextRun({ text, bold: true, font: "Arial", size: 22 });
}
function value(text) {
return new TextRun({ text, font: "Arial", size: 22 });
}
function spacer() {
return new Paragraph({ children: [new TextRun("")], spacing: { before: 80, after: 80 } });
}
function sectionHeading(text) {
return new Paragraph({
heading: HeadingLevel.HEADING_2,
children: [new TextRun({ text, font: "Arial", bold: true, size: 26, color: "1F497D" })],
spacing: { before: 240, after: 120 },
border: {
bottom: { style: BorderStyle.SINGLE, size: 6, color: "1F497D", space: 4 }
}
});
}
function bodyText(text) {
return new Paragraph({
children: [new TextRun({ text, font: "Arial", size: 22 })],
spacing: { before: 60, after: 60 }
});
}
function bulletItem(text) {
return new Paragraph({
numbering: { reference: "bullets", level: 0 },
children: [new TextRun({ text, font: "Arial", size: 22 })],
spacing: { before: 40, after: 40 }
});
}
function infoRow(labelText, valueText) {
return new TableRow({
children: [
new TableCell({
width: { size: 3000, type: WidthType.DXA },
shading: { type: ShadingType.SOLID, color: "E9EEF6" },
children: [new Paragraph({ children: [label(labelText)], spacing: { before: 80, after: 80 }, indent: { left: 80 } })],
borders: {
top: { style: BorderStyle.NONE }, bottom: { style: BorderStyle.NONE },
left: { style: BorderStyle.NONE }, right: { style: BorderStyle.NONE }
}
}),
new TableCell({
width: { size: 6000, type: WidthType.DXA },
children: [new Paragraph({ children: [value(valueText)], spacing: { before: 80, after: 80 }, indent: { left: 80 } })],
borders: {
top: { style: BorderStyle.NONE }, bottom: { style: BorderStyle.NONE },
left: { style: BorderStyle.NONE }, right: { style: BorderStyle.NONE }
}
})
]
});
}
// ─── Document ────────────────────────────────────────────────────────────────
const doc = new Document({
numbering: {
config: [
{
reference: "bullets",
levels: [{
level: 0, format: LevelFormat.BULLET, text: "\u2022",
alignment: AlignmentType.LEFT,
style: { paragraph: { indent: { left: 720, hanging: 360 } } }
}]
}
]
},
styles: {
default: {
document: { run: { font: "Arial", size: 22 } }
},
paragraphStyles: [
{
id: "Heading1", name: "Heading 1", basedOn: "Normal", next: "Normal", quickFormat: true,
run: { size: 36, bold: true, font: "Arial", color: "1F497D" },
paragraph: { spacing: { before: 0, after: 200 }, outlineLevel: 0 }
},
{
id: "Heading2", name: "Heading 2", basedOn: "Normal", next: "Normal", quickFormat: true,
run: { size: 26, bold: true, font: "Arial", color: "1F497D" },
paragraph: { spacing: { before: 240, after: 120 }, outlineLevel: 1 }
}
]
},
sections: [{
properties: {
page: {
margin: { top: 1000, bottom: 1000, left: 1100, right: 1100 }
}
},
headers: {
default: new Header({
children: [
new Paragraph({
alignment: AlignmentType.RIGHT,
children: [
new TextRun({ text: "CONFIDENTIAL - FOR CLINICAL USE ONLY", font: "Arial", size: 18, color: "AA0000", bold: true })
],
border: { bottom: { style: BorderStyle.SINGLE, size: 6, color: "1F497D", space: 4 } }
})
]
})
},
footers: {
default: new Footer({
children: [
new Paragraph({
alignment: AlignmentType.CENTER,
children: [
new TextRun({ text: "City Physiotherapy Clinic | Tel: 01-234-5678 | Page ", font: "Arial", size: 18, color: "555555" }),
new TextRun({ children: [PageNumber.CURRENT], font: "Arial", size: 18, color: "555555" }),
new TextRun({ text: " of ", font: "Arial", size: 18, color: "555555" }),
new TextRun({ children: [PageNumber.TOTAL_PAGES], font: "Arial", size: 18, color: "555555" })
],
border: { top: { style: BorderStyle.SINGLE, size: 6, color: "1F497D", space: 4 } }
})
]
})
},
children: [
// ── TITLE BLOCK ──────────────────────────────────────────────────────
new Paragraph({
alignment: AlignmentType.CENTER,
children: [new TextRun({ text: "PHYSIOTHERAPY ASSESSMENT REPORT", font: "Arial", size: 40, bold: true, color: "1F497D" })],
spacing: { before: 200, after: 100 }
}),
new Paragraph({
alignment: AlignmentType.CENTER,
children: [new TextRun({ text: "City Physiotherapy Clinic", font: "Arial", size: 24, color: "555555" })],
spacing: { before: 0, after: 40 }
}),
new Paragraph({
alignment: AlignmentType.CENTER,
children: [new TextRun({ text: "123 Health Street, Dublin 2 | Tel: 01-234-5678 | Email: info@cityphysio.ie", font: "Arial", size: 20, color: "555555" })],
spacing: { before: 0, after: 40 }
}),
new Paragraph({
alignment: AlignmentType.CENTER,
children: [new TextRun({ text: "Date of Report: 13 July 2026", font: "Arial", size: 22, bold: true })],
spacing: { before: 80, after: 200 }
}),
// ── PATIENT DETAILS ──────────────────────────────────────────────────
sectionHeading("1. Patient Details"),
new Table({
width: { size: 9000, type: WidthType.DXA },
rows: [
infoRow("Patient Name:", "Mr. James O'Sullivan"),
infoRow("Date of Birth:", "14 March 1978 (Age: 48)"),
infoRow("Gender:", "Male"),
infoRow("Address:", "45 Maple Avenue, Dublin 6"),
infoRow("Contact Number:", "085-123-4567"),
infoRow("GP / Referring Doctor:", "Dr. Sarah Byrne, Rathmines Medical Centre"),
infoRow("Consultant (Referral To):", "Mr. David Hughes, Orthopaedic Consultant, St. Vincent's Hospital"),
infoRow("Date of Initial Assessment:", "01 July 2026"),
infoRow("Date of This Report:", "13 July 2026"),
infoRow("Treating Physiotherapist:", "Ms. Aoife Kelly, BSc. Physio, MISCP")
]
}),
spacer(),
// ── REASON FOR REFERRAL ──────────────────────────────────────────────
sectionHeading("2. Reason for Physiotherapy Referral"),
bodyText(
"Mr. O'Sullivan was referred to physiotherapy by Dr. Sarah Byrne following a road traffic " +
"accident on 18 June 2026. He sustained a Grade II lumbar muscle strain with suspected " +
"involvement of the L4-L5 disc. This report is prepared at the request of the treating " +
"physiotherapist to assist Mr. David Hughes (Orthopaedic Consultant) in further management."
),
spacer(),
// ── SUBJECTIVE ASSESSMENT ────────────────────────────────────────────
sectionHeading("3. Subjective Assessment"),
new Paragraph({ children: [label("Chief Complaint:")], spacing: { before: 100, after: 60 } }),
bodyText(
"Low back pain (LBP) with radiation to the right buttock and posterior thigh, worse with " +
"prolonged sitting and bending forward."
),
new Paragraph({ children: [label("Pain Score (NRS):")], spacing: { before: 100, after: 60 } }),
bodyText("7/10 at rest; 9/10 with activity at initial assessment."),
new Paragraph({ children: [label("Aggravating Factors:")], spacing: { before: 100, after: 60 } }),
bulletItem("Prolonged sitting (>20 minutes)"),
bulletItem("Forward flexion and lifting"),
bulletItem("Coughing and sneezing"),
new Paragraph({ children: [label("Easing Factors:")], spacing: { before: 100, after: 60 } }),
bulletItem("Lying supine with knees flexed"),
bulletItem("Heat application"),
bulletItem("Analgesic medication (Ibuprofen 400 mg TDS as prescribed)"),
new Paragraph({ children: [label("Past Medical History:")], spacing: { before: 100, after: 60 } }),
bodyText("Hypertension (well-controlled, Amlodipine 5 mg OD). No prior spinal surgery. Non-smoker."),
spacer(),
// ── OBJECTIVE ASSESSMENT ─────────────────────────────────────────────
sectionHeading("4. Objective Assessment"),
new Paragraph({ children: [label("Observation:")], spacing: { before: 100, after: 60 } }),
bulletItem("Antalgic posture with right lateral shift"),
bulletItem("Reduced lumbar lordosis"),
bulletItem("Mild paraspinal muscle guarding (L3-L5 bilaterally, R > L)"),
new Paragraph({ children: [label("Range of Motion (Lumbar Spine):")], spacing: { before: 100, after: 60 } }),
new Table({
width: { size: 7000, type: WidthType.DXA },
rows: [
new TableRow({
children: [
new TableCell({ children: [new Paragraph({ children: [label("Movement")], indent: { left: 80 } })], shading: { type: ShadingType.SOLID, color: "1F497D" }, width: { size: 2500, type: WidthType.DXA } }),
new TableCell({ children: [new Paragraph({ children: [new TextRun({ text: "Normal", font: "Arial", size: 22, bold: true, color: "FFFFFF" })], indent: { left: 80 } })], shading: { type: ShadingType.SOLID, color: "1F497D" }, width: { size: 2000, type: WidthType.DXA } }),
new TableCell({ children: [new Paragraph({ children: [new TextRun({ text: "Measured", font: "Arial", size: 22, bold: true, color: "FFFFFF" })], indent: { left: 80 } })], shading: { type: ShadingType.SOLID, color: "1F497D" }, width: { size: 2500, type: WidthType.DXA } })
]
}),
new TableRow({ children: [new TableCell({ children: [new Paragraph({ children: [value("Flexion")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] }), new TableCell({ children: [new Paragraph({ children: [value("~80-90 deg")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] }), new TableCell({ children: [new Paragraph({ children: [value("35 deg (pain +++)")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] })] }),
new TableRow({ children: [new TableCell({ children: [new Paragraph({ children: [value("Extension")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] }), new TableCell({ children: [new Paragraph({ children: [value("~20-30 deg")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] }), new TableCell({ children: [new Paragraph({ children: [value("15 deg (mild pain)")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] })] }),
new TableRow({ children: [new TableCell({ children: [new Paragraph({ children: [value("L. Flexion")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] }), new TableCell({ children: [new Paragraph({ children: [value("~30-35 deg")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] }), new TableCell({ children: [new Paragraph({ children: [value("20 deg")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] })] }),
new TableRow({ children: [new TableCell({ children: [new Paragraph({ children: [value("R. Flexion")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] }), new TableCell({ children: [new Paragraph({ children: [value("~30-35 deg")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] }), new TableCell({ children: [new Paragraph({ children: [value("12 deg (pain +++)")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] })] }),
new TableRow({ children: [new TableCell({ children: [new Paragraph({ children: [value("Rotation (L)")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] }), new TableCell({ children: [new Paragraph({ children: [value("~30 deg")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] }), new TableCell({ children: [new Paragraph({ children: [value("22 deg")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] })] }),
new TableRow({ children: [new TableCell({ children: [new Paragraph({ children: [value("Rotation (R)")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] }), new TableCell({ children: [new Paragraph({ children: [value("~30 deg")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] }), new TableCell({ children: [new Paragraph({ children: [value("18 deg (pain ++)")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] })] })
]
}),
spacer(),
new Paragraph({ children: [label("Neurological Screen:")], spacing: { before: 100, after: 60 } }),
bulletItem("Straight Leg Raise (SLR): Positive on the right at 45 deg (radicular reproduction)"),
bulletItem("Dermatomal sensation: Reduced light touch in right L5 distribution (dorsum of foot)"),
bulletItem("Myotomal testing: Grade 4/5 weakness noted in right great toe extension (EHL)"),
bulletItem("Reflexes: Right knee jerk intact; right ankle jerk slightly reduced (1+)"),
new Paragraph({ children: [label("Special Tests:")], spacing: { before: 100, after: 60 } }),
bulletItem("FABER: Negative bilaterally (hip pathology excluded)"),
bulletItem("Slump Test: Positive right side, reproducing posterior thigh symptoms"),
bulletItem("Palpation: Significant tenderness at L4-L5 spinous process and right paraspinal muscles"),
spacer(),
// ── INVESTIGATIONS ───────────────────────────────────────────────────
sectionHeading("5. Investigations"),
bodyText("X-ray Lumbar Spine (27 June 2026): Mild disc space narrowing at L4-L5. No fracture or spondylolisthesis."),
bodyText("MRI Lumbar Spine (requested, pending at time of report): Not yet available."),
spacer(),
// ── PHYSIOTHERAPY DIAGNOSIS ──────────────────────────────────────────
sectionHeading("6. Physiotherapy Working Diagnosis"),
bodyText(
"Right-sided L4-L5 disc pathology with suspected nerve root irritation (L5 radiculopathy), " +
"secondary to road traffic accident on 18 June 2026. Clinical presentation is consistent with " +
"a contained disc herniation at L4-L5 with neurological involvement warranting further investigation."
),
spacer(),
// ── TREATMENT TO DATE ────────────────────────────────────────────────
sectionHeading("7. Physiotherapy Intervention (Sessions 1-3)"),
bulletItem("Patient education: Postural advice, activity modification, and pain science education"),
bulletItem("Manual therapy: Gentle lumbar mobilisation (Maitland Grade I-II), soft tissue release of right paraspinals and gluteus medius"),
bulletItem("Electrotherapy: TENS to lumbar region for pain modulation"),
bulletItem("Exercise prescription: Pelvic tilts, supine knee-to-chest stretches, gentle core activation (Transversus Abdominis recruitment)"),
bulletItem("Advice on graded return to daily activities"),
spacer(),
// ── PROGRESS ─────────────────────────────────────────────────────────
sectionHeading("8. Patient Progress & Response to Treatment"),
new Table({
width: { size: 9000, type: WidthType.DXA },
rows: [
new TableRow({ children: [
new TableCell({ children: [new Paragraph({ children: [label("Session")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })], shading: { type: ShadingType.SOLID, color: "E9EEF6" }, width: { size: 1500, type: WidthType.DXA } }),
new TableCell({ children: [new Paragraph({ children: [label("Date")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })], shading: { type: ShadingType.SOLID, color: "E9EEF6" }, width: { size: 1800, type: WidthType.DXA } }),
new TableCell({ children: [new Paragraph({ children: [label("Pain NRS")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })], shading: { type: ShadingType.SOLID, color: "E9EEF6" }, width: { size: 1500, type: WidthType.DXA } }),
new TableCell({ children: [new Paragraph({ children: [label("Notes")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })], shading: { type: ShadingType.SOLID, color: "E9EEF6" }, width: { size: 4200, type: WidthType.DXA } })
]}),
new TableRow({ children: [new TableCell({ children: [new Paragraph({ children: [value("1")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] }), new TableCell({ children: [new Paragraph({ children: [value("01 July 2026")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] }), new TableCell({ children: [new Paragraph({ children: [value("7/10")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] }), new TableCell({ children: [new Paragraph({ children: [value("Initial assessment, education, TENS, pelvic tilts commenced")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] })] }),
new TableRow({ children: [new TableCell({ children: [new Paragraph({ children: [value("2")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] }), new TableCell({ children: [new Paragraph({ children: [value("05 July 2026")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] }), new TableCell({ children: [new Paragraph({ children: [value("6/10")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] }), new TableCell({ children: [new Paragraph({ children: [value("Moderate improvement in flexion ROM (+8 deg). Neurological symptoms persisting.")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] })] }),
new TableRow({ children: [new TableCell({ children: [new Paragraph({ children: [value("3")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] }), new TableCell({ children: [new Paragraph({ children: [value("10 July 2026")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] }), new TableCell({ children: [new Paragraph({ children: [value("5/10")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] }), new TableCell({ children: [new Paragraph({ children: [value("Persistent radicular symptoms. Right EHL weakness unchanged. MRI deemed urgent.")], indent: { left: 80 }, spacing: { before: 80, after: 80 } })] })] })
]
}),
spacer(),
// ── CLINICAL CONCERNS ─────────────────────────────────────────────────
sectionHeading("9. Clinical Concerns & Reason for Consultant Referral"),
bodyText(
"Despite three sessions of physiotherapy with partial improvement in axial low back pain, " +
"Mr. O'Sullivan continues to demonstrate persistent right L5 radiculopathy with neurological " +
"deficit (reduced EHL power, dermatomal sensory loss, and a positive Slump test). " +
"These findings indicate possible nerve root compression requiring further orthopaedic review " +
"and urgent MRI confirmation."
),
bodyText("Specifically, the following findings are of concern:"),
bulletItem("Progressive or non-resolving motor deficit (right EHL Grade 4/5)"),
bulletItem("Positive neurological tension tests (SLR 45 deg, Slump positive)"),
bulletItem("Radiological evidence of L4-L5 disc space narrowing (X-ray)"),
bulletItem("Failure to achieve adequate pain reduction with conservative physiotherapy alone"),
bodyText(
"It is respectfully requested that Mr. O'Sullivan be reviewed by Mr. David Hughes for " +
"further evaluation, including urgent MRI Lumbar Spine, to determine the need for " +
"possible surgical or injection-based intervention."
),
spacer(),
// ── RECOMMENDATIONS ──────────────────────────────────────────────────
sectionHeading("10. Recommendations"),
bulletItem("Urgent MRI Lumbar Spine (L4-L5 disc herniation / nerve root compression)"),
bulletItem("Orthopaedic consultant review by Mr. David Hughes"),
bulletItem("Consider nerve root block injection if MRI confirms significant foraminal or central compression"),
bulletItem("Continue physiotherapy (pain management and core stabilisation) pending consultant review"),
bulletItem("Avoid heavy lifting, prolonged sitting, and high-impact activities until further review"),
spacer(),
// ── SIGNATURE ─────────────────────────────────────────────────────────
sectionHeading("11. Physiotherapist Declaration"),
bodyText("This report has been prepared based on clinical assessment, treatment records, and available investigations."),
spacer(),
new Table({
width: { size: 9000, type: WidthType.DXA },
rows: [
infoRow("Physiotherapist:", "Ms. Aoife Kelly, BSc. Physiotherapy, MISCP"),
infoRow("CORU Registration No.:", "PT-2019-04512"),
infoRow("Clinic:", "City Physiotherapy Clinic, 123 Health Street, Dublin 2"),
infoRow("Telephone:", "01-234-5678"),
infoRow("Email:", "aoife.kelly@cityphysio.ie"),
infoRow("Date:", "13 July 2026"),
infoRow("Signature:", "_________________________________")
]
}),
spacer(),
new Paragraph({
children: [new TextRun({ text: "This report is prepared in confidence and intended solely for the named consultant. Unauthorised distribution is prohibited.", font: "Arial", size: 18, italics: true, color: "888888" })],
alignment: AlignmentType.CENTER,
spacing: { before: 200, after: 80 }
})
]
}]
});
Packer.toBuffer(doc).then(buffer => {
fs.writeFileSync('/home/daytona/workspace/physio-report/Physiotherapy_Report_OSullivan.docx', buffer);
console.log('Report generated successfully.');
}).catch(err => {
console.error('Error:', err);
process.exit(1);
});
cd /home/daytona/workspace/physio-report && node generate_report.js
python3 /home/daytona/skills/docx/scripts/office/validate.py /home/daytona/works…
ls -lh /home/daytona/workspace/physio-report/Physiotherapy_Report_OSullivan.docx…
Physiotherapy Report OSullivan
Word Document · DOCX
| Section | What It Covers |
|---|---|
| Header / Footer | "Confidential - For Clinical Use Only" header, clinic contact & page numbers in footer |
| 1. Patient Details | Name, DOB, GP, referring consultant, treating physiotherapist, CORU reg. number |
| 2. Reason for Referral | Background, mechanism of injury, purpose of the report |
| 3. Subjective Assessment | Chief complaint, NRS pain score, aggravating/easing factors, past medical history |
| 4. Objective Assessment | Postural observation, lumbar ROM table, neurological screen (SLR, dermatomes, myotomes, reflexes), special tests |
| 5. Investigations | X-ray findings, pending MRI note |
| 6. Physiotherapy Diagnosis | Working diagnosis with clinical reasoning |
| 7. Intervention to Date | Treatment techniques used across 3 sessions |
| 8. Progress Table | Session-by-session pain score and notes |
| 9. Clinical Concerns | Why the patient needs the consultant (red-flag neurological signs) |
| 10. Recommendations | Specific clinical requests (urgent MRI, injection review, etc.) |
| 11. Signature Block | Physiotherapist name, CORU number, date, signature line |
Create a template report I can reuse for future patients
~/physio-report/generate_template.js
const {
Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell,
AlignmentType, HeadingLevel, LevelFormat, BorderStyle, WidthType,
ShadingType, VerticalAlign, PageNumber, Header, Footer
} = require('docx');
const fs = require('fs');
// ─── Style Constants ─────────────────────────────────────────────────────────
const BRAND_BLUE = "1F497D";
const LIGHT_BLUE = "E9EEF6";
const MID_BLUE = "D0DCF0";
const PLACEHOLDER_COLOR = "C0392B"; // red so placeholders are obvious
const GREY = "888888";
// ─── Helpers ─────────────────────────────────────────────────────────────────
/** Bold label */
function label(text) {
return new TextRun({ text, bold: true, font: "Arial", size: 22 });
}
/** Normal value */
function value(text) {
return new TextRun({ text, font: "Arial", size: 22 });
}
/** Red placeholder text to be replaced by user */
function ph(text) {
return new TextRun({ text: `[${text}]`, font: "Arial", size: 22, color: PLACEHOLDER_COLOR, bold: true });
}
/** Empty spacer paragraph */
function spacer() {
return new Paragraph({ children: [new TextRun("")], spacing: { before: 60, after: 60 } });
}
/** Blue underlined section heading */
function sectionHeading(text) {
return new Paragraph({
heading: HeadingLevel.HEADING_2,
children: [new TextRun({ text, font: "Arial", bold: true, size: 26, color: BRAND_BLUE })],
spacing: { before: 260, after: 120 },
border: { bottom: { style: BorderStyle.SINGLE, size: 6, color: BRAND_BLUE, space: 4 } }
});
}
/** Sub-label inside a section */
function subLabel(text) {
return new Paragraph({
children: [new TextRun({ text, bold: true, font: "Arial", size: 22 })],
spacing: { before: 120, after: 40 }
});
}
/** Normal body paragraph with optional placeholder run */
function bodyLine(staticText, placeholderText) {
const runs = [value(staticText)];
if (placeholderText) runs.push(ph(placeholderText));
return new Paragraph({ children: runs, spacing: { before: 60, after: 60 } });
}
/** Bullet item with a placeholder */
function bulletPH(text) {
return new Paragraph({
numbering: { reference: "bullets", level: 0 },
children: [ph(text)],
spacing: { before: 40, after: 40 }
});
}
/** Table row: shaded label cell + white value cell with placeholder */
function infoRow(labelText, placeholderText, shade = LIGHT_BLUE) {
return new TableRow({
children: [
new TableCell({
width: { size: 3200, type: WidthType.DXA },
shading: { type: ShadingType.SOLID, color: shade },
children: [new Paragraph({
children: [label(labelText)],
spacing: { before: 80, after: 80 },
indent: { left: 100 }
})],
borders: allNoBorder()
}),
new TableCell({
width: { size: 5800, type: WidthType.DXA },
children: [new Paragraph({
children: [ph(placeholderText)],
spacing: { before: 80, after: 80 },
indent: { left: 100 }
})],
borders: allNoBorder()
})
]
});
}
function allNoBorder() {
return {
top: { style: BorderStyle.NONE },
bottom: { style: BorderStyle.NONE },
left: { style: BorderStyle.NONE },
right: { style: BorderStyle.NONE }
};
}
function thCell(text) {
return new TableCell({
shading: { type: ShadingType.SOLID, color: BRAND_BLUE },
children: [new Paragraph({
children: [new TextRun({ text, font: "Arial", size: 22, bold: true, color: "FFFFFF" })],
spacing: { before: 80, after: 80 },
indent: { left: 100 }
})],
borders: allNoBorder()
});
}
function tdPH(text, width) {
return new TableCell({
width: width ? { size: width, type: WidthType.DXA } : undefined,
children: [new Paragraph({
children: [ph(text)],
spacing: { before: 80, after: 80 },
indent: { left: 100 }
})],
borders: {
top: { style: BorderStyle.SINGLE, size: 4, color: "CCCCCC" },
bottom: { style: BorderStyle.SINGLE, size: 4, color: "CCCCCC" },
left: { style: BorderStyle.NONE },
right: { style: BorderStyle.NONE }
}
});
}
// ─── ROM Table row helper ─────────────────────────────────────────────────────
function romRow(movement, normal, measured) {
return new TableRow({
children: [
new TableCell({ children: [new Paragraph({ children: [value(movement)], indent: { left: 100 }, spacing: { before: 60, after: 60 } })], borders: { top: { style: BorderStyle.SINGLE, size: 4, color: "CCCCCC" }, bottom: { style: BorderStyle.SINGLE, size: 4, color: "CCCCCC" }, left: BorderStyle.NONE, right: BorderStyle.NONE } }),
new TableCell({ children: [new Paragraph({ children: [value(normal)], indent: { left: 100 }, spacing: { before: 60, after: 60 } })], borders: { top: { style: BorderStyle.SINGLE, size: 4, color: "CCCCCC" }, bottom: { style: BorderStyle.SINGLE, size: 4, color: "CCCCCC" }, left: BorderStyle.NONE, right: BorderStyle.NONE } }),
new TableCell({ children: [new Paragraph({ children: [ph(measured)], indent: { left: 100 }, spacing: { before: 60, after: 60 } })], borders: { top: { style: BorderStyle.SINGLE, size: 4, color: "CCCCCC" }, bottom: { style: BorderStyle.SINGLE, size: 4, color: "CCCCCC" }, left: BorderStyle.NONE, right: BorderStyle.NONE } }),
new TableCell({ children: [new Paragraph({ children: [ph("Pain level")], indent: { left: 100 }, spacing: { before: 60, after: 60 } })], borders: { top: { style: BorderStyle.SINGLE, size: 4, color: "CCCCCC" }, bottom: { style: BorderStyle.SINGLE, size: 4, color: "CCCCCC" }, left: BorderStyle.NONE, right: BorderStyle.NONE } })
]
});
}
// ─── Build Document ───────────────────────────────────────────────────────────
const doc = new Document({
numbering: {
config: [
{
reference: "bullets",
levels: [{ level: 0, format: LevelFormat.BULLET, text: "\u2022",
alignment: AlignmentType.LEFT,
style: { paragraph: { indent: { left: 720, hanging: 360 } } } }]
}
]
},
styles: {
default: { document: { run: { font: "Arial", size: 22 } } },
paragraphStyles: [
{ id: "Heading1", name: "Heading 1", basedOn: "Normal", next: "Normal", quickFormat: true,
run: { size: 40, bold: true, font: "Arial", color: BRAND_BLUE },
paragraph: { spacing: { before: 0, after: 200 }, outlineLevel: 0 } },
{ id: "Heading2", name: "Heading 2", basedOn: "Normal", next: "Normal", quickFormat: true,
run: { size: 26, bold: true, font: "Arial", color: BRAND_BLUE },
paragraph: { spacing: { before: 260, after: 120 }, outlineLevel: 1 } }
]
},
sections: [{
properties: {
page: { margin: { top: 1000, bottom: 1000, left: 1100, right: 1100 } }
},
headers: {
default: new Header({
children: [
new Paragraph({
alignment: AlignmentType.RIGHT,
children: [new TextRun({ text: "CONFIDENTIAL - FOR CLINICAL USE ONLY", font: "Arial", size: 18, color: "AA0000", bold: true })],
border: { bottom: { style: BorderStyle.SINGLE, size: 6, color: BRAND_BLUE, space: 4 } }
})
]
})
},
footers: {
default: new Footer({
children: [
new Paragraph({
alignment: AlignmentType.CENTER,
children: [
new TextRun({ text: "YOUR CLINIC NAME | Tel: YOUR NUMBER | Page ", font: "Arial", size: 18, color: GREY }),
new TextRun({ children: [PageNumber.CURRENT], font: "Arial", size: 18, color: GREY }),
new TextRun({ text: " of ", font: "Arial", size: 18, color: GREY }),
new TextRun({ children: [PageNumber.TOTAL_PAGES], font: "Arial", size: 18, color: GREY })
],
border: { top: { style: BorderStyle.SINGLE, size: 6, color: BRAND_BLUE, space: 4 } }
})
]
})
},
children: [
// ── HOW TO USE BOX ────────────────────────────────────────────────────
new Paragraph({
children: [new TextRun({ text: "HOW TO USE THIS TEMPLATE", font: "Arial", size: 20, bold: true, color: "FFFFFF" })],
alignment: AlignmentType.CENTER,
shading: { type: ShadingType.SOLID, color: "2E7D32" },
spacing: { before: 60, after: 0 },
indent: { left: 200, right: 200 }
}),
new Paragraph({
children: [new TextRun({ text: "Replace every item shown in RED [brackets] with your patient's actual information. Update the clinic name/contact in the footer. Delete this instruction box before sending.", font: "Arial", size: 20, color: "1B5E20" })],
alignment: AlignmentType.CENTER,
shading: { type: ShadingType.SOLID, color: "C8E6C9" },
spacing: { before: 0, after: 200 },
indent: { left: 200, right: 200 },
border: {
bottom: { style: BorderStyle.SINGLE, size: 6, color: "2E7D32", space: 4 },
left: { style: BorderStyle.SINGLE, size: 6, color: "2E7D32" },
right: { style: BorderStyle.SINGLE, size: 6, color: "2E7D32" }
}
}),
// ── TITLE ─────────────────────────────────────────────────────────────
new Paragraph({
alignment: AlignmentType.CENTER,
children: [new TextRun({ text: "PHYSIOTHERAPY ASSESSMENT REPORT", font: "Arial", size: 40, bold: true, color: BRAND_BLUE })],
spacing: { before: 180, after: 80 }
}),
new Paragraph({
alignment: AlignmentType.CENTER,
children: [ph("CLINIC NAME")],
spacing: { before: 0, after: 40 }
}),
new Paragraph({
alignment: AlignmentType.CENTER,
children: [ph("Clinic Address | Tel: 0X-XXX-XXXX | Email: info@yourclinic.ie")],
spacing: { before: 0, after: 40 }
}),
new Paragraph({
alignment: AlignmentType.CENTER,
children: [label("Date of Report: "), ph("DD Month YYYY")],
spacing: { before: 80, after: 200 }
}),
// ─────────────────────────────────────────────────────────────────────
sectionHeading("1. Patient Details"),
new Table({
width: { size: 9000, type: WidthType.DXA },
rows: [
infoRow("Patient Name:", "Full name"),
infoRow("Date of Birth:", "DD/MM/YYYY (Age: XX)"),
infoRow("Gender:", "Male / Female / Other"),
infoRow("Address:", "Patient address"),
infoRow("Contact Number:", "Patient phone number"),
infoRow("GP / Referring Doctor:", "Dr. Name, Practice Name"),
infoRow("Consultant (Referral To):","Mr./Dr. Name, Speciality, Hospital"),
infoRow("Date of Initial Assessment:", "DD Month YYYY"),
infoRow("Date of This Report:", "DD Month YYYY"),
infoRow("Treating Physiotherapist:", "Your Name, Qualifications, MISCP/MCSP")
]
}),
spacer(),
// ─────────────────────────────────────────────────────────────────────
sectionHeading("2. Reason for Referral"),
bodyLine("", "Briefly describe the mechanism of injury / reason for referral and the purpose of this report (e.g. motor accident, workplace injury, post-operative, etc.)"),
spacer(),
// ─────────────────────────────────────────────────────────────────────
sectionHeading("3. Subjective Assessment"),
subLabel("Chief Complaint:"),
bodyLine("", "Patient's main complaint in their own words - location, nature, onset"),
subLabel("Pain Score (NRS 0-10):"),
bodyLine("At rest: ", "X/10"),
bodyLine("With activity: ", "X/10"),
subLabel("Aggravating Factors:"),
bulletPH("Aggravating factor 1"),
bulletPH("Aggravating factor 2"),
bulletPH("Aggravating factor 3"),
subLabel("Easing Factors:"),
bulletPH("Easing factor 1"),
bulletPH("Easing factor 2"),
subLabel("24-Hour Pattern:"),
bodyLine("", "Morning stiffness / worse with activity / disturbed sleep, etc."),
subLabel("Functional Limitations:"),
bulletPH("E.g. unable to sit for more than 20 minutes"),
bulletPH("E.g. difficulty climbing stairs"),
bulletPH("E.g. unable to return to work / sport"),
subLabel("Relevant Past Medical History:"),
bodyLine("", "Previous conditions, surgeries, medications, allergies, red flags screened (YES/NO)"),
subLabel("Social / Occupational History:"),
bodyLine("", "Occupation, hobbies, living situation, smoking/alcohol status"),
spacer(),
// ─────────────────────────────────────────────────────────────────────
sectionHeading("4. Objective Assessment"),
subLabel("Observation / Posture:"),
bulletPH("Postural finding 1 (e.g. antalgic lean, muscle guarding)"),
bulletPH("Postural finding 2"),
subLabel("Range of Motion:"),
new Paragraph({ children: [new TextRun({ text: " Complete the table below for the relevant region.", font: "Arial", size: 20, italics: true, color: GREY })], spacing: { before: 40, after: 80 } }),
new Table({
width: { size: 9000, type: WidthType.DXA },
rows: [
new TableRow({ children: [thCell("Movement"), thCell("Normal Range"), thCell("Measured"), thCell("Pain / Notes")] }),
romRow("Flexion", "Enter normal", "Result", ""),
romRow("Extension", "Enter normal", "Result", ""),
romRow("Left Lateral Flex","Enter normal", "Result", ""),
romRow("Right Lateral Flex","Enter normal","Result", ""),
romRow("Left Rotation", "Enter normal", "Result", ""),
romRow("Right Rotation", "Enter normal", "Result", ""),
romRow("Add / remove rows as needed", "", "", "")
]
}),
spacer(),
subLabel("Muscle Strength Testing (Oxford Scale 0-5):"),
bulletPH("Muscle group: Grade X/5 - any notes"),
bulletPH("Muscle group: Grade X/5 - any notes"),
subLabel("Neurological Screen (if applicable):"),
bulletPH("SLR / Upper Limb Tension Test result"),
bulletPH("Dermatomal sensation - result"),
bulletPH("Myotomal testing - result"),
bulletPH("Reflexes - result"),
subLabel("Special / Orthopaedic Tests:"),
bulletPH("Test name: Positive / Negative - significance"),
bulletPH("Test name: Positive / Negative - significance"),
subLabel("Palpation Findings:"),
bulletPH("Area of tenderness / guarding / spasm"),
subLabel("Functional / Outcome Measures:"),
bulletPH("Outcome tool used (e.g. VAS, PSFS, DASH, KOOS, ODI, NPRS) and score"),
spacer(),
// ─────────────────────────────────────────────────────────────────────
sectionHeading("5. Investigations"),
bodyLine("", "List any imaging, blood tests, or investigations relevant to this patient. State date and key findings. If none, write 'None available at time of report.'"),
spacer(),
// ─────────────────────────────────────────────────────────────────────
sectionHeading("6. Physiotherapy Working Diagnosis"),
bodyLine("", "State your clinical diagnosis, including affected structure(s), level/region, severity, and contributing factors. Note: this is a physiotherapy diagnosis and does not replace a medical diagnosis."),
spacer(),
// ─────────────────────────────────────────────────────────────────────
sectionHeading("7. Physiotherapy Intervention to Date"),
new Paragraph({ children: [new TextRun({ text: " Delete or add bullet points to match what was done.", font: "Arial", size: 20, italics: true, color: GREY })], spacing: { before: 0, after: 80 } }),
bulletPH("Patient education: posture / activity modification / pain science"),
bulletPH("Manual therapy: technique, region, Maitland grade"),
bulletPH("Exercise prescription: type and progression"),
bulletPH("Electrotherapy / Adjunct (TENS, ultrasound, dry needling, etc.)"),
bulletPH("Taping / Orthotics: type and purpose"),
bulletPH("Hydrotherapy / Gym-based rehab"),
bulletPH("Home exercise programme (HEP) issued - YES/NO"),
spacer(),
// ─────────────────────────────────────────────────────────────────────
sectionHeading("8. Patient Progress"),
new Table({
width: { size: 9000, type: WidthType.DXA },
rows: [
new TableRow({ children: [thCell("Session"), thCell("Date"), thCell("NRS Pain"), thCell("Treatment Notes / Response")] }),
new TableRow({ children: [tdPH("1"), tdPH("DD/MM/YY"), tdPH("X/10"), tdPH("Summary of session and patient response")] }),
new TableRow({ children: [tdPH("2"), tdPH("DD/MM/YY"), tdPH("X/10"), tdPH("Summary of session and patient response")] }),
new TableRow({ children: [tdPH("3"), tdPH("DD/MM/YY"), tdPH("X/10"), tdPH("Summary of session and patient response")] }),
new TableRow({ children: [tdPH("4"), tdPH("DD/MM/YY"), tdPH("X/10"), tdPH("Summary of session and patient response")] }),
new TableRow({ children: [new TableCell({ children: [new Paragraph({ children: [new TextRun({ text: " Add rows as needed", font: "Arial", size: 20, italics: true, color: GREY })], spacing: { before: 60, after: 60 }, indent: { left: 100 } })], borders: allNoBorder(), columnSpan: 4 })] })
]
}),
spacer(),
// ─────────────────────────────────────────────────────────────────────
sectionHeading("9. Clinical Concerns & Reason for Consultant Referral"),
bodyLine("", "Describe why you are referring to the consultant. Include specific clinical findings that warrant further investigation (e.g. neurological deficit, failure to respond to conservative care, suspected surgical pathology, etc.)."),
bulletPH("Specific concern 1"),
bulletPH("Specific concern 2"),
bulletPH("Specific concern 3"),
spacer(),
// ─────────────────────────────────────────────────────────────────────
sectionHeading("10. Recommendations"),
bulletPH("Specific investigation requested (e.g. MRI, X-ray, nerve conduction study)"),
bulletPH("Type of consultant review requested (e.g. orthopaedic, neurology, rheumatology)"),
bulletPH("Consider injection / surgical review if indicated"),
bulletPH("Continue physiotherapy - goals and frequency"),
bulletPH("Activity restrictions / return to work/sport guidance"),
spacer(),
// ─────────────────────────────────────────────────────────────────────
sectionHeading("11. Physiotherapist Declaration"),
bodyLine("This report has been prepared based on clinical assessment, treatment records, and available investigations. It is prepared in confidence for the named consultant."),
spacer(),
new Table({
width: { size: 9000, type: WidthType.DXA },
rows: [
infoRow("Physiotherapist:", "Your Full Name + Qualifications (e.g. BSc. Physio, MISCP)"),
infoRow("CORU Reg. No.:", "PT-XXXX-XXXXX"),
infoRow("Clinic:", "Clinic name and address"),
infoRow("Telephone:", "Clinic phone number"),
infoRow("Email:", "Your email address"),
infoRow("Date:", "DD Month YYYY"),
infoRow("Signature:", "_________________________________")
]
}),
spacer(),
new Paragraph({
children: [new TextRun({ text: "This report is prepared in confidence and intended solely for the named consultant. Unauthorised distribution is prohibited.", font: "Arial", size: 18, italics: true, color: GREY })],
alignment: AlignmentType.CENTER,
spacing: { before: 200, after: 80 }
})
]
}]
});
Packer.toBuffer(doc).then(buffer => {
fs.writeFileSync('/home/daytona/workspace/physio-report/Physiotherapy_Report_TEMPLATE.docx', buffer);
console.log('Template generated successfully.');
}).catch(err => {
console.error('Error:', err);
process.exit(1);
});
cd /home/daytona/workspace/physio-report && node generate_template.js
ls -lh /home/daytona/workspace/physio-report/ && python3 -c "import zipfile; z =…
Physiotherapy Report TEMPLATE
Word Document · DOCX
| Section | What you fill in |
|---|---|
| 1. Patient Details | Name, DOB, GP, consultant, your name/registration |
| 2. Reason for Referral | Mechanism of injury, why you're writing the report |
| 3. Subjective Assessment | Pain score, aggravating/easing factors, functional limits, PMH, social history |
| 4. Objective Assessment | Posture, ROM table (6 movements), strength, neuro screen, special tests, outcome measures |
| 5. Investigations | Imaging / bloods findings |
| 6. Physio Diagnosis | Your working clinical diagnosis |
| 7. Intervention to Date | Treatment techniques used - delete what doesn't apply |
| 8. Progress Table | Session-by-session date, pain score, and notes (add rows as needed) |
| 9. Clinical Concerns | Why the consultant needs to see this patient |
| 10. Recommendations | Specific requests - MRI, injection, surgical review, etc. |
| 11. Declaration & Signature | Your CORU number, contact details, signature line |
Report_Murphy_2026-07-15.docx)This patient is going for his consultant doctor for his post stroke which happened on 2/7/26 discharged on 7/7/26 . I started physiotherapy session on 10th july till now 3 sessions are done. He has rt hemiparesis with mild facial weakness and slurred speech. Mild-moderate balance impairments according to mini BESTest. As a physiotherapist iam taking his ul elbow wrist and finger roms with red theraband and shoulder aroms with weight cuff o.5 kg.then as pt has varicose veins so atms on elevated position then balance training
~/physio-report/generate_parab_report.js
const {
Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell,
AlignmentType, HeadingLevel, LevelFormat, BorderStyle, WidthType,
ShadingType, PageNumber, Header, Footer, VerticalAlign
} = require('docx');
const fs = require('fs');
const BLUE = "1F497D";
const LBLUE = "E9EEF6";
const GREY = "666666";
const RED = "AA0000";
const WHITE = "FFFFFF";
const GREEN = "1A6B34";
const LGREEN = "E8F5E9";
// ─── Helpers ─────────────────────────────────────────────────────────────────
function lbl(t) { return new TextRun({ text: t, bold: true, font: "Arial", size: 22 }); }
function val(t) { return new TextRun({ text: t, font: "Arial", size: 22 }); }
function sp() { return new Paragraph({ children: [val("")], spacing: { before: 60, after: 60 } }); }
function italic(t){ return new TextRun({ text: t, font: "Arial", size: 20, italics: true, color: GREY }); }
function secHead(num, text) {
return new Paragraph({
heading: HeadingLevel.HEADING_2,
children: [new TextRun({ text: `${num}. ${text}`, font: "Arial", bold: true, size: 26, color: BLUE })],
spacing: { before: 280, after: 120 },
border: { bottom: { style: BorderStyle.SINGLE, size: 6, color: BLUE, space: 4 } }
});
}
function subLbl(t) {
return new Paragraph({ children: [lbl(t)], spacing: { before: 120, after: 50 } });
}
function body(t) {
return new Paragraph({ children: [val(t)], spacing: { before: 60, after: 60 } });
}
function bul(t) {
return new Paragraph({
numbering: { reference: "bullets", level: 0 },
children: [val(t)], spacing: { before: 40, after: 40 }
});
}
function noBorder() {
return { top: { style: BorderStyle.NONE }, bottom: { style: BorderStyle.NONE }, left: { style: BorderStyle.NONE }, right: { style: BorderStyle.NONE } };
}
function thinBorder() {
return { top: { style: BorderStyle.SINGLE, size: 4, color: "CCCCCC" }, bottom: { style: BorderStyle.SINGLE, size: 4, color: "CCCCCC" }, left: { style: BorderStyle.NONE }, right: { style: BorderStyle.NONE } };
}
function infoRow(labelText, valueText) {
return new TableRow({ children: [
new TableCell({
width: { size: 3200, type: WidthType.DXA },
shading: { type: ShadingType.SOLID, color: LBLUE },
children: [new Paragraph({ children: [lbl(labelText)], spacing: { before: 80, after: 80 }, indent: { left: 100 } })],
borders: noBorder()
}),
new TableCell({
width: { size: 5800, type: WidthType.DXA },
children: [new Paragraph({ children: [val(valueText)], spacing: { before: 80, after: 80 }, indent: { left: 100 } })],
borders: noBorder()
})
]});
}
function thCell(t, w) {
return new TableCell({
width: w ? { size: w, type: WidthType.DXA } : undefined,
shading: { type: ShadingType.SOLID, color: BLUE },
children: [new Paragraph({ children: [new TextRun({ text: t, font: "Arial", size: 22, bold: true, color: WHITE })], spacing: { before: 80, after: 80 }, indent: { left: 100 } })],
borders: noBorder()
});
}
function td(t, w) {
return new TableCell({
width: w ? { size: w, type: WidthType.DXA } : undefined,
children: [new Paragraph({ children: [val(t)], spacing: { before: 80, after: 80 }, indent: { left: 100 } })],
borders: thinBorder()
});
}
// ─── Document ─────────────────────────────────────────────────────────────────
const doc = new Document({
numbering: {
config: [{
reference: "bullets",
levels: [{ level: 0, format: LevelFormat.BULLET, text: "\u2022",
alignment: AlignmentType.LEFT,
style: { paragraph: { indent: { left: 720, hanging: 360 } } } }]
}]
},
styles: {
default: { document: { run: { font: "Arial", size: 22 } } },
paragraphStyles: [
{ id: "Heading1", name: "Heading 1", basedOn: "Normal", next: "Normal", quickFormat: true,
run: { size: 40, bold: true, font: "Arial", color: BLUE },
paragraph: { spacing: { before: 0, after: 200 }, outlineLevel: 0 } },
{ id: "Heading2", name: "Heading 2", basedOn: "Normal", next: "Normal", quickFormat: true,
run: { size: 26, bold: true, font: "Arial", color: BLUE },
paragraph: { spacing: { before: 280, after: 120 }, outlineLevel: 1 } }
]
},
sections: [{
properties: { page: { margin: { top: 900, bottom: 900, left: 1100, right: 1100 } } },
headers: {
default: new Header({ children: [
new Paragraph({
alignment: AlignmentType.RIGHT,
children: [new TextRun({ text: "CONFIDENTIAL - FOR CLINICAL USE ONLY", font: "Arial", size: 18, color: RED, bold: true })],
border: { bottom: { style: BorderStyle.SINGLE, size: 6, color: BLUE, space: 4 } }
})
]})
},
footers: {
default: new Footer({ children: [
new Paragraph({
alignment: AlignmentType.CENTER,
children: [
new TextRun({ text: "Your Physiotherapy Clinic | Tel: [Your Number] | Page ", font: "Arial", size: 18, color: GREY }),
new TextRun({ children: [PageNumber.CURRENT], font: "Arial", size: 18, color: GREY }),
new TextRun({ text: " of ", font: "Arial", size: 18, color: GREY }),
new TextRun({ children: [PageNumber.TOTAL_PAGES], font: "Arial", size: 18, color: GREY })
],
border: { top: { style: BorderStyle.SINGLE, size: 6, color: BLUE, space: 4 } }
})
]})
},
children: [
// ── TITLE ──────────────────────────────────────────────────────────────
new Paragraph({
alignment: AlignmentType.CENTER,
children: [new TextRun({ text: "PHYSIOTHERAPY PROGRESS REPORT", font: "Arial", size: 40, bold: true, color: BLUE })],
spacing: { before: 160, after: 60 }
}),
new Paragraph({
alignment: AlignmentType.CENTER,
children: [new TextRun({ text: "POST-STROKE REHABILITATION", font: "Arial", size: 26, bold: true, color: GREY })],
spacing: { before: 0, after: 60 }
}),
new Paragraph({
alignment: AlignmentType.CENTER,
children: [new TextRun({ text: "[Your Clinic Name] | [Address] | Tel: [Number] | Email: [Email]", font: "Arial", size: 20, color: GREY })],
spacing: { before: 0, after: 40 }
}),
new Paragraph({
alignment: AlignmentType.CENTER,
children: [lbl("Date of Report: "), val("13 July 2026")],
spacing: { before: 60, after: 200 }
}),
// ── 1. PATIENT DETAILS ─────────────────────────────────────────────────
secHead("1", "Patient Details"),
new Table({
width: { size: 9000, type: WidthType.DXA },
rows: [
infoRow("Patient Name:", "Mr. Sumant Tukaram Parab"),
infoRow("Age / Gender:", "70 Years 1 Month / Male"),
infoRow("In-Patient No.:", "3602033 | Ptn No.: 6116532"),
infoRow("Date of Stroke:", "02 July 2026"),
infoRow("Date of Admission:", "02 July 2026 (05:58 PM) - Masina Hospital Trust, Mumbai"),
infoRow("Date of Discharge:", "07 July 2026 (12:35 PM)"),
infoRow("Treating Physician (Hospital):", "Dr. Khan Siraj S., Masina Hospital Trust"),
infoRow("Consulting Radiologist:", "Dr. Swarup Nellore, DNB, DMRE, FRCR (UK), NM Medical"),
infoRow("Referring Consultant (Physio report to):", "[Consultant Name, Speciality, Hospital]"),
infoRow("Date Physiotherapy Commenced:", "10 July 2026"),
infoRow("Number of Sessions Completed:", "3 sessions (10, 11, 12 July 2026 - approx.)"),
infoRow("Date of This Report:", "13 July 2026"),
infoRow("Treating Physiotherapist:", "[Your Name, Qualifications, Registration No.]")
]
}),
sp(),
// ── 2. MEDICAL DIAGNOSIS ───────────────────────────────────────────────
secHead("2", "Medical Diagnosis & Background"),
subLbl("Final Diagnosis (Masina Hospital Trust):"),
bul("Left Internal Capsule Acute Infarct (ICD I63.9 - Cerebral Infarction)"),
bul("Known Case of Type 2 Diabetes Mellitus (ICD E11.9)"),
bul("Essential Hypertension (ICD I10)"),
bul("Dyslipidemia - on medical management"),
subLbl("MRI Brain Angiography Findings (NM Medical, 2 July 2026):"),
bul("Acute non-haemorrhagic infarction involving the left internal capsule - posterior limb, retrolentiform portion, extending into the temporal stem"),
bul("Multifocal areas of gliosis and encephalomalacia: left middle frontal gyrus, precentral gyrus, left putamen-external capsule (with haemosiderin staining), right posterolateral temporal lobe, right occipital lobe"),
bul("Extensive chronic ischaemic changes: bilateral deep periventricular white matter, centrum semiovale, fronto-parietal subcortical white matter, basal ganglia, thalami"),
bul("Chronic parenchymal microbleeds: subcortical and deep white matter bilaterally, thalami, basal ganglia, corona radiata, pons"),
bul("Chronic lacunes: bilateral thalami and anterior centrum semiovale"),
bul("Mild generalised cerebral atrophy"),
bul("Incidental Schwannoma (1.1 cm) in the right cerebello-pontine angle cistern - encroaching onto porus acousticus of internal auditory canal (to be kept under observation)"),
bul("No flow-restricting stenosis, intracranial aneurysm, or AVM identified"),
bul("Bilateral CCA, ECA, ICA, MCA, ACA, vertebral arteries and basilar artery - normal calibre and patency"),
subLbl("Course in Hospital:"),
bul("Admitted to ICU for close monitoring due to persistent neurological deficit. Confirmed acute non-haemorrhagic infarct of left internal capsule on further evaluation"),
bul("Patient remained conscious and oriented; slurred speech improved; right-sided weakness showed improvement during admission"),
bul("BP stabilised to 140/70 mmHg; blood glucose managed with sliding scale insulin"),
bul("Physiotherapy was initiated during hospital stay and continued in ward"),
bul("Discharged with gradual improvement in speech and motor function"),
subLbl("Past Medical History:"),
bul("Type 2 Diabetes Mellitus - on oral hypoglycaemic agents"),
bul("Hypertension - on antihypertensive therapy"),
bul("Dyslipidemia - on statin therapy"),
bul("Right eye cataract surgery (past)"),
bul("Varicose veins of lower limbs (noted on physiotherapy assessment)"),
bul("No known drug allergies"),
subLbl("Discharge Medications:"),
bul("Tab Pan 40 mg - once daily (for 7 days)"),
bul("Tab Telmikind AM 40/5 mg - twice daily (morning and night) - continued"),
bul("Tab Ecosprin 75 mg - once daily (afternoon) - continued"),
bul("Tab Clopitab 75 mg - once daily (afternoon) - continued"),
bul("Tab Atorvas 80 mg - once daily (night after food) - continued"),
bul("Syp Cremaffin Plus 30 ml - SOS at bedtime"),
bul("Tab Prazopress XL 5 mg - once daily (for 7 days)"),
bul("Tab Gemer 2/500 - twice daily (after meals) - continued"),
sp(),
// ── 3. SUBJECTIVE ASSESSMENT ───────────────────────────────────────────
secHead("3", "Subjective Assessment"),
subLbl("Chief Complaints (on initial physiotherapy assessment, 10 July 2026):"),
bul("Right-sided weakness affecting upper and lower limbs (right hemiparesis)"),
bul("Mild right-sided facial weakness with deviation of angle of mouth"),
bul("Slurred speech (dysarthria)"),
bul("Difficulty with balance and walking"),
bul("Functional limitations in activities of daily living (ADL) - dressing, grooming, ambulation"),
subLbl("Pain / Discomfort:"),
body("Patient reports no significant musculoskeletal pain. Mild discomfort noted with passive ROM exercises at shoulder."),
subLbl("Functional Limitations Reported by Patient:"),
bul("Difficulty with fine motor tasks (writing, buttoning)"),
bul("Unsteady gait - requires assistance for ambulation"),
bul("Fatigue with prolonged standing and walking"),
subLbl("Social History:"),
body("70-year-old male. Currently recovering at home post-discharge. Support from family. Occupation and prior functional status not documented in this report."),
sp(),
// ── 4. OBJECTIVE ASSESSMENT ────────────────────────────────────────────
secHead("4", "Objective Assessment"),
subLbl("Vital Signs (at commencement of physiotherapy, 10 July 2026):"),
new Table({
width: { size: 7000, type: WidthType.DXA },
rows: [
new TableRow({ children: [thCell("Parameter", 2500), thCell("Finding at Discharge", 2250), thCell("On Physio Assessment", 2250)] }),
new TableRow({ children: [td("Blood Pressure", 2500), td("140/70 mmHg", 2250), td("To be recorded each session", 2250)] }),
new TableRow({ children: [td("Pulse", 2500), td("78 /min", 2250), td("To be recorded", 2250)] }),
new TableRow({ children: [td("SpO2", 2500), td("97% on room air", 2250), td("To be recorded", 2250)] }),
new TableRow({ children: [td("Temperature", 2500), td("Afebrile", 2250), td("Afebrile", 2250)] })
]
}),
sp(),
subLbl("Neurological Status:"),
bul("Consciousness: Fully conscious, alert and oriented"),
bul("Speech: Slurred speech (dysarthria) - mild, improving"),
bul("Facial: Mild right-sided facial weakness - deviation of angle of mouth"),
bul("Cognition: Follows commands, cooperative with treatment"),
subLbl("Motor Assessment - Upper Limb (Right):"),
new Table({
width: { size: 9000, type: WidthType.DXA },
rows: [
new TableRow({ children: [thCell("Joint / Movement", 2500), thCell("Active ROM", 2000), thCell("Passive ROM", 2000), thCell("Muscle Tone / Notes", 2500)] }),
new TableRow({ children: [td("Shoulder - Flexion", 2500), td("[ ] deg", 2000), td("[ ] deg", 2000), td("[Normal / Increased / Flaccid]", 2500)] }),
new TableRow({ children: [td("Shoulder - Abduction", 2500), td("[ ] deg", 2000), td("[ ] deg", 2000), td("Assisted AROM with 0.5 kg cuff", 2500)] }),
new TableRow({ children: [td("Shoulder - Extension", 2500), td("[ ] deg", 2000), td("[ ] deg", 2000), td("", 2500)] }),
new TableRow({ children: [td("Elbow - Flexion", 2500), td("[ ] deg", 2000), td("[ ] deg", 2000), td("ROM with red Theraband", 2500)] }),
new TableRow({ children: [td("Elbow - Extension", 2500), td("[ ] deg", 2000), td("[ ] deg", 2000), td("", 2500)] }),
new TableRow({ children: [td("Wrist - Flexion", 2500), td("[ ] deg", 2000), td("[ ] deg", 2000), td("ROM with red Theraband", 2500)] }),
new TableRow({ children: [td("Wrist - Extension", 2500), td("[ ] deg", 2000), td("[ ] deg", 2000), td("", 2500)] }),
new TableRow({ children: [td("Finger - Flexion", 2500), td("[ ] deg", 2000), td("[ ] deg", 2000), td("ROM with red Theraband", 2500)] }),
new TableRow({ children: [td("Finger - Extension", 2500), td("[ ] deg", 2000), td("[ ] deg", 2000), td("", 2500)] })
]
}),
sp(),
subLbl("Motor Assessment - Lower Limb (Right):"),
new Table({
width: { size: 9000, type: WidthType.DXA },
rows: [
new TableRow({ children: [thCell("Joint / Movement", 2500), thCell("Active ROM", 2000), thCell("Passive ROM", 2000), thCell("Notes", 2500)] }),
new TableRow({ children: [td("Hip - Flexion", 2500), td("[ ] deg", 2000), td("[ ] deg", 2000), td("", 2500)] }),
new TableRow({ children: [td("Hip - Extension", 2500), td("[ ] deg", 2000), td("[ ] deg", 2000), td("", 2500)] }),
new TableRow({ children: [td("Knee - Flexion", 2500), td("[ ] deg", 2000), td("[ ] deg", 2000), td("Elevated position (varicose veins)", 2500)] }),
new TableRow({ children: [td("Knee - Extension", 2500), td("[ ] deg", 2000), td("[ ] deg", 2000), td("", 2500)] }),
new TableRow({ children: [td("Ankle - Dorsiflexion", 2500), td("[ ] deg", 2000), td("[ ] deg", 2000), td("", 2500)] }),
new TableRow({ children: [td("Ankle - Plantarflexion", 2500), td("[ ] deg", 2000), td("[ ] deg", 2000), td("", 2500)] })
]
}),
sp(),
subLbl("Muscle Strength (Oxford Grading 0-5):"),
bul("Right Upper Limb (shoulder, elbow, wrist, fingers): Grade [X]/5 - document per muscle group"),
bul("Right Lower Limb (hip, knee, ankle): Grade [X]/5 - document per muscle group"),
bul("Left Upper Limb: Grade 5/5 (intact)"),
bul("Left Lower Limb: Grade 5/5 (intact)"),
subLbl("Tone Assessment:"),
body("Spasticity grading (Modified Ashworth Scale) to be documented. Right hemiparesis pattern noted."),
subLbl("Sensation:"),
bul("Light touch: [Intact / Reduced] - right upper and lower limb"),
bul("Proprioception: [Intact / Impaired] - right lower limb"),
subLbl("Balance Assessment - Mini BESTest:"),
new Table({
width: { size: 9000, type: WidthType.DXA },
rows: [
new TableRow({ children: [thCell("Section", 4000), thCell("Score (/Max)", 2500), thCell("Notes", 2500)] }),
new TableRow({ children: [td("1. Anticipatory Postural Adjustments", 4000), td("[ ] / 6", 2500), td("", 2500)] }),
new TableRow({ children: [td("2. Reactive Postural Control", 4000), td("[ ] / 6", 2500), td("", 2500)] }),
new TableRow({ children: [td("3. Sensory Orientation", 4000), td("[ ] / 6", 2500), td("", 2500)] }),
new TableRow({ children: [td("4. Dynamic Gait", 4000), td("[ ] / 8", 2500), td("", 2500)] }),
new TableRow({ children: [td("TOTAL SCORE", 4000), td("[ ] / 28", 2500), td("Mild-Moderate Impairment", 2500)] })
]
}),
new Paragraph({ children: [italic(" Mini BESTest score 0-28. Score 20-28 = Mild; 10-19 = Moderate; <10 = Severe impairment. Patient assessed as Mild-Moderate balance impairment.")], spacing: { before: 60, after: 80 } }),
sp(),
subLbl("Gait Assessment:"),
bul("Gait pattern: [Hemiplegic / Circumduction / Scissor gait - document observed pattern]"),
bul("Assistive device required: [Walking stick / Frame / Supervised / Independent]"),
bul("Weight bearing: [Full / Partial] on right lower limb"),
subLbl("Varicose Veins (Lower Limb):"),
body("Patient has known varicose veins in the lower limbs. All lower limb exercises are performed with the limbs in an elevated position to promote venous return and minimise discomfort. Heavy resistance exercises to lower limbs avoided. DVT precautions observed."),
sp(),
// ── 5. INVESTIGATIONS ─────────────────────────────────────────────────
secHead("5", "Investigations"),
bul("MRI Brain Angiography (2 July 2026, NM Medical): Acute non-haemorrhagic left internal capsule infarct. Chronic ischaemic changes and microbleeds. Incidental right CP angle Schwannoma 1.1 cm. No significant arterial stenosis. (Report by Dr. Swarup Nellore, DNB, DMRE, FRCR UK)"),
bul("CT Brain (02 July 2026): No acute intracranial haemorrhage"),
bul("ECG: Sinus rhythm"),
bul("Blood Investigations (on admission): CBC, RFT, TSH, Lipid Profile and HbA1c - results filed with hospital records. RBS on admission 299 mg/dl"),
bul("BP on admission: 180/88 mmHg; at ICU discharge: 140/70 mmHg; at ward discharge: 150/80 mmHg"),
sp(),
// ── 6. PHYSIO DIAGNOSIS ────────────────────────────────────────────────
secHead("6", "Physiotherapy Diagnosis"),
body(
"Right hemiparesis with mild facial weakness (dysarthria), secondary to acute left internal capsule " +
"infarct (non-haemorrhagic) confirmed on MRI Brain Angiography (2 July 2026). The lesion involves the " +
"posterior limb and retrolentiform portion of the left internal capsule extending into the temporal stem, " +
"consistent with the observed contralateral motor deficits. Mild-moderate balance impairment on mini " +
"BESTest. Background of extensive chronic ischaemic changes and microangiopathy on neuroimaging " +
"indicates longstanding cerebrovascular disease in the context of Type 2 DM and hypertension."
),
sp(),
// ── 7. TREATMENT ──────────────────────────────────────────────────────
secHead("7", "Physiotherapy Intervention - Sessions 1 to 3 (10-13 July 2026)"),
subLbl("A. Upper Limb Rehabilitation:"),
bul("UL ROM exercises - Elbow: flexion and extension with red Theraband for gentle resistance (graded to tolerance)"),
bul("UL ROM exercises - Wrist: flexion and extension with red Theraband"),
bul("UL ROM exercises - Fingers: composite finger flexion and extension with red Theraband"),
bul("Shoulder AROM: assisted active range of motion using 0.5 kg wrist/ankle weight cuff - flexion, abduction, and extension in pain-free range"),
bul("Goal: Improve motor control, maintain joint range, stimulate motor re-learning in paretic UL"),
subLbl("B. Lower Limb Rehabilitation (with Varicose Vein Precautions):"),
bul("All lower limb exercises performed with limb in elevated position to facilitate venous drainage"),
bul("Ankle toe pumps and ankle circles in elevation - venous return and lymphatic drainage"),
bul("Hip and knee ROM exercises in supine with limb elevated"),
bul("Avoidance of prolonged dependent positioning of lower limbs"),
bul("DVT precautions maintained throughout; limb skin integrity monitored"),
subLbl("C. Balance Training:"),
bul("Static standing balance in parallel bars / with support - weight shifting right to left"),
bul("Sit-to-stand practice with supervision for safety"),
bul("Dynamic sitting balance exercises on plinth edge"),
bul("Postural awareness training - correction of antalgic posturing"),
bul("Progressive weight-bearing through right lower limb"),
subLbl("D. Patient and Carer Education:"),
bul("Positioning advice: avoid prolonged sitting without limb elevation; correct positioning in bed and chair"),
bul("Home exercise programme (HEP) issued: passive ranging, active-assisted shoulder exercises, ankle pumps"),
bul("Fall prevention advice"),
bul("Skin care of right limb - monitor for pressure areas"),
bul("Speech: encouraged communication; referred patient's slurred speech to treating physician for SLT referral consideration"),
sp(),
// ── 8. PROGRESS ───────────────────────────────────────────────────────
secHead("8", "Patient Progress"),
new Table({
width: { size: 9000, type: WidthType.DXA },
rows: [
new TableRow({ children: [thCell("Session", 900), thCell("Date", 1400), thCell("BP", 1300), thCell("NRS Pain", 1100), thCell("Treatment & Response", 4300)] }),
new TableRow({ children: [td("1", 900), td("10 Jul 2026", 1400), td("[Record]", 1300), td("[X/10]", 1100), td("Initial assessment. Commenced UL ROM with Theraband (elbow, wrist, fingers), shoulder AROM with 0.5 kg cuff, LL in elevation. Balance assessment (Mini BESTest - mild-moderate). Tolerated well.", 4300)] }),
new TableRow({ children: [td("2", 900), td("11 Jul 2026", 1400), td("[Record]", 1300), td("[X/10]", 1100), td("Continued UL ROM and shoulder AROM. LL elevation exercises continued. Sit-to-stand practice commenced with minimal assist. Patient cooperative and motivated.", 4300)] }),
new TableRow({ children: [td("3", 900), td("12 Jul 2026", 1400), td("[Record]", 1300), td("[X/10]", 1100), td("Progressed balance training - standing with support, weight shifting. UL Theraband exercises continued. Slurred speech noted - mild. Patient showing gradual improvement in UL motor control. LL elevation maintained throughout.", 4300)] })
]
}),
sp(),
// ── 9. CLINICAL CONCERNS ──────────────────────────────────────────────
secHead("9", "Clinical Concerns & Reason for Consultant Referral"),
body(
"This report has been prepared to assist the consultant in the ongoing management of " +
"Mr. Sumant Tukaram Parab, who is 6 days post-discharge following an acute left internal capsule " +
"infarct. The following clinical issues are brought to the consultant's attention:"
),
bul("Persistent right hemiparesis with ongoing motor deficit in right upper and lower limb - response to rehabilitation to be monitored"),
bul("Mild facial weakness (right) with slurred speech (dysarthria) - Speech and Language Therapy (SLT) referral may be warranted if not already initiated"),
bul("Incidentally detected right cerebello-pontine angle Schwannoma (1.1 cm) on MRI - this has not been addressed in the physiotherapy context but is flagged for the consultant's awareness and appropriate ENT/neurosurgery follow-up"),
bul("Extensive background chronic ischaemic changes and microbleeds on MRI - secondary stroke prevention management is ongoing (antiplatelet, antihypertensive, statin)"),
bul("Varicose veins in lower limb - requires careful monitoring during lower limb rehabilitation; vascular review may be appropriate"),
bul("Blood glucose management ongoing - exercise tolerance and response monitored at each session in context of diabetic profile"),
bul("Balance impairment (mild-moderate on Mini BESTest) - fall risk is significant; home safety assessment recommended"),
sp(),
// ── 10. RECOMMENDATIONS ───────────────────────────────────────────────
secHead("10", "Recommendations"),
bul("Continue outpatient physiotherapy - target frequency 3-5 sessions per week; progressive UL motor re-learning, lower limb strengthening, gait rehabilitation and balance training"),
bul("Speech and Language Therapy (SLT) referral for formal dysarthria assessment and management"),
bul("Occupational Therapy (OT) referral for ADL assessment and adaptive equipment if not yet initiated"),
bul("Specialist review for incidental right CP angle Schwannoma (audiological and ENT/neurosurgery referral as appropriate)"),
bul("Vascular surgery / vascular medicine review for varicose veins to guide safety of lower limb rehabilitation"),
bul("Home safety assessment / fall risk assessment recommended"),
bul("Maintain secondary prevention: antiplatelet therapy (Ecosprin + Clopitab), statin (Atorvas 80 mg), antihypertensive, antidiabetic as prescribed"),
bul("Blood glucose and blood pressure monitoring at each physiotherapy session"),
bul("Follow-up with Dr. Siraj Khan (Masina Hospital Trust) as planned for FBS/PPBS review"),
sp(),
// ── 11. GOALS ─────────────────────────────────────────────────────────
secHead("11", "Short and Long-Term Physiotherapy Goals"),
new Table({
width: { size: 9000, type: WidthType.DXA },
rows: [
new TableRow({ children: [thCell("Timeframe", 2000), thCell("Goal", 7000)] }),
new TableRow({ children: [td("Short-term\n(2-4 weeks)", 2000), td("Improve right UL active range of motion and strength. Independent sitting balance. Reduce fall risk. Improve bed mobility and transfers.", 7000)] }),
new TableRow({ children: [td("Medium-term\n(4-8 weeks)", 2000), td("Independent standing balance. Supervised community ambulation. Improve right hand functional grip for ADL tasks. Reduce dysarthria with SLT support.", 7000)] }),
new TableRow({ children: [td("Long-term\n(3-6 months)", 2000), td("Maximum functional independence in ADLs. Community ambulation with or without assistive device. Return to prior level of function where achievable.", 7000)] })
]
}),
sp(),
// ── 12. DECLARATION ───────────────────────────────────────────────────
secHead("12", "Physiotherapist Declaration"),
body("This report has been prepared based on clinical assessment, physiotherapy treatment records, and review of available hospital documentation. All information is provided in confidence for the named consultant."),
sp(),
new Table({
width: { size: 9000, type: WidthType.DXA },
rows: [
infoRow("Physiotherapist:", "[Your Full Name + Qualifications]"),
infoRow("Registration No.:", "[Your Registration Number]"),
infoRow("Clinic / Organisation:", "[Your Clinic Name and Address]"),
infoRow("Telephone:", "[Your Contact Number]"),
infoRow("Email:", "[Your Email Address]"),
infoRow("Date:", "13 July 2026"),
infoRow("Signature:", "_________________________________")
]
}),
sp(),
new Paragraph({
alignment: AlignmentType.CENTER,
children: [italic("This report is confidential and intended solely for the named consultant. Unauthorised distribution is prohibited.")],
spacing: { before: 200, after: 60 }
})
]
}]
});
Packer.toBuffer(doc).then(buf => {
fs.writeFileSync('/home/daytona/workspace/physio-report/Physiotherapy_Report_Parab_Sumant.docx', buf);
console.log('Report generated.');
}).catch(e => { console.error(e); process.exit(1); });
cd /home/daytona/workspace/physio-report && node generate_parab_report.js 2>&1
ls -lh /home/daytona/workspace/physio-report/ && python3 -c "import zipfile; z=z…
Physiotherapy Report Parab Sumant
Word Document · DOCX
| Source | Data Used |
|---|---|
| MRI Report (NM Medical) | Full findings - left IC infarct, chronic ischaemic changes, microbleeds, incidental Schwannoma, normal vessels |
| Discharge Summary (Masina Hospital) | Admission/discharge dates, Dr. Khan Siraj S., diagnosis codes (I63.9, E11.9, I10), history of presenting illness, vitals |
| MRI Remarks Page | Dr. Swarup Nellore's summary - acute infarct, gliosis/encephalomalacia, microangiopathy, Schwannoma |
| Treatment Sheet | All admission medications (Cerebrolysin, Clexane, Ecosprin, Clopitab, Atorvas etc.) and all discharge medications with doses |
| Clinical Course Page | ICU and ward course - conscious, improving motor function, stable vitals, physio started in hospital |
Generate a stroke rehabilitation protocol checklist as a reference guide
~/physio-report/generate_checklist.js
const {
Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell,
AlignmentType, HeadingLevel, LevelFormat, BorderStyle, WidthType,
ShadingType, PageNumber, Header, Footer
} = require('docx');
const fs = require('fs');
// ─── Colors ───────────────────────────────────────────────────────────────────
const C = {
blue: "1F497D",
lblue: "D6E4F0",
dblue: "154360",
teal: "117A65",
lteal: "D1F2EB",
orange: "CA6F1E",
lorange: "FDEBD0",
red: "922B21",
lred: "FADBD8",
purple: "6C3483",
lpurple: "E8DAEF",
green: "1E8449",
lgreen: "D5F5E3",
grey: "555555",
lgrey: "F2F3F4",
white: "FFFFFF",
black: "1A1A1A",
amber: "B7770D",
lamber: "FEF9E7"
};
// ─── Helpers ──────────────────────────────────────────────────────────────────
function noBorder() {
return { top:{style:BorderStyle.NONE}, bottom:{style:BorderStyle.NONE}, left:{style:BorderStyle.NONE}, right:{style:BorderStyle.NONE} };
}
function thinBorder(color="BBBBBB") {
return { top:{style:BorderStyle.SINGLE,size:4,color}, bottom:{style:BorderStyle.SINGLE,size:4,color}, left:{style:BorderStyle.NONE}, right:{style:BorderStyle.NONE} };
}
function sp(before=60, after=60) {
return new Paragraph({ children:[new TextRun("")], spacing:{before,after} });
}
// Header cell (colored)
function th(text, color, textColor=C.white, w) {
return new TableCell({
width: w ? {size:w,type:WidthType.DXA} : undefined,
shading: {type:ShadingType.SOLID, color},
verticalAlign: "center",
children: [new Paragraph({
children: [new TextRun({text, font:"Arial", size:22, bold:true, color:textColor})],
spacing:{before:80,after:80}, indent:{left:100}
})],
borders: noBorder()
});
}
// Data cell
function td(text, color=null, textColor=C.black, w, bold=false) {
return new TableCell({
width: w ? {size:w,type:WidthType.DXA} : undefined,
shading: color ? {type:ShadingType.SOLID,color} : undefined,
children: [new Paragraph({
children: [new TextRun({text, font:"Arial", size:21, color:textColor, bold})],
spacing:{before:70,after:70}, indent:{left:100}
})],
borders: thinBorder()
});
}
// Checkbox cell (unicode checkbox)
function chk(label, subtext) {
const children = [new TextRun({text:"\u2610 "+label, font:"Arial", size:21})];
if(subtext) children.push(new TextRun({text:" "+subtext, font:"Arial", size:19, italics:true, color:C.grey}));
return new Paragraph({ children, spacing:{before:50,after:50} });
}
function chkDone(label) {
return new Paragraph({
children:[new TextRun({text:"\u2611 "+label, font:"Arial", size:21, color:C.green})],
spacing:{before:50,after:50}
});
}
// Phase header (full-width colored banner row)
function phaseRow(text, color, textColor=C.white) {
return new TableRow({ children:[
new TableCell({
columnSpan: 4,
shading:{type:ShadingType.SOLID,color},
children:[new Paragraph({
alignment: AlignmentType.CENTER,
children:[new TextRun({text, font:"Arial", size:24, bold:true, color:textColor})],
spacing:{before:100,after:100}
})],
borders: noBorder()
})
]});
}
// Section heading paragraph
function secHead(text, color=C.blue) {
return new Paragraph({
heading: HeadingLevel.HEADING_2,
children:[new TextRun({text, font:"Arial", bold:true, size:26, color})],
spacing:{before:280,after:120},
border:{bottom:{style:BorderStyle.SINGLE,size:6,color,space:4}}
});
}
function subHead(text, color=C.dblue) {
return new Paragraph({
children:[new TextRun({text, font:"Arial", bold:true, size:23, color})],
spacing:{before:160,after:60}
});
}
function note(text, color=C.grey) {
return new Paragraph({
children:[new TextRun({text:" \u24D8 "+text, font:"Arial", size:19, italics:true, color})],
spacing:{before:40,after:60}
});
}
// ─── Colored info box ─────────────────────────────────────────────────────────
function infoBox(lines, bgColor, textColor=C.black) {
return new Table({
width:{size:9200,type:WidthType.DXA},
rows:[new TableRow({children:[new TableCell({
shading:{type:ShadingType.SOLID,color:bgColor},
children: lines.map(l => new Paragraph({
children:[new TextRun({text:l.text, font:"Arial", size:l.size||21, bold:l.bold||false, color:l.color||textColor, italics:l.italics||false})],
spacing:{before:60,after:60}, indent:{left:160}
})),
borders: noBorder()
})]})],
});
}
// ─── CHECKLIST section table ──────────────────────────────────────────────────
function checkTable(title, titleColor, items) {
// items = [ {label, sub, done} ]
const rows = [
new TableRow({ children:[
new TableCell({
columnSpan:2,
shading:{type:ShadingType.SOLID,color:titleColor},
children:[new Paragraph({
children:[new TextRun({text:title, font:"Arial", size:22, bold:true, color:C.white})],
spacing:{before:80,after:80}, indent:{left:120}
})],
borders:noBorder()
})
]}),
...items.map(item => new TableRow({ children:[
new TableCell({
width:{size:600,type:WidthType.DXA},
shading:{type:ShadingType.SOLID,color:C.lgrey},
children:[new Paragraph({
alignment:AlignmentType.CENTER,
children:[new TextRun({text:item.done?"\u2611":"\u2610", font:"Arial", size:24, color:item.done?C.green:C.grey})],
spacing:{before:70,after:70}
})],
borders:thinBorder("DDDDDD")
}),
new TableCell({
children:[
new Paragraph({
children:[
new TextRun({text:item.label, font:"Arial", size:21, bold:item.bold||false}),
...(item.sub ? [new TextRun({text:" - "+item.sub, font:"Arial", size:19, italics:true, color:C.grey})] : [])
],
spacing:{before:70,after:70}, indent:{left:120}
})
],
borders:thinBorder("DDDDDD")
})
]}))
];
return new Table({ width:{size:9200,type:WidthType.DXA}, rows });
}
// ─── Assessment scale quick ref ───────────────────────────────────────────────
function scaleTable(headers, rows_data, colWidths, headerColor) {
return new Table({
width:{size:9200,type:WidthType.DXA},
rows:[
new TableRow({children: headers.map((h,i) => th(h, headerColor, C.white, colWidths[i]))}),
...rows_data.map(row => new TableRow({
children: row.map((c,i) => td(c, i===0?C.lgrey:null, C.black, colWidths[i]))
}))
]
});
}
// ═════════════════════════════════════════════════════════════════════════════
// DOCUMENT
// ═════════════════════════════════════════════════════════════════════════════
const doc = new Document({
numbering:{config:[{
reference:"bullets",
levels:[{level:0,format:LevelFormat.BULLET,text:"\u2022",alignment:AlignmentType.LEFT,
style:{paragraph:{indent:{left:720,hanging:360}}}}]
}]},
styles:{
default:{document:{run:{font:"Arial",size:21}}},
paragraphStyles:[
{id:"Heading1",name:"Heading 1",basedOn:"Normal",next:"Normal",quickFormat:true,
run:{size:36,bold:true,font:"Arial",color:C.blue},
paragraph:{spacing:{before:0,after:200},outlineLevel:0}},
{id:"Heading2",name:"Heading 2",basedOn:"Normal",next:"Normal",quickFormat:true,
run:{size:26,bold:true,font:"Arial",color:C.blue},
paragraph:{spacing:{before:280,after:120},outlineLevel:1}}
]
},
sections:[{
properties:{page:{margin:{top:800,bottom:800,left:900,right:900}}},
headers:{default: new Header({children:[
new Paragraph({
alignment:AlignmentType.RIGHT,
children:[new TextRun({text:"STROKE REHABILITATION PROTOCOL | PHYSIOTHERAPY REFERENCE GUIDE", font:"Arial", size:17, color:C.blue, bold:true})],
border:{bottom:{style:BorderStyle.SINGLE,size:6,color:C.blue,space:4}}
})
]})},
footers:{default: new Footer({children:[
new Paragraph({
alignment:AlignmentType.CENTER,
children:[
new TextRun({text:"For clinical use only. Based on current stroke rehabilitation evidence (AHA/ASA, RCP, NICE Guidelines). | Page ", font:"Arial", size:17, color:C.grey}),
new TextRun({children:[PageNumber.CURRENT], font:"Arial", size:17, color:C.grey}),
new TextRun({text:" of ", font:"Arial", size:17, color:C.grey}),
new TextRun({children:[PageNumber.TOTAL_PAGES], font:"Arial", size:17, color:C.grey})
],
border:{top:{style:BorderStyle.SINGLE,size:6,color:C.blue,space:4}}
})
]})},
children:[
// ── TITLE PAGE BLOCK ─────────────────────────────────────────────────
new Paragraph({
alignment:AlignmentType.CENTER,
children:[new TextRun({text:"STROKE REHABILITATION", font:"Arial",size:52,bold:true,color:C.blue})],
spacing:{before:160,after:60}
}),
new Paragraph({
alignment:AlignmentType.CENTER,
children:[new TextRun({text:"PROTOCOL CHECKLIST & REFERENCE GUIDE", font:"Arial",size:30,bold:true,color:C.dblue})],
spacing:{before:0,after:60}
}),
new Paragraph({
alignment:AlignmentType.CENTER,
children:[new TextRun({text:"For Physiotherapists | Post-Acute & Outpatient Stroke Rehabilitation", font:"Arial",size:22,color:C.grey})],
spacing:{before:0,after:200}
}),
// ── WHO IS THIS FOR ───────────────────────────────────────────────────
infoBox([
{text:"PURPOSE", bold:true, size:22, color:C.dblue},
{text:"This guide provides physiotherapists with a structured, phase-by-phase checklist for stroke rehabilitation. It covers assessment, goal-setting, treatment planning, outcome measures, precautions, and discharge planning. Use it at each session to ensure no key step is missed.", size:20},
{text:"References: AHA/ASA Stroke Rehabilitation Guidelines | NICE CG162 | RCP National Clinical Guidelines for Stroke | Cochrane Reviews", italics:true, size:18, color:C.grey}
], C.lblue),
sp(80,80),
// ══════════════════════════════════════════════════════════════════════
// SECTION 1 - INITIAL ASSESSMENT CHECKLIST
// ══════════════════════════════════════════════════════════════════════
secHead("1. INITIAL ASSESSMENT CHECKLIST", C.blue),
note("Complete on first contact. Tick each item once assessed and documented."),
sp(40,40),
checkTable("A. Safety & Medical Clearance", C.red, [
{label:"Confirm stroke type (ischaemic / haemorrhagic) from medical notes"},
{label:"Check time from stroke onset to assessment"},
{label:"Review MRI/CT report - lesion site and extent"},
{label:"Review current medications", sub:"anticoagulants, antihypertensives, antiplatelets, antidiabetics"},
{label:"Record baseline vitals: BP, HR, SpO2, temperature"},
{label:"Screen for red flags", sub:"uncontrolled BP >180/110, new neurological deficit, chest pain, severe dysphagia"},
{label:"Check swallowing - SALT referral if dysphagia suspected"},
{label:"Confirm weight-bearing status from medical team"},
{label:"Confirm DVT/VTE prophylaxis status"},
{label:"Note precautions: varicose veins, osteoporosis, cardiac conditions, falls risk"}
]),
sp(80,40),
checkTable("B. Subjective Assessment", C.teal, [
{label:"Chief complaints in patient's own words"},
{label:"Symptom onset, duration, progression"},
{label:"Pain score (NRS 0-10) at rest and with activity"},
{label:"Functional limitations - ADLs, mobility, self-care"},
{label:"Patient goals and expectations"},
{label:"Social history: living situation, carer support, occupation"},
{label:"Past medical/surgical history documented"},
{label:"Communication ability noted", sub:"dysarthria, aphasia, comprehension"},
{label:"Cognitive status - follows commands, orientation"},
{label:"Prior level of function (PLOF) documented"}
]),
sp(80,40),
checkTable("C. Neurological Assessment", C.purple, [
{label:"Level of consciousness (GCS / AVPU)"},
{label:"Orientation - time, place, person"},
{label:"Cognitive screen - MoCA or MMSE"},
{label:"Limb tone - Modified Ashworth Scale (MAS) each limb"},
{label:"Limb power - Oxford Grading 0-5, all major muscle groups"},
{label:"Sensation - light touch, proprioception, pain"},
{label:"Reflexes - deep tendon reflexes, plantar response"},
{label:"Facial weakness / asymmetry noted"},
{label:"Visual field defects / neglect screened"},
{label:"Involuntary movements / spasms noted"}
]),
sp(80,40),
checkTable("D. Musculoskeletal & ROM Assessment", C.orange, [
{label:"Shoulder ROM (AROM and PROM) - bilateral"},
{label:"Elbow, wrist, finger ROM - paretic side"},
{label:"Hip, knee, ankle ROM - paretic side"},
{label:"Trunk range of motion"},
{label:"Shoulder subluxation check - paretic side"},
{label:"Oedema assessment - distal limbs"},
{label:"Skin integrity check - paretic limb"},
{label:"Pain during ROM noted and documented"}
]),
sp(80,40),
checkTable("E. Functional & Balance Assessment", C.dblue, [
{label:"Bed mobility - rolling, bridging, supine to sit"},
{label:"Sitting balance - static and dynamic"},
{label:"Transfers - sit to stand, bed to chair"},
{label:"Standing balance - static and dynamic"},
{label:"Gait assessment - pattern, aid, distance, safety"},
{label:"Berg Balance Scale (BBS) or Mini BESTest scored"},
{label:"Timed Up and Go (TUG) test"},
{label:"Functional Independence Measure (FIM) or Barthel Index"},
{label:"Fall risk categorised (Low / Moderate / High)"},
{label:"Stairs assessment (if applicable)"}
]),
sp(100,60),
// ══════════════════════════════════════════════════════════════════════
// SECTION 2 - OUTCOME MEASURES QUICK REFERENCE
// ══════════════════════════════════════════════════════════════════════
secHead("2. OUTCOME MEASURES - QUICK REFERENCE", C.teal),
note("Select and document at assessment, mid-point, and discharge. Use the same tool each time."),
sp(40,40),
scaleTable(
["Outcome Measure","What It Assesses","Score Range","Clinical Cut-Off / Guidance"],
[
["Modified Ashworth Scale (MAS)","Spasticity / muscle tone","0 - 4","0=no tone; 4=rigid. Grade each muscle group"],
["Oxford Grading (MRC Scale)","Muscle strength","0 - 5","Grade 3 = antigravity; Grade 5 = normal"],
["Berg Balance Scale (BBS)","Static and dynamic balance","0 - 56","<45 = fall risk; <36 = high fall risk"],
["Mini BESTest","Balance across 4 systems","0 - 28","<20 = moderate impairment; <10 = severe"],
["Timed Up and Go (TUG)","Functional mobility","Seconds","<12 sec = low fall risk; >20 sec = high fall risk"],
["Functional Independence Measure (FIM)","ADL independence","18 - 126","<72 = dependent; >108 = independent"],
["Barthel Index (BI)","ADL function","0 - 100","<40 severe; 40-60 moderate; >60 mild dependency"],
["10 Metre Walk Test (10MWT)","Walking speed (m/s)","Seconds","<0.4 m/s community non-functional; >0.8 m/s community ambulatory"],
["Modified Rankin Scale (mRS)","Disability and dependence","0 - 6","0=no symptoms; 6=death; <2=functional independence"],
["Fugl-Meyer Assessment (FMA-UE)","UL motor recovery post-stroke","0 - 66","<19 = severe; 19-55 = moderate; >55 = mild UL impairment"],
["NRS / VAS","Pain intensity","0 - 10 / 0-100mm","0=no pain; 10/100=worst imaginable pain"],
["MoCA","Cognitive screening","0 - 30","<26 = possible cognitive impairment"]
],
[2300, 2200, 1500, 3200], C.teal
),
sp(100,60),
// ══════════════════════════════════════════════════════════════════════
// SECTION 3 - REHABILITATION PHASES
// ══════════════════════════════════════════════════════════════════════
secHead("3. REHABILITATION PHASES & TREATMENT CHECKLIST", C.blue),
// Phase 1
sp(40,20),
new Table({
width:{size:9200,type:WidthType.DXA},
rows:[phaseRow("PHASE 1 | ACUTE (Day 0 - Day 7 post-stroke)", C.red)]
}),
sp(20,40),
infoBox([
{text:"Key Principles: Early mobilisation (within 24-48 hrs if medically stable). Prevent secondary complications. Stimulate neuroplasticity.", bold:false, size:20},
{text:"Contraindications: Uncontrolled BP (>220/120 mmHg ischaemic / >180/105 haemorrhagic), fever, severe hypoxia, new neurological deterioration.", italics:true, size:19, color:C.red}
], C.lred),
sp(40,40),
checkTable("Phase 1 Treatment Checklist", C.red, [
{label:"Positioning: correct lying, sitting alignment - prevent shoulder subluxation"},
{label:"Early sitting out of bed (within 24-48 hrs if haemodynamically stable)"},
{label:"Passive ROM - all limbs, twice daily"},
{label:"Bed mobility: rolling, bridging, supine to sit with minimal assist"},
{label:"Sitting balance at edge of bed - static progress to dynamic"},
{label:"Respiratory physiotherapy if indicated"},
{label:"DVT prevention: ankle pumps, early mobilisation, compression as prescribed"},
{label:"Swallowing screen (SALT referral if needed)"},
{label:"Communication with nursing re: positioning and turning schedule"},
{label:"Patient and family education: stroke, positioning, early rehab goals"},
{label:"Prevent contracture: splinting / resting hand splint if needed"},
{label:"Skin integrity monitoring - pressure area prevention"}
]),
sp(80,40),
// Phase 2
new Table({
width:{size:9200,type:WidthType.DXA},
rows:[phaseRow("PHASE 2 | EARLY REHABILITATION (Week 1 - Week 4)", C.orange)]
}),
sp(20,40),
infoBox([
{text:"Key Principles: Active motor relearning. Task-specific training. Intensive practice of functional tasks. Core stability and trunk control.", size:20},
{text:"Frequency: Minimum 45 minutes of active therapy daily (NICE / RCP guidelines).", italics:true, size:19, color:C.amber}
], C.lorange),
sp(40,40),
checkTable("Phase 2 - Upper Limb Checklist", C.orange, [
{label:"Active-assisted ROM: shoulder, elbow, wrist, fingers"},
{label:"Active ROM with resistance (Theraband - start light e.g. yellow/red)"},
{label:"Shoulder AROM with weight cuff (0.5-1 kg) - flexion, abduction"},
{label:"Task-specific hand/arm practice: reaching, grasping, releasing"},
{label:"Mirror therapy for UL motor relearning"},
{label:"Shoulder subluxation management: sling use review, taping if indicated"},
{label:"Mental imagery / motor imagery practice"},
{label:"Electrical stimulation (NMES/FES) for wrist extensors if available"},
{label:"Constraint-induced movement therapy (CIMT) - if eligible (>10 deg wrist ext)"},
{label:"Graded fine motor tasks: peg board, picking objects, writing practice"}
]),
sp(60,40),
checkTable("Phase 2 - Lower Limb & Gait Checklist", C.amber, [
{label:"Active ROM: hip, knee, ankle - paretic side"},
{label:"Bridging exercises (hip extension, gluteal activation)"},
{label:"Sit to stand practice - 10 reps, graded assistance"},
{label:"Standing balance in parallel bars: static and weight shifting"},
{label:"Marching on spot, high knees, stepping"},
{label:"Gait re-education: heel strike, push-off, swing phase correction"},
{label:"Treadmill training (with body weight support if needed)"},
{label:"Stairs training with rail: step-to pattern progressing to alternate"},
{label:"Ankle-foot orthosis (AFO) fitting review if drop foot present"},
{label:"Proprioceptive training: foam, rocker boards at appropriate stage"}
]),
sp(60,40),
checkTable("Phase 2 - Trunk & Balance Checklist", C.teal, [
{label:"Trunk rotation and lateral flexion exercises"},
{label:"Seated balance on unstable surface (wobble cushion, Bobath ball)"},
{label:"Standing balance: narrow base, eyes closed, perturbation training"},
{label:"Core activation: transversus abdominis, pelvic floor (if appropriate)"},
{label:"Reactive balance training with therapist perturbations"},
{label:"Dual-task training: balance + cognitive task e.g. counting"},
{label:"Dynamic balance: side steps, turning, stepping over obstacles"},
{label:"Progress balance score weekly (BBS / Mini BESTest)"}
]),
sp(80,40),
// Phase 3
new Table({
width:{size:9200,type:WidthType.DXA},
rows:[phaseRow("PHASE 3 | COMMUNITY REHABILITATION (Week 4 - 3 Months)", C.teal)]
}),
sp(20,40),
infoBox([
{text:"Key Principles: Maximum functional independence. Community ambulation. Return to occupation/activity. Self-management and HEP.", size:20},
{text:"Target: community ambulatory speed >0.8 m/s (10MWT). Balance to reduce fall risk. Upper limb functional use in ADLs.", italics:true, size:19, color:C.teal}
], C.lteal),
sp(40,40),
checkTable("Phase 3 Treatment Checklist", C.teal, [
{label:"Progressive resistance training: UL and LL with bands/weights/gym equipment"},
{label:"Circuit training for aerobic fitness and strength (post-stroke fatigue management)"},
{label:"Community walking programme: distance and speed goals"},
{label:"Outdoor gait: uneven terrain, slopes, kerbs, crowded environments"},
{label:"Driving assessment referral (if applicable and appropriate)"},
{label:"Return to work / leisure activity assessment"},
{label:"Aquatic therapy (hydrotherapy) - if varicose vein and cardiovascular status permits"},
{label:"Fatigue management strategies taught"},
{label:"Energy conservation techniques for ADLs"},
{label:"Review and progress HEP - written and verbal instructions"},
{label:"Carer training: handling, guiding, assisting"},
{label:"Community falls prevention programme referral"},
{label:"Psychological wellbeing screen: depression, anxiety (post-stroke depression common)"},
{label:"SLT ongoing review for communication and dysphagia"},
{label:"OT review for ADL equipment and home adaptations"}
]),
sp(100,60),
// ══════════════════════════════════════════════════════════════════════
// SECTION 4 - UPPER LIMB SPECIFIC
// ══════════════════════════════════════════════════════════════════════
secHead("4. UPPER LIMB REHABILITATION - EVIDENCE-BASED APPROACHES", C.purple),
scaleTable(
["Intervention","Indication","Evidence Level","Notes / Dose"],
[
["Task-Specific Training","Any motor deficit","A - Strong","Massed practice of functional tasks. Min 30 min/day"],
["Constraint-Induced Movement Therapy (CIMT)","Minimal residual movement (>10 deg wrist ext)","A - Strong","6 hrs therapy/day x 2 weeks. Constraint for 90% waking hrs"],
["Mirror Therapy","Moderate-severe UL impairment","A - Moderate","30 min/day. Effective for motor and sensory recovery"],
["NMES / FES (Neuromuscular Electrical Stimulation)","Wrist extensors, shoulder subluxation","B - Moderate","30 min sessions. Combine with active movement for best effect"],
["Theraband / Resistance Training","Subacute and chronic phase","A - Strong","Grade resistance: yellow > red > green > blue > black"],
["Bobath / Neurodevelopmental Technique (NDT)","Tone management, movement facilitation","C - Moderate","Use to facilitate normal movement patterns"],
["Bilateral Arm Training","Chronic UL impairment","B - Moderate","Both arms simultaneously. BATRAC protocol"],
["Virtual Reality / Gaming","Motivation, repetitive practice","B - Moderate","Complement to conventional therapy"],
["Shoulder Taping","Subluxation prevention","B - Low","Kinesio or rigid taping. Check skin integrity frequently"],
["Splinting","Spasticity / contracture prevention","C","Resting splint overnight. Serial casting for established contracture"]
],
[2200, 1700, 1400, 3900], C.purple
),
sp(100,60),
// ══════════════════════════════════════════════════════════════════════
// SECTION 5 - GAIT & MOBILITY
// ══════════════════════════════════════════════════════════════════════
secHead("5. GAIT REHABILITATION - EVIDENCE-BASED APPROACHES", C.orange),
scaleTable(
["Intervention","Indication","Evidence Level","Notes"],
[
["Treadmill Training (+/- BWS)","Non-ambulatory to ambulatory","A - Strong","Body weight support reduced gradually. Target walking speed"],
["Overground Gait Training","All ambulatory patients","A - Strong","Task-specific. Distance and speed targets"],
["AFO (Ankle-Foot Orthosis)","Drop foot / equinovarus","B - Strong","Dynamic vs. rigid AFO. Review at 3-6 months"],
["Electrical Stimulation (FES) - TA","Drop foot","A - Moderate","Peroneal nerve stimulation. Time with heel strike"],
["Balance Training (BBS-guided)","Balance impairment","A - Strong","Progressing difficulty: stable > unstable surface, eyes open > closed"],
["Aquatic / Hydrotherapy","Early gait, pain, spasticity","B - Moderate","Avoid if open wounds, uncontrolled BP, varicose veins caution"],
["Robot-Assisted Gait Training","Non-ambulatory post-stroke","B - Moderate","Lokomat / Ekso if available. Supplement overground training"],
["Virtual Reality Gait","Dual-task, outdoor gait sim","B - Moderate","Improves balance and walking speed"],
["Nordic Walking / Cane Use","Community ambulatory","B - Low","Correct cane height: greater trochanter level, contralateral side"]
],
[2300, 1600, 1300, 4000], C.orange
),
sp(100,60),
// ══════════════════════════════════════════════════════════════════════
// SECTION 6 - SPASTICITY MANAGEMENT
// ══════════════════════════════════════════════════════════════════════
secHead("6. SPASTICITY MANAGEMENT PROTOCOL", C.dblue),
infoBox([
{text:"Spasticity develops in 20-40% of stroke survivors, typically appearing 1-3 weeks post-stroke. Early intervention reduces contracture and pain.", size:20},
{text:"Modified Ashworth Scale (MAS): 0 = Normal tone | 1 = Slight increase | 1+ = Slight increase with catch | 2 = Marked increase | 3 = Considerable increase | 4 = Rigid", italics:true, size:19}
], C.lblue),
sp(40,40),
checkTable("Spasticity Checklist", C.dblue, [
{label:"Grade spasticity using MAS - each joint, each session"},
{label:"Daily passive ROM - slow, sustained stretching (30-60 sec holds)"},
{label:"Positioning programme: anti-spastic positioning in lying and sitting"},
{label:"Resting splints: hand/wrist overnight if MAS >2"},
{label:"Serial casting: for established equinus or wrist flexion deformity"},
{label:"Cryotherapy (cold packs) for temporary tone reduction before exercise"},
{label:"Electrical stimulation to antagonists for reciprocal inhibition"},
{label:"Hydrotherapy (warm water) - reduces tone for exercise window"},
{label:"Botulinum toxin A injection (Botox) - refer to physician if MAS ≥2 and functional goal identified"},
{label:"Oral antispastics: refer to physician if systemic treatment needed (Baclofen, Tizanidine)"},
{label:"Monitor for pain, contracture, pressure sores secondary to spasticity"}
]),
sp(100,60),
// ══════════════════════════════════════════════════════════════════════
// SECTION 7 - SPECIAL PRECAUTIONS
// ══════════════════════════════════════════════════════════════════════
secHead("7. SPECIAL PRECAUTIONS & RED FLAGS", C.red),
new Table({
width:{size:9200,type:WidthType.DXA},
rows:[
new TableRow({children:[
th("Condition/Precaution", C.red, C.white, 2500),
th("Physiotherapy Considerations", C.red, C.white, 4000),
th("Action Required", C.red, C.white, 2700)
]}),
new TableRow({children:[td("Hypertension", C.lred, C.black, 2500, true), td("Exercise if BP <180/110 mmHg. Stop if BP rises >20 mmHg systolic during activity", null, C.black, 4000), td("Monitor BP pre/during/post. Stop and rest if exceeded", null, C.black, 2700)]}),
new TableRow({children:[td("Diabetes Mellitus", C.lgrey, C.black, 2500, true), td("Check blood glucose pre-exercise. Optimal: 6-15 mmol/L. Avoid exercise if <4 or >15 mmol/L", null, C.black, 4000), td("Have glucose available. Educate patient on hypoglycaemia signs", null, C.black, 2700)]}),
new TableRow({children:[td("Varicose Veins", C.lred, C.black, 2500, true), td("Elevate lower limbs during all LL exercises. Avoid prolonged dependent positioning. Avoid heavy LL resistance", null, C.black, 4000), td("Monitor for increased pain, swelling, skin colour change", null, C.black, 2700)]}),
new TableRow({children:[td("DVT Risk", C.lgrey, C.black, 2500, true), td("Anticoagulants noted. Ankle pumps and early mobilisation. No vigorous LL massage", null, C.black, 4000), td("Refer to medical team immediately if hot, swollen, painful calf", null, C.black, 2700)]}),
new TableRow({children:[td("Shoulder Subluxation", C.lred, C.black, 2500, true), td("Support paretic arm at all times. No overhead pulleys. No strong traction. Use sling/taping as indicated", null, C.black, 4000), td("X-ray referral if subluxation suspected or painful shoulder develops", null, C.black, 2700)]}),
new TableRow({children:[td("Falls Risk", C.lgrey, C.black, 2500, true), td("BBS <45 = fall risk. Close supervision. Anti-slip footwear. Remove hazards. Hip protectors if appropriate", null, C.black, 4000), td("Falls risk assessment tool completed. Notify team", null, C.black, 2700)]}),
new TableRow({children:[td("Dysphagia", C.lred, C.black, 2500, true), td("Do not give food/water without SALT clearance. Upright positioning during feeding", null, C.black, 4000), td("Urgent SALT referral if coughing/choking/wet voice noted", null, C.black, 2700)]}),
new TableRow({children:[td("Cardiac Precautions", C.lgrey, C.black, 2500, true), td("Borg RPE 11-13 (light-moderate exertion). Stop if chest pain, SOB, palpitations, diaphoresis, syncope", null, C.black, 4000), td("Emergency protocol if cardiac event suspected. Notify medical team", null, C.black, 2700)]}),
new TableRow({children:[td("NEW Neurological Symptoms", C.lred, C.black, 2500, true), td("STOP all physiotherapy immediately", null, C.red, 4000, true), td("URGENT medical review - possible re-stroke or deterioration", null, C.red, 2700, true)]}),
]
}),
sp(100,60),
// ══════════════════════════════════════════════════════════════════════
// SECTION 8 - SESSION STRUCTURE
// ══════════════════════════════════════════════════════════════════════
secHead("8. RECOMMENDED SESSION STRUCTURE", C.teal),
scaleTable(
["Phase","Duration","Components","Focus"],
[
["Warm-up","5-10 min","Breathing, gentle ROM, vital sign check","Prepare body, check baseline, patient report"],
["Main Therapy","35-50 min","UL training, gait, balance, functional tasks","Task-specific, repetitive, progressive"],
["Cool-down","5-10 min","Gentle stretching, positioning, relaxation","Reduce tone, prevent stiffness"],
["Education","5-10 min","HEP review, carer training, goal update","Empower self-management"],
["Documentation","5 min","Session notes, outcome scores, plan for next session","Continuity of care"]
],
[1400, 1200, 3200, 3400], C.teal
),
note("Total: 45-75 min per session. Minimum 45 min of active therapy daily recommended (NICE CG162)."),
sp(100,60),
// ══════════════════════════════════════════════════════════════════════
// SECTION 9 - MDT REFERRAL CHECKLIST
// ══════════════════════════════════════════════════════════════════════
secHead("9. MULTI-DISCIPLINARY TEAM (MDT) REFERRAL CHECKLIST", C.dblue),
note("Stroke rehabilitation is most effective within a coordinated MDT. Screen and refer at initial assessment."),
sp(40,40),
checkTable("MDT Referral Tracking", C.dblue, [
{label:"Speech & Language Therapy (SALT)", sub:"dysarthria, aphasia, dysphagia - refer if any present"},
{label:"Occupational Therapy (OT)", sub:"ADL assessment, upper limb function, home adaptations, driving"},
{label:"Orthotics", sub:"AFO for drop foot, splinting for spasticity"},
{label:"Neuropsychology", sub:"cognitive impairment, attention, memory, executive function"},
{label:"Social Work", sub:"discharge planning, home support, financial/legal issues"},
{label:"Dietitian", sub:"nutritional support, dysphagia diet, diabetic meal planning"},
{label:"Nursing", sub:"skin integrity, continence, medication management, infection prevention"},
{label:"Vascular / Cardiology", sub:"if varicose veins, arrhythmia, or cardiac comorbidity present"},
{label:"ENT / Neurosurgery", sub:"if CP angle lesion, acoustic neuroma, or Schwannoma incidentally detected"},
{label:"Ophthalmology", sub:"visual field defects, hemianopia, diplopia"},
{label:"Neurorehabilitation physician", sub:"for Botox, complex spasticity, assistive technology"},
{label:"Community Physiotherapy", sub:"transition from acute/outpatient to community programme"},
{label:"Stroke support group referral", sub:"peer support, carer groups, stroke association"}
]),
sp(100,60),
// ══════════════════════════════════════════════════════════════════════
// SECTION 10 - DISCHARGE CHECKLIST
// ══════════════════════════════════════════════════════════════════════
secHead("10. DISCHARGE PLANNING CHECKLIST", C.green),
checkTable("Discharge Criteria Met", C.green, [
{label:"All short-term goals achieved or maximally achieved"},
{label:"Patient independent or safely supervised in mobility"},
{label:"Falls risk adequately managed (BBS >45 or home adapted)"},
{label:"Patient and carer confident with HEP"},
{label:"Final outcome measures completed and documented"},
{label:"Discharge summary written and sent to GP and consultant"},
{label:"All MDT referrals completed or handed over"},
{label:"Community physiotherapy or maintenance programme arranged"},
{label:"Stroke support group / peer support information given"},
{label:"Patient aware of stroke warning signs (FAST / BE-FAST)"},
{label:"Secondary prevention medications confirmed with patient"},
{label:"Follow-up appointment arranged if needed"}
]),
sp(80,40),
// ── BE-FAST reminder ─────────────────────────────────────────────────
infoBox([
{text:"BE-FAST - Stroke Warning Signs (Teach Every Patient)", bold:true, size:22, color:C.red},
{text:"B - Balance: sudden loss of balance or coordination", size:21},
{text:"E - Eyes: sudden vision changes in one or both eyes", size:21},
{text:"F - Face drooping: one side of the face droops or is numb", size:21},
{text:"A - Arm weakness: one arm is weak or numb", size:21},
{text:"S - Speech: slurred, strange, or unable to speak", size:21},
{text:"T - Time to call emergency services immediately!", bold:true, size:21, color:C.red}
], C.lred),
sp(100,60),
// ── Footer note ──────────────────────────────────────────────────────
new Paragraph({
alignment: AlignmentType.CENTER,
children:[new TextRun({text:"Stroke Rehabilitation Protocol Checklist | Compiled by [Your Name/Clinic] | Date: July 2026 | Review Date: July 2027", font:"Arial", size:18, italics:true, color:C.grey})],
spacing:{before:160,after:60}
}),
new Paragraph({
alignment: AlignmentType.CENTER,
children:[new TextRun({text:"Based on: AHA/ASA 2016 Stroke Rehabilitation Guidelines | NICE CG162 | RCP National Clinical Guidelines for Stroke 2023 | Cochrane Reviews", font:"Arial", size:17, italics:true, color:C.grey})],
spacing:{before:0,after:60}
})
]
}]
});
Packer.toBuffer(doc).then(buf => {
fs.writeFileSync('/home/daytona/workspace/physio-report/Stroke_Rehab_Protocol_Checklist.docx', buf);
console.log('Checklist generated successfully.');
}).catch(e => { console.error(e); process.exit(1); });
cd /home/daytona/workspace/physio-report && node generate_checklist.js 2>&1
ls -lh /home/daytona/workspace/physio-report/Stroke_Rehab_Protocol_Checklist.doc…
Stroke Rehab Protocol Checklist
Word Document · DOCX
This contains too much of medical make it physiotherapy management oriented I started physiotherapy session on 10th july till now 3 sessions are done. He has rt hemiparesis with mild facial weakness and slurred speech. Mild-moderate balance impairments according to mini BESTest. As a physiotherapist iam taking his ul elbow wrist and finger roms with red theraband and shoulder aroms with weight cuff o.5 kg.then as pt has varicose veins so atms on elevated position then balance training And stair climbing 7 flights done once . Write a report as the doctor understand about what physiotherapy is going on
~/physio-report/generate_consultant_report.js
const {
Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell,
AlignmentType, HeadingLevel, LevelFormat, BorderStyle, WidthType,
ShadingType, PageNumber, Header, Footer
} = require('docx');
const fs = require('fs');
const BLUE = "1F497D";
const LBLUE = "D6E4F0";
const DBLUE = "154360";
const TEAL = "0E6655";
const LTEAL = "D1F2EB";
const GREY = "555555";
const LGREY = "F4F6F7";
const WHITE = "FFFFFF";
const GREEN = "1A6B34";
const LGREEN = "D5F5E3";
const AMBER = "7D6608";
const LAMBER = "FEF9E7";
const RED = "922B21";
function noBorder() {
return {
top:{style:BorderStyle.NONE}, bottom:{style:BorderStyle.NONE},
left:{style:BorderStyle.NONE}, right:{style:BorderStyle.NONE}
};
}
function thinLine(c="CCCCCC") {
return {
top:{style:BorderStyle.SINGLE,size:4,color:c},
bottom:{style:BorderStyle.SINGLE,size:4,color:c},
left:{style:BorderStyle.NONE}, right:{style:BorderStyle.NONE}
};
}
function sp(b=60,a=60){ return new Paragraph({children:[new TextRun("")],spacing:{before:b,after:a}}); }
// Section heading - blue underline
function sec(text){
return new Paragraph({
heading: HeadingLevel.HEADING_2,
children:[new TextRun({text, font:"Arial", bold:true, size:25, color:BLUE})],
spacing:{before:280,after:100},
border:{bottom:{style:BorderStyle.SINGLE,size:6,color:BLUE,space:4}}
});
}
// Sub-label bold
function sub(text){
return new Paragraph({
children:[new TextRun({text, font:"Arial", bold:true, size:22, color:DBLUE})],
spacing:{before:120,after:40}
});
}
// Body paragraph
function body(text, color=null){
return new Paragraph({
children:[new TextRun({text, font:"Arial", size:22, color:color||"000000"})],
spacing:{before:60,after:60}
});
}
// Bullet
function bul(text){
return new Paragraph({
numbering:{reference:"bullets",level:0},
children:[new TextRun({text, font:"Arial", size:22})],
spacing:{before:40,after:40}
});
}
// Info row (2-col table without borders)
function infoRow(lText, rText, shade=LGREY){
return new TableRow({ children:[
new TableCell({
width:{size:3200,type:WidthType.DXA},
shading:{type:ShadingType.SOLID,color:shade},
children:[new Paragraph({children:[new TextRun({text:lText,font:"Arial",size:22,bold:true})],spacing:{before:80,after:80},indent:{left:100}})],
borders:noBorder()
}),
new TableCell({
width:{size:5800,type:WidthType.DXA},
children:[new Paragraph({children:[new TextRun({text:rText,font:"Arial",size:22})],spacing:{before:80,after:80},indent:{left:100}})],
borders:noBorder()
})
]});
}
// Colored banner row (full width)
function banner(text, bg, fg=WHITE){
return new Paragraph({
alignment:AlignmentType.CENTER,
shading:{type:ShadingType.SOLID,color:bg},
children:[new TextRun({text, font:"Arial", size:23, bold:true, color:fg})],
spacing:{before:100,after:100},
indent:{left:100,right:100}
});
}
// Progress row in session table
function sessRow(n, date, activity, response){
return new TableRow({ children:[
new TableCell({ width:{size:700,type:WidthType.DXA}, children:[new Paragraph({children:[new TextRun({text:n, font:"Arial",size:22})],spacing:{before:80,after:80},indent:{left:80}})], borders:thinLine() }),
new TableCell({ width:{size:1500,type:WidthType.DXA}, children:[new Paragraph({children:[new TextRun({text:date, font:"Arial",size:22})],spacing:{before:80,after:80},indent:{left:80}})], borders:thinLine() }),
new TableCell({ width:{size:3700,type:WidthType.DXA}, children:[new Paragraph({children:[new TextRun({text:activity,font:"Arial",size:22})],spacing:{before:80,after:80},indent:{left:80}})], borders:thinLine() }),
new TableCell({ width:{size:3100,type:WidthType.DXA}, children:[new Paragraph({children:[new TextRun({text:response,font:"Arial",size:22})],spacing:{before:80,after:80},indent:{left:80}})], borders:thinLine() })
]});
}
function thRow(cols, widths, color){
return new TableRow({ children: cols.map((c,i) =>
new TableCell({
width:{size:widths[i],type:WidthType.DXA},
shading:{type:ShadingType.SOLID,color},
children:[new Paragraph({children:[new TextRun({text:c,font:"Arial",size:22,bold:true,color:WHITE})],spacing:{before:80,after:80},indent:{left:80}})],
borders:noBorder()
})
)});
}
// ─── DOCUMENT ─────────────────────────────────────────────────────────────────
const doc = new Document({
numbering:{config:[{reference:"bullets",levels:[{
level:0,format:LevelFormat.BULLET,text:"\u2022",alignment:AlignmentType.LEFT,
style:{paragraph:{indent:{left:680,hanging:340}}}
}]}]},
styles:{
default:{document:{run:{font:"Arial",size:22}}},
paragraphStyles:[
{id:"Heading1",name:"Heading 1",basedOn:"Normal",next:"Normal",quickFormat:true,
run:{size:38,bold:true,font:"Arial",color:BLUE},
paragraph:{spacing:{before:0,after:180},outlineLevel:0}},
{id:"Heading2",name:"Heading 2",basedOn:"Normal",next:"Normal",quickFormat:true,
run:{size:25,bold:true,font:"Arial",color:BLUE},
paragraph:{spacing:{before:280,after:100},outlineLevel:1}}
]
},
sections:[{
properties:{page:{margin:{top:850,bottom:850,left:1100,right:1100}}},
headers:{default: new Header({children:[
new Paragraph({
alignment:AlignmentType.RIGHT,
children:[new TextRun({text:"CONFIDENTIAL | PHYSIOTHERAPY PROGRESS REPORT | FOR CONSULTANT USE", font:"Arial",size:17,color:RED,bold:true})],
border:{bottom:{style:BorderStyle.SINGLE,size:6,color:BLUE,space:4}}
})
]})},
footers:{default: new Footer({children:[
new Paragraph({
alignment:AlignmentType.CENTER,
children:[
new TextRun({text:"[Your Clinic Name] | [Contact Number] | Page ",font:"Arial",size:17,color:GREY}),
new TextRun({children:[PageNumber.CURRENT],font:"Arial",size:17,color:GREY}),
new TextRun({text:" of ",font:"Arial",size:17,color:GREY}),
new TextRun({children:[PageNumber.TOTAL_PAGES],font:"Arial",size:17,color:GREY})
],
border:{top:{style:BorderStyle.SINGLE,size:6,color:BLUE,space:4}}
})
]})},
children:[
// ─── TITLE ───────────────────────────────────────────────────────────
new Paragraph({
alignment:AlignmentType.CENTER,
children:[new TextRun({text:"PHYSIOTHERAPY PROGRESS REPORT", font:"Arial",size:38,bold:true,color:BLUE})],
spacing:{before:160,after:50}
}),
new Paragraph({
alignment:AlignmentType.CENTER,
children:[new TextRun({text:"Post-Stroke Rehabilitation | Sessions 1 - 3", font:"Arial",size:24,bold:true,color:GREY})],
spacing:{before:0,after:60}
}),
new Paragraph({
alignment:AlignmentType.CENTER,
children:[new TextRun({text:"[Your Clinic / Practice Name] | [Address] | Tel: [Number]", font:"Arial",size:20,color:GREY})],
spacing:{before:0,after:40}
}),
new Paragraph({
alignment:AlignmentType.CENTER,
children:[new TextRun({text:"Date of Report: 13 July 2026", font:"Arial",size:22,bold:true})],
spacing:{before:80,after:200}
}),
// ─── 1. PATIENT SNAPSHOT ─────────────────────────────────────────────
sec("1. Patient Snapshot"),
new Table({
width:{size:9000,type:WidthType.DXA},
rows:[
infoRow("Patient:", "Mr. Sumant Tukaram Parab, 70 Years, Male"),
infoRow("Medical Diagnosis:", "Left Internal Capsule Acute Infarct (Ischaemic Stroke) | ICD I63.9"),
infoRow("Date of Stroke:", "02 July 2026"),
infoRow("Discharged from:", "Masina Hospital Trust, Mumbai — 07 July 2026"),
infoRow("Treating Physician:", "Dr. Khan Siraj S., Masina Hospital Trust"),
infoRow("Report Addressed To:","[Consultant Name, Speciality, Hospital]"),
infoRow("Physio Started:", "10 July 2026 (3 days post-discharge)"),
infoRow("Sessions Completed:", "3 (10 July, 11 July, 12 July 2026)"),
infoRow("Treating Physiotherapist:", "[Your Name, Qualifications, Registration No.]"),
infoRow("Date of This Report:","13 July 2026")
]
}),
sp(80,40),
// ─── PURPOSE BOX ─────────────────────────────────────────────────────
new Table({
width:{size:9000,type:WidthType.DXA},
rows:[new TableRow({children:[new TableCell({
shading:{type:ShadingType.SOLID,color:LBLUE},
children:[
new Paragraph({children:[new TextRun({text:"Purpose of This Report", font:"Arial",size:22,bold:true,color:DBLUE})], spacing:{before:80,after:40}, indent:{left:140}}),
new Paragraph({children:[new TextRun({text:"This report provides the consultant with a clear summary of the physiotherapy intervention being carried out for Mr. Parab following his stroke. It describes the clinical presentation at the time of physiotherapy assessment, the specific treatment techniques being used, the rationale behind each, and the patient's functional progress after three sessions.", font:"Arial",size:22})], spacing:{before:0,after:80}, indent:{left:140}})
],
borders:noBorder()
})]})],
}),
sp(100,60),
// ─── 2. CLINICAL PRESENTATION AT PHYSIOTHERAPY ASSESSMENT ────────────
sec("2. Clinical Presentation at Physiotherapy Assessment (10 July 2026)"),
body("Mr. Parab presented 3 days after hospital discharge with the following active deficits:"),
sp(40,20),
// 2-col layout table
new Table({
width:{size:9000,type:WidthType.DXA},
rows:[
new TableRow({children:[
new TableCell({ width:{size:4400,type:WidthType.DXA},
shading:{type:ShadingType.SOLID,color:LBLUE},
children:[
new Paragraph({children:[new TextRun({text:"Motor & Functional Deficits",font:"Arial",size:22,bold:true,color:DBLUE})], spacing:{before:80,after:60}, indent:{left:120}}),
new Paragraph({numbering:{reference:"bullets",level:0}, children:[new TextRun({text:"Right hemiparesis — weakness of the right upper and lower limb",font:"Arial",size:22})], spacing:{before:40,after:40}}),
new Paragraph({numbering:{reference:"bullets",level:0}, children:[new TextRun({text:"Mild right facial weakness — deviation of angle of mouth",font:"Arial",size:22})], spacing:{before:40,after:40}}),
new Paragraph({numbering:{reference:"bullets",level:0}, children:[new TextRun({text:"Slurred speech (dysarthria) — mild, improving from hospital",font:"Arial",size:22})], spacing:{before:40,after:40}}),
new Paragraph({numbering:{reference:"bullets",level:0}, children:[new TextRun({text:"Reduced active range of motion in right elbow, wrist and fingers",font:"Arial",size:22})], spacing:{before:40,after:40}}),
new Paragraph({numbering:{reference:"bullets",level:0}, children:[new TextRun({text:"Reduced shoulder active range of motion — right side",font:"Arial",size:22})], spacing:{before:40,after:80}})
],
borders:noBorder()
}),
new TableCell({ width:{size:4600,type:WidthType.DXA},
shading:{type:ShadingType.SOLID,color:LGREEN},
children:[
new Paragraph({children:[new TextRun({text:"Balance & Mobility",font:"Arial",size:22,bold:true,color:GREEN})], spacing:{before:80,after:60}, indent:{left:120}}),
new Paragraph({numbering:{reference:"bullets",level:0}, children:[new TextRun({text:"Mild-to-moderate balance impairment — assessed using the Mini Balance Evaluation Systems Test (Mini BESTest)",font:"Arial",size:22})], spacing:{before:40,after:40}}),
new Paragraph({numbering:{reference:"bullets",level:0}, children:[new TextRun({text:"Unsteady gait — requires supervision",font:"Arial",size:22})], spacing:{before:40,after:40}}),
new Paragraph({numbering:{reference:"bullets",level:0}, children:[new TextRun({text:"Varicose veins present in lower limbs — requires elevation precaution during all lower limb exercises",font:"Arial",size:22})], spacing:{before:40,after:40}}),
new Paragraph({numbering:{reference:"bullets",level:0}, children:[new TextRun({text:"Conscious, alert, cooperative, and able to follow instructions",font:"Arial",size:22})], spacing:{before:40,after:80}})
],
borders:noBorder()
})
]})
]
}),
sp(100,60),
// ─── 3. PHYSIOTHERAPY TREATMENT BEING GIVEN ──────────────────────────
sec("3. Physiotherapy Treatment Programme (Sessions 1 - 3)"),
body("The treatment programme has been designed specifically to address the motor, balance, and functional deficits secondary to right hemiparesis. Each session follows the structure outlined below:"),
sp(40,20),
// Treatment block 1
banner("A. RIGHT UPPER LIMB REHABILITATION", TEAL),
sp(20,40),
sub("1. Elbow, Wrist and Finger Range of Motion — Red Theraband"),
body("The patient performs active-resisted range of motion exercises for the right elbow (flexion and extension), wrist (flexion and extension), and fingers (composite flexion and extension) using a red Theraband."),
sp(20,10),
new Table({
width:{size:9000,type:WidthType.DXA},
rows:[new TableRow({children:[new TableCell({
shading:{type:ShadingType.SOLID,color:LTEAL},
children:[
new Paragraph({children:[new TextRun({text:"Why this is used:",font:"Arial",size:21,bold:true,color:TEAL})], spacing:{before:70,after:40}, indent:{left:120}}),
new Paragraph({children:[new TextRun({text:"After a stroke affecting the left internal capsule, voluntary movement of the contralateral (right) limb is impaired due to disruption of the corticospinal tract. Theraband resistance exercises provide controlled, graded resistance that stimulates motor unit recruitment, promotes neuromuscular re-education, and encourages cortical reorganisation (neuroplasticity). Red Theraband represents a light-to-moderate resistance level appropriate for the early subacute phase — challenging enough to facilitate recovery without causing fatigue or compensatory movement patterns.",font:"Arial",size:21})], spacing:{before:0,after:80}, indent:{left:120}})
], borders:noBorder()
})]})],
}),
sp(60,20),
sub("2. Shoulder Active Range of Motion — 0.5 kg Weight Cuff"),
body("Shoulder active range of motion exercises (flexion, abduction, extension) are performed with a 0.5 kg weight cuff on the right wrist to provide light loading through the shoulder girdle."),
sp(20,10),
new Table({
width:{size:9000,type:WidthType.DXA},
rows:[new TableRow({children:[new TableCell({
shading:{type:ShadingType.SOLID,color:LTEAL},
children:[
new Paragraph({children:[new TextRun({text:"Why this is used:",font:"Arial",size:21,bold:true,color:TEAL})], spacing:{before:70,after:40}, indent:{left:120}}),
new Paragraph({children:[new TextRun({text:"Following a stroke, the shoulder is vulnerable to subluxation (partial dislocation) due to weakness of the rotator cuff and periscapular muscles. Active range of motion with a light weight cuff serves two purposes: (1) it activates the shoulder stabilisers and deltoid to maintain joint integrity; and (2) it provides proprioceptive feedback to the shoulder, reinforcing motor control without placing excessive load on a weakened joint. A 0.5 kg load is deliberately conservative at this stage (10 days post-stroke) to match the patient's current muscle power.",font:"Arial",size:21})], spacing:{before:0,after:80}, indent:{left:120}})
], borders:noBorder()
})]})],
}),
sp(100,40),
// Treatment block 2
banner("B. RIGHT LOWER LIMB — ELEVATED POSITION (Varicose Vein Precaution)", AMBER, WHITE),
sp(20,40),
sub("3. Lower Limb Range of Motion and Exercises in Elevation"),
body("All lower limb exercises are performed with the right lower limb maintained in an elevated position throughout the session."),
sp(20,10),
new Table({
width:{size:9000,type:WidthType.DXA},
rows:[new TableRow({children:[new TableCell({
shading:{type:ShadingType.SOLID,color:LAMBER},
children:[
new Paragraph({children:[new TextRun({text:"Why elevation is used:",font:"Arial",size:21,bold:true,color:AMBER})], spacing:{before:70,after:40}, indent:{left:120}}),
new Paragraph({children:[new TextRun({text:"Mr. Parab has known varicose veins in the lower limbs, which indicates impaired venous valve function and increased risk of venous stasis. Exercising the lower limb in a dependent (hanging down) position against gravity can significantly worsen venous pooling, cause pain, increase limb swelling, and potentially contribute to a deep vein thrombosis (DVT). Elevating the limb during exercise counteracts this by using gravity to assist venous return to the heart. This precaution allows full lower limb rehabilitation to continue safely without aggravating the venous condition.",font:"Arial",size:21})], spacing:{before:0,after:80}, indent:{left:120}})
], borders:noBorder()
})]})],
}),
sp(100,40),
// Treatment block 3
banner("C. BALANCE TRAINING", "1A5276", WHITE),
sp(20,40),
sub("4. Balance Training — Static and Dynamic"),
body("Progressive balance training is performed in each session, including static standing balance, dynamic weight shifting, and task-specific balance challenges."),
sp(20,10),
new Table({
width:{size:9000,type:WidthType.DXA},
rows:[new TableRow({children:[new TableCell({
shading:{type:ShadingType.SOLID,color:"D6EAF8"},
children:[
new Paragraph({children:[new TextRun({text:"Why balance training is essential:",font:"Arial",size:21,bold:true,color:"1A5276"})], spacing:{before:70,after:40}, indent:{left:120}}),
new Paragraph({children:[new TextRun({text:"The Mini BESTest assesses four systems contributing to balance: anticipatory postural adjustments, reactive postural control, sensory orientation, and dynamic gait. Mr. Parab scores in the mild-to-moderate impairment range, indicating meaningful fall risk. The left internal capsule infarct disrupts motor and sensory pathways that contribute to postural control of the right limb. Balance training stimulates adaptation of the central nervous system to re-establish postural strategies, reduces fall risk, and is a prerequisite for safe functional ambulation and community independence.",font:"Arial",size:21})], spacing:{before:0,after:80}, indent:{left:120}})
], borders:noBorder()
})]})],
}),
sp(100,40),
// Treatment block 4
banner("D. STAIR CLIMBING", GREEN, WHITE),
sp(20,40),
sub("5. Stair Climbing — 7 Flights Completed (Session 3)"),
body("Mr. Parab has successfully completed 7 flights of stairs as part of functional rehabilitation during session 3, with physiotherapist supervision."),
sp(20,10),
new Table({
width:{size:9000,type:WidthType.DXA},
rows:[new TableRow({children:[new TableCell({
shading:{type:ShadingType.SOLID,color:LGREEN},
children:[
new Paragraph({children:[new TextRun({text:"Clinical significance of 7 flights:",font:"Arial",size:21,bold:true,color:GREEN})], spacing:{before:70,after:40}, indent:{left:120}}),
new Paragraph({children:[new TextRun({text:"Stair climbing is among the most functionally demanding activities in stroke rehabilitation. It requires: (1) adequate lower limb strength to propel body weight upward; (2) dynamic single-leg balance and weight transfer; (3) hip flexor and ankle dorsiflexor activation — often specifically impaired after a left internal capsule stroke; and (4) coordination and concentration. The fact that Mr. Parab has completed 7 flights at just 3 sessions post-discharge — 6 days after hospital discharge — is a significant functional milestone. It demonstrates meaningful motor recovery and cardiovascular tolerance, and it indicates that the rehabilitation programme is progressing well.",font:"Arial",size:21})], spacing:{before:0,after:80}, indent:{left:120}})
], borders:noBorder()
})]})],
}),
sp(100,60),
// ─── 4. PROGRESS SUMMARY ─────────────────────────────────────────────
sec("4. Session Progress Summary"),
new Table({
width:{size:9000,type:WidthType.DXA},
rows:[
thRow(["Session","Date","Treatment Performed","Functional Progress"],[700,1500,3700,3100], BLUE),
sessRow("1","10 Jul 2026",
"Initial assessment. Right UL ROM with red Theraband (elbow, wrist, fingers). Shoulder AROM with 0.5 kg cuff. LL exercises in elevation. Mini BESTest — mild-moderate impairment. Static balance at parallel bars.",
"Patient able to follow all instructions. Tolerated Theraband and weight cuff well. Moderate assistance required for standing balance."
),
sessRow("2","11 Jul 2026",
"Continued UL Theraband ROM (elbow, wrist, fingers) — increased repetitions. Shoulder AROM with 0.5 kg cuff. LL elevation exercises. Sitting-to-standing practice. Dynamic balance: weight shifting and stepping.",
"Improved endurance with UL exercises. Reduced assistance required for sit-to-stand. Progressing balance from static to dynamic."
),
sessRow("3","12 Jul 2026",
"UL Theraband and shoulder AROM continued. LL in elevation. Balance training — standing with reduced support. Stair climbing introduced: 7 flights completed with supervision.",
"Stair climbing 7 flights achieved — significant functional milestone. Balance improving. Patient motivated and engaged. Slurred speech noted as mild and stable.")
]
}),
sp(100,60),
// ─── 5. CURRENT FUNCTIONAL STATUS ────────────────────────────────────
sec("5. Current Functional Status (after 3 sessions | 13 July 2026)"),
new Table({
width:{size:9000,type:WidthType.DXA},
rows:[
new TableRow({children:[
new TableCell({
width:{size:3000,type:WidthType.DXA},
shading:{type:ShadingType.SOLID,color:LBLUE},
children:[new Paragraph({children:[new TextRun({text:"Function",font:"Arial",size:22,bold:true,color:DBLUE})],spacing:{before:80,after:80},indent:{left:100}})],
borders:noBorder()
}),
new TableCell({
width:{size:2500,type:WidthType.DXA},
shading:{type:ShadingType.SOLID,color:LBLUE},
children:[new Paragraph({children:[new TextRun({text:"Status",font:"Arial",size:22,bold:true,color:DBLUE})],spacing:{before:80,after:80},indent:{left:100}})],
borders:noBorder()
}),
new TableCell({
width:{size:3500,type:WidthType.DXA},
shading:{type:ShadingType.SOLID,color:LBLUE},
children:[new Paragraph({children:[new TextRun({text:"Notes",font:"Arial",size:22,bold:true,color:DBLUE})],spacing:{before:80,after:80},indent:{left:100}})],
borders:noBorder()
})
]}),
new TableRow({children:[
new TableCell({width:{size:3000,type:WidthType.DXA}, children:[new Paragraph({children:[new TextRun({text:"Right UL Active Movement",font:"Arial",size:22})],spacing:{before:80,after:80},indent:{left:100}})], borders:thinLine()}),
new TableCell({width:{size:2500,type:WidthType.DXA}, shading:{type:ShadingType.SOLID,color:"FEF9E7"}, children:[new Paragraph({children:[new TextRun({text:"Improving",font:"Arial",size:22,bold:true,color:"7D6608"})],spacing:{before:80,after:80},indent:{left:100}})], borders:thinLine()}),
new TableCell({width:{size:3500,type:WidthType.DXA}, children:[new Paragraph({children:[new TextRun({text:"Elbow, wrist, fingers responding to Theraband training",font:"Arial",size:22})],spacing:{before:80,after:80},indent:{left:100}})], borders:thinLine()})
]}),
new TableRow({children:[
new TableCell({width:{size:3000,type:WidthType.DXA}, children:[new Paragraph({children:[new TextRun({text:"Right Shoulder AROM",font:"Arial",size:22})],spacing:{before:80,after:80},indent:{left:100}})], borders:thinLine()}),
new TableCell({width:{size:2500,type:WidthType.DXA}, shading:{type:ShadingType.SOLID,color:"FEF9E7"}, children:[new Paragraph({children:[new TextRun({text:"Improving",font:"Arial",size:22,bold:true,color:"7D6608"})],spacing:{before:80,after:80},indent:{left:100}})], borders:thinLine()}),
new TableCell({width:{size:3500,type:WidthType.DXA}, children:[new Paragraph({children:[new TextRun({text:"Active range increasing with 0.5 kg cuff",font:"Arial",size:22})],spacing:{before:80,after:80},indent:{left:100}})], borders:thinLine()})
]}),
new TableRow({children:[
new TableCell({width:{size:3000,type:WidthType.DXA}, children:[new Paragraph({children:[new TextRun({text:"Balance",font:"Arial",size:22})],spacing:{before:80,after:80},indent:{left:100}})], borders:thinLine()}),
new TableCell({width:{size:2500,type:WidthType.DXA}, shading:{type:ShadingType.SOLID,color:"FEF9E7"}, children:[new Paragraph({children:[new TextRun({text:"Improving",font:"Arial",size:22,bold:true,color:"7D6608"})],spacing:{before:80,after:80},indent:{left:100}})], borders:thinLine()}),
new TableCell({width:{size:3500,type:WidthType.DXA}, children:[new Paragraph({children:[new TextRun({text:"Progressed from static to dynamic balance tasks",font:"Arial",size:22})],spacing:{before:80,after:80},indent:{left:100}})], borders:thinLine()})
]}),
new TableRow({children:[
new TableCell({width:{size:3000,type:WidthType.DXA}, children:[new Paragraph({children:[new TextRun({text:"Stair Climbing",font:"Arial",size:22})],spacing:{before:80,after:80},indent:{left:100}})], borders:thinLine()}),
new TableCell({width:{size:2500,type:WidthType.DXA}, shading:{type:ShadingType.SOLID,color:LGREEN}, children:[new Paragraph({children:[new TextRun({text:"Achieved",font:"Arial",size:22,bold:true,color:GREEN})],spacing:{before:80,after:80},indent:{left:100}})], borders:thinLine()}),
new TableCell({width:{size:3500,type:WidthType.DXA}, children:[new Paragraph({children:[new TextRun({text:"7 flights completed with supervision — major milestone",font:"Arial",size:22})],spacing:{before:80,after:80},indent:{left:100}})], borders:thinLine()})
]}),
new TableRow({children:[
new TableCell({width:{size:3000,type:WidthType.DXA}, children:[new Paragraph({children:[new TextRun({text:"Lower Limb Safety",font:"Arial",size:22})],spacing:{before:80,after:80},indent:{left:100}})], borders:thinLine()}),
new TableCell({width:{size:2500,type:WidthType.DXA}, shading:{type:ShadingType.SOLID,color:LGREEN}, children:[new Paragraph({children:[new TextRun({text:"Managed",font:"Arial",size:22,bold:true,color:GREEN})],spacing:{before:80,after:80},indent:{left:100}})], borders:thinLine()}),
new TableCell({width:{size:3500,type:WidthType.DXA}, children:[new Paragraph({children:[new TextRun({text:"Varicose vein precaution maintained throughout",font:"Arial",size:22})],spacing:{before:80,after:80},indent:{left:100}})], borders:thinLine()})
]}),
new TableRow({children:[
new TableCell({width:{size:3000,type:WidthType.DXA}, children:[new Paragraph({children:[new TextRun({text:"Speech (Dysarthria)",font:"Arial",size:22})],spacing:{before:80,after:80},indent:{left:100}})], borders:thinLine()}),
new TableCell({width:{size:2500,type:WidthType.DXA}, shading:{type:ShadingType.SOLID,color:"FEF9E7"}, children:[new Paragraph({children:[new TextRun({text:"Mild / Stable",font:"Arial",size:22,bold:true,color:"7D6608"})],spacing:{before:80,after:80},indent:{left:100}})], borders:thinLine()}),
new TableCell({width:{size:3500,type:WidthType.DXA}, children:[new Paragraph({children:[new TextRun({text:"Not within physiotherapy scope — SLT referral recommended",font:"Arial",size:22})],spacing:{before:80,after:80},indent:{left:100}})], borders:thinLine()})
]})
]
}),
sp(100,60),
// ─── 6. PLAN GOING FORWARD ────────────────────────────────────────────
sec("6. Physiotherapy Plan Going Forward"),
bul("Continue progressive UL Theraband resistance training (elbow, wrist, fingers) — increase repetitions and resistance band as strength improves"),
bul("Continue shoulder AROM with 0.5 kg cuff — progress to 1 kg when patient demonstrates good shoulder control"),
bul("Continue lower limb exercises in elevated position throughout — maintain varicose vein precaution"),
bul("Progress balance training: reduce support, introduce dual-task balance (balance + cognitive task), outdoor walking"),
bul("Progress stair climbing — aim to increase number of flights and eventual independence without rail"),
bul("Introduce fine motor tasks (grip, pinch, writing, functional reach) for right hand as motor control improves"),
bul("Gait re-education: correct right hemiplegic gait pattern, heel strike, push-off"),
bul("Home Exercise Programme (HEP) issued and reviewed at each session"),
bul("Target: 3-5 sessions per week for maximum neuroplasticity window in early subacute phase"),
sp(80,40),
// ─── 7. REQUESTS TO CONSULTANT ───────────────────────────────────────
sec("7. Requests to the Consultant"),
new Table({
width:{size:9000,type:WidthType.DXA},
rows:[
new TableRow({children:[
th("Request", BLUE, WHITE, 2800),
th("Reason", BLUE, WHITE, 6200)
]}),
new TableRow({children:[
new TableCell({width:{size:2800,type:WidthType.DXA}, shading:{type:ShadingType.SOLID,color:LGREY}, children:[new Paragraph({children:[new TextRun({text:"Speech & Language Therapy (SLT) referral",font:"Arial",size:22,bold:true})],spacing:{before:80,after:80},indent:{left:100}})], borders:thinLine()}}),
new TableCell({width:{size:6200,type:WidthType.DXA}, children:[new Paragraph({children:[new TextRun({text:"Slurred speech (dysarthria) and mild facial weakness persist. Formal SLT assessment would address dysarthria and screen for any dysphagia not yet identified",font:"Arial",size:22})],spacing:{before:80,after:80},indent:{left:100}})], borders:thinLine()})
]}),
new TableRow({children:[
new TableCell({width:{size:2800,type:WidthType.DXA}, shading:{type:ShadingType.SOLID,color:LGREY}, children:[new Paragraph({children:[new TextRun({text:"Vascular review for varicose veins",font:"Arial",size:22,bold:true})],spacing:{before:80,after:80},indent:{left:100}})], borders:thinLine()}}),
new TableCell({width:{size:6200,type:WidthType.DXA}, children:[new Paragraph({children:[new TextRun({text:"To confirm the appropriate level of exercise intensity and elevation protocol for the lower limbs, and to assess for any vascular intervention that may facilitate safer lower limb rehabilitation",font:"Arial",size:22})],spacing:{before:80,after:80},indent:{left:100}})], borders:thinLine()})
]}),
new TableRow({children:[
new TableCell({width:{size:2800,type:WidthType.DXA}, shading:{type:ShadingType.SOLID,color:LGREY}, children:[new Paragraph({children:[new TextRun({text:"ENT / Neurosurgery awareness",font:"Arial",size:22,bold:true})],spacing:{before:80,after:80},indent:{left:100}})], borders:thinLine()}}),
new TableCell({width:{size:6200,type:WidthType.DXA}, children:[new Paragraph({children:[new TextRun({text:"MRI (02/07/2026) incidentally detected a 1.1 cm Schwannoma in the right cerebello-pontine angle encroaching onto the internal auditory canal. This is flagged for appropriate specialist follow-up outside physiotherapy scope",font:"Arial",size:22})],spacing:{before:80,after:80},indent:{left:100}})], borders:thinLine()})
]}),
new TableRow({children:[
new TableCell({width:{size:2800,type:WidthType.DXA}, shading:{type:ShadingType.SOLID,color:LGREY}, children:[new Paragraph({children:[new TextRun({text:"Confirm medication stable",font:"Arial",size:22,bold:true})],spacing:{before:80,after:80},indent:{left:100}})], borders:thinLine()}}),
new TableCell({width:{size:6200,type:WidthType.DXA}, children:[new Paragraph({children:[new TextRun({text:"Patient is on antiplatelet (Ecosprin + Clopitab), antihypertensive (Telmikind AM), statin (Atorvas 80 mg) and antidiabetic (Gemer 2/500). Blood pressure and blood glucose are monitored at each physiotherapy session",font:"Arial",size:22})],spacing:{before:80,after:80},indent:{left:100}})], borders:thinLine()})
]})
]
}),
sp(100,60),
// ─── SIGNATURE ────────────────────────────────────────────────────────
sec("8. Physiotherapist Declaration"),
body("This report has been prepared to provide the consultant with an accurate account of the physiotherapy management being delivered to Mr. Sumant Tukaram Parab. All treatment decisions are based on clinical assessment findings, current evidence-based stroke rehabilitation guidelines, and the patient's individual functional goals."),
sp(60,20),
new Table({
width:{size:9000,type:WidthType.DXA},
rows:[
infoRow("Physiotherapist:", "[Your Name, Qualifications]"),
infoRow("Registration No.:", "[Your Registration Number]"),
infoRow("Clinic:", "[Your Clinic Name and Address]"),
infoRow("Telephone:", "[Your Contact Number]"),
infoRow("Email:", "[Your Email]"),
infoRow("Date:", "13 July 2026"),
infoRow("Signature:", "_________________________________")
]
}),
sp(60,40),
new Paragraph({
alignment:AlignmentType.CENTER,
children:[new TextRun({text:"This report is confidential and intended solely for the named consultant. Unauthorised disclosure is not permitted.", font:"Arial",size:18,italics:true,color:GREY})],
spacing:{before:160,after:60}
})
]
}]
});
Packer.toBuffer(doc).then(buf => {
fs.writeFileSync('/home/daytona/workspace/physio-report/Physio_Progress_Report_Parab_ForConsultant.docx', buf);
console.log('Done.');
}).catch(e => { console.error(e); process.exit(1); });
cd /home/daytona/workspace/physio-report && node generate_consultant_report.js 2…
~/physio-report/generate_consultant_report.js
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/physio-report/generate_consultant_report.js'
cd /home/daytona/workspace/physio-report && node -e " const src = require('fs').…
~/physio-report/generate_consultant_report.js
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/physio-report/generate_consultant_report.js'
~/physio-report/generate_consultant_report.js
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/physio-report/generate_consultant_report.js'
cd /home/daytona/workspace/physio-report && node generate_consultant_report.js 2…
node --input-type=module < /dev/null; node -e " var s = require('fs').readFileSy…
node -e " try { require('/home/daytona/workspace/physio-report/generate_consul…
~/physio-report/generate_consultant_report.js
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/physio-report/generate_consultant_report.js'
cd /home/daytona/workspace/physio-report && node generate_consultant_report.js 2…
~/physio-report/generate_consultant_report.js
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/physio-report/generate_consultant_report.js'
~/physio-report/generate_consultant_report.js
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/physio-report/generate_consultant_report.js'
cd /home/daytona/workspace/physio-report && node generate_consultant_report.js 2…
~/physio-report/generate_consultant_report.js
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/physio-report/generate_consultant_report.js'
~/physio-report/generate_consultant_report.js
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/physio-report/generate_consultant_report.js'
cd /home/daytona/workspace/physio-report && node generate_consultant_report.js 2…
This contains too much of medical make it physiotherapy management oriented I started physiotherapy session on 10th july till now 3 sessions are done. He has rt hemiparesis with mild facial weakness and slurred speech. Mild-moderate balance impairments according to mini BESTest. As a physiotherapist iam taking his ul elbow wrist and finger roms with red theraband and shoulder aroms with weight cuff o.5 kg.then as pt has varicose veins so atms on elevated position then balance training And stair climbing 7 flights done once . Write a report as the doctor understand about what physiotherapy is going on
Physio Progress Report Parab ForConsultant
Word Document · DOCX
| Treatment | Explanation written for the doctor |
|---|---|
| Elbow, Wrist, Finger ROM with Red Theraband | Explains corticospinal tract disruption, why graded resistance triggers neuroplasticity, why red band is appropriate at this stage |
| Shoulder AROM with 0.5 kg cuff | Explains subluxation risk post-stroke, why 0.5 kg is specifically chosen, proprioceptive feedback rationale |
| Lower limb in elevated position | Explains varicose vein physiology, venous pooling risk, why elevation is a safety precaution not optional |
| Balance training | Explains Mini BESTest systems, how internal capsule lesion disrupts postural control, why training is essential for fall prevention |
| Stair climbing - 7 flights | Explains exactly why 7 flights at 3 sessions post-discharge is a significant milestone - strength, single-leg balance, dorsiflexion, coordination all needed |
Too much colorful make basic black and white with patient details. Initial assessment. Then physiotherapy management in list format ul and ll rom are done 30 reps each and facial and tongue exercise with scapular exercise are also taken. Make it short and concise
~/physio-report/generate_final.js
const {
Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell,
AlignmentType, HeadingLevel, LevelFormat, BorderStyle, WidthType,
ShadingType, PageNumber, Header, Footer
} = require('docx');
const fs = require('fs');
function noBorder() {
return { top:{style:BorderStyle.NONE}, bottom:{style:BorderStyle.NONE}, left:{style:BorderStyle.NONE}, right:{style:BorderStyle.NONE} };
}
function thinBorder() {
return { top:{style:BorderStyle.SINGLE,size:4,color:"AAAAAA"}, bottom:{style:BorderStyle.SINGLE,size:4,color:"AAAAAA"}, left:{style:BorderStyle.NONE}, right:{style:BorderStyle.NONE} };
}
function sp(b=80,a=80){ return new Paragraph({children:[new TextRun("")],spacing:{before:b,after:a}}); }
function secHead(text) {
return new Paragraph({
children:[new TextRun({text:text.toUpperCase(), font:"Arial", bold:true, size:22})],
spacing:{before:240,after:80},
border:{bottom:{style:BorderStyle.SINGLE,size:6,color:"000000",space:4}}
});
}
function bold(text){ return new TextRun({text, font:"Arial", size:22, bold:true}); }
function normal(text){ return new TextRun({text, font:"Arial", size:22}); }
function bul(text){
return new Paragraph({
numbering:{reference:"bullets",level:0},
children:[new TextRun({text, font:"Arial", size:22})],
spacing:{before:40,after:40}
});
}
function infoRow(lbl, val){
return new TableRow({ children:[
new TableCell({
width:{size:2800,type:WidthType.DXA},
children:[new Paragraph({children:[bold(lbl)],spacing:{before:70,after:70}})],
borders:thinBorder()
}),
new TableCell({
width:{size:6000,type:WidthType.DXA},
children:[new Paragraph({children:[normal(val)],spacing:{before:70,after:70}})],
borders:thinBorder()
})
]});
}
const doc = new Document({
numbering:{config:[{reference:"bullets",levels:[{
level:0, format:LevelFormat.BULLET, text:"\u2022", alignment:AlignmentType.LEFT,
style:{paragraph:{indent:{left:640,hanging:320}}}
}]}]},
styles:{
default:{document:{run:{font:"Arial",size:22}}},
paragraphStyles:[
{id:"Heading1",name:"Heading 1",basedOn:"Normal",next:"Normal",quickFormat:true,
run:{size:28,bold:true,font:"Arial",color:"000000"},
paragraph:{spacing:{before:0,after:160},outlineLevel:0}},
{id:"Heading2",name:"Heading 2",basedOn:"Normal",next:"Normal",quickFormat:true,
run:{size:22,bold:true,font:"Arial",color:"000000"},
paragraph:{spacing:{before:240,after:80},outlineLevel:1}}
]
},
sections:[{
properties:{page:{margin:{top:1000,bottom:1000,left:1200,right:1200}}},
headers:{default: new Header({children:[
new Paragraph({
alignment:AlignmentType.RIGHT,
children:[new TextRun({text:"Confidential | For Consultant Use Only", font:"Arial", size:18, italics:true})],
border:{bottom:{style:BorderStyle.SINGLE,size:4,color:"000000",space:4}}
})
]})},
footers:{default: new Footer({children:[
new Paragraph({
alignment:AlignmentType.CENTER,
children:[
new TextRun({text:"[Clinic Name] | [Contact] | Page ", font:"Arial", size:18}),
new TextRun({children:[PageNumber.CURRENT], font:"Arial", size:18}),
new TextRun({text:" of ", font:"Arial", size:18}),
new TextRun({children:[PageNumber.TOTAL_PAGES], font:"Arial", size:18})
],
border:{top:{style:BorderStyle.SINGLE,size:4,color:"000000",space:4}}
})
]})},
children:[
// Title
new Paragraph({
alignment:AlignmentType.CENTER,
children:[new TextRun({text:"PHYSIOTHERAPY PROGRESS REPORT", font:"Arial", size:32, bold:true})],
spacing:{before:100,after:60}
}),
new Paragraph({
alignment:AlignmentType.CENTER,
children:[new TextRun({text:"[Clinic Name] | [Address] | Tel: [Number]", font:"Arial", size:20})],
spacing:{before:0,after:40}
}),
new Paragraph({
alignment:AlignmentType.CENTER,
children:[new TextRun({text:"Date: 13 July 2026", font:"Arial", size:22, bold:true})],
spacing:{before:40,after:200}
}),
// ── 1. PATIENT DETAILS ──────────────────────────────────────────────
secHead("1. Patient Details"),
new Table({
width:{size:8800,type:WidthType.DXA},
rows:[
infoRow("Patient Name:", "Mr. Sumant Tukaram Parab"),
infoRow("Age / Gender:", "70 Years / Male"),
infoRow("Diagnosis:", "Left Internal Capsule Acute Ischaemic Stroke"),
infoRow("Date of Stroke:", "02 July 2026"),
infoRow("Hospital:", "Masina Hospital Trust, Mumbai"),
infoRow("Treating Doctor:", "Dr. Khan Siraj S."),
infoRow("Date of Discharge:", "07 July 2026"),
infoRow("Physio Start Date:", "10 July 2026"),
infoRow("Sessions Completed:", "3 (10, 11, 12 July 2026)"),
infoRow("Report Prepared For:", "[Consultant Name, Speciality]"),
infoRow("Physiotherapist:", "[Your Name, Qualifications, Reg. No.]")
]
}),
sp(100,60),
// ── 2. INITIAL ASSESSMENT ───────────────────────────────────────────
secHead("2. Initial Assessment (10 July 2026)"),
new Paragraph({children:[bold("Presenting Deficits:")], spacing:{before:80,after:40}}),
bul("Right hemiparesis — weakness of right upper and lower limb"),
bul("Mild right-sided facial weakness with deviation of angle of mouth"),
bul("Slurred speech (dysarthria) — mild, improving from hospital"),
bul("Reduced active and passive range of motion — right upper and lower limb"),
bul("Mild-to-moderate balance impairment (Mini Balance Evaluation Systems Test — Mini BESTest)"),
bul("Varicose veins — bilateral lower limbs"),
bul("Gait: unsteady, requires supervision"),
bul("Cognition: conscious, alert, follows commands, cooperative"),
sp(60,40),
new Paragraph({children:[bold("Past History:")], spacing:{before:60,after:40}}),
bul("Type 2 Diabetes Mellitus — on oral hypoglycaemics (Gemer 2/500)"),
bul("Hypertension — on antihypertensive (Telmikind AM)"),
bul("Dyslipidaemia — on statin (Atorvas 80 mg)"),
bul("Antiplatelet therapy: Ecosprin 75 mg + Clopitab 75 mg — continued"),
sp(100,60),
// ── 3. PHYSIOTHERAPY MANAGEMENT ────────────────────────────────────
secHead("3. Physiotherapy Management"),
new Paragraph({children:[bold("A. Upper Limb Exercises")], spacing:{before:80,after:40}}),
bul("Elbow flexion and extension — Red Theraband, 30 repetitions"),
bul("Wrist flexion and extension — Red Theraband, 30 repetitions"),
bul("Finger flexion and extension — Red Theraband, 30 repetitions"),
bul("Shoulder active range of motion (flexion, abduction, extension) — 0.5 kg weight cuff, 30 repetitions"),
bul("Scapular exercises — scapular protraction, retraction and depression to activate periscapular muscles and prevent shoulder subluxation"),
sp(60,40),
new Paragraph({children:[bold("B. Lower Limb Exercises")], spacing:{before:60,after:40}}),
bul("All lower limb exercises performed with limb in elevated position throughout — due to varicose veins (to facilitate venous return and prevent venous pooling)"),
bul("Hip, knee and ankle range of motion — 30 repetitions each"),
bul("Ankle toe pumps and ankle circles — 30 repetitions"),
sp(60,40),
new Paragraph({children:[bold("C. Facial and Oral Motor Exercises")], spacing:{before:60,after:40}}),
bul("Facial exercises: lip pursing, cheek puffing, smile and retraction, symmetrical facial expression practice — to address mild right facial weakness"),
bul("Tongue exercises: tongue protrusion, lateral movements, tongue-to-palate — to improve dysarthria and oral motor control"),
sp(60,40),
new Paragraph({children:[bold("D. Balance Training")], spacing:{before:60,after:40}}),
bul("Static sitting balance at edge of plinth"),
bul("Sit-to-stand practice with supervision"),
bul("Static standing balance at parallel bars — weight shifting right to left"),
bul("Dynamic standing balance — stepping and lateral weight transfer"),
sp(60,40),
new Paragraph({children:[bold("E. Functional Training")], spacing:{before:60,after:40}}),
bul("Stair climbing — 7 flights completed with physiotherapist supervision (Session 3, 12 July 2026)"),
bul("Home exercise programme (HEP) issued and reviewed each session"),
sp(100,60),
// ── 4. PROGRESS ──────────────────────────────────────────────────────
secHead("4. Progress after 3 Sessions"),
new Table({
width:{size:8800,type:WidthType.DXA},
rows:[
new TableRow({children:[
new TableCell({width:{size:3200,type:WidthType.DXA}, children:[new Paragraph({children:[bold("Area")],spacing:{before:70,after:70}})], borders:thinBorder()}),
new TableCell({width:{size:5600,type:WidthType.DXA}, children:[new Paragraph({children:[bold("Status")],spacing:{before:70,after:70}})], borders:thinBorder()})
]}),
new TableRow({children:[new TableCell({width:{size:3200,type:WidthType.DXA},children:[new Paragraph({children:[normal("Right UL ROM")],spacing:{before:70,after:70}})],borders:thinBorder()}),new TableCell({width:{size:5600,type:WidthType.DXA},children:[new Paragraph({children:[normal("Improving — tolerating Theraband resistance well")],spacing:{before:70,after:70}})],borders:thinBorder()})]}),
new TableRow({children:[new TableCell({width:{size:3200,type:WidthType.DXA},children:[new Paragraph({children:[normal("Shoulder AROM")],spacing:{before:70,after:70}})],borders:thinBorder()}),new TableCell({width:{size:5600,type:WidthType.DXA},children:[new Paragraph({children:[normal("Improving — active range increasing with 0.5 kg cuff")],spacing:{before:70,after:70}})],borders:thinBorder()})]}),
new TableRow({children:[new TableCell({width:{size:3200,type:WidthType.DXA},children:[new Paragraph({children:[normal("Balance")],spacing:{before:70,after:70}})],borders:thinBorder()}),new TableCell({width:{size:5600,type:WidthType.DXA},children:[new Paragraph({children:[normal("Improving — progressed from static to dynamic balance")],spacing:{before:70,after:70}})],borders:thinBorder()})]}),
new TableRow({children:[new TableCell({width:{size:3200,type:WidthType.DXA},children:[new Paragraph({children:[normal("Stair Climbing")],spacing:{before:70,after:70}})],borders:thinBorder()}),new TableCell({width:{size:5600,type:WidthType.DXA},children:[new Paragraph({children:[normal("7 flights achieved with supervision — significant functional milestone")],spacing:{before:70,after:70}})],borders:thinBorder()})]}),
new TableRow({children:[new TableCell({width:{size:3200,type:WidthType.DXA},children:[new Paragraph({children:[normal("Facial / Oral Motor")],spacing:{before:70,after:70}})],borders:thinBorder()}),new TableCell({width:{size:5600,type:WidthType.DXA},children:[new Paragraph({children:[normal("Dysarthria mild and stable — SLT referral recommended")],spacing:{before:70,after:70}})],borders:thinBorder()})]}),
new TableRow({children:[new TableCell({width:{size:3200,type:WidthType.DXA},children:[new Paragraph({children:[normal("Lower Limb Safety")],spacing:{before:70,after:70}})],borders:thinBorder()}),new TableCell({width:{size:5600,type:WidthType.DXA},children:[new Paragraph({children:[normal("Varicose vein precaution maintained throughout all sessions")],spacing:{before:70,after:70}})],borders:thinBorder()})]})
]
}),
sp(100,60),
// ── 5. PLAN ──────────────────────────────────────────────────────────
secHead("5. Plan"),
bul("Continue and progress UL and LL ROM and strengthening exercises"),
bul("Increase resistance band grade and weight cuff load as tolerated"),
bul("Progress balance training — reduce support, outdoor walking"),
bul("Progress stair climbing to independence"),
bul("Continue facial and tongue exercises — consider formal SLT referral for dysarthria"),
bul("Introduce gait re-education and fine motor tasks"),
bul("Target: 3-5 sessions per week"),
sp(100,60),
// ── SIGNATURE ────────────────────────────────────────────────────────
secHead("Physiotherapist Details"),
new Table({
width:{size:8800,type:WidthType.DXA},
rows:[
infoRow("Name:", "[Your Full Name, Qualifications]"),
infoRow("Registration No.:","[Your Registration Number]"),
infoRow("Clinic:", "[Clinic Name and Address]"),
infoRow("Date:", "13 July 2026"),
infoRow("Signature:", "_________________________________")
]
}),
sp(60,40),
new Paragraph({
alignment:AlignmentType.CENTER,
children:[new TextRun({text:"This report is confidential and prepared for the named consultant only.", font:"Arial", size:18, italics:true})],
spacing:{before:120,after:60}
})
]
}]
});
Packer.toBuffer(doc).then(buf => {
fs.writeFileSync('/home/daytona/workspace/physio-report/Physio_Report_Parab_Final.docx', buf);
console.log('Done.');
}).catch(e => { console.error(e); process.exit(1); });
cd /home/daytona/workspace/physio-report && node generate_final.js 2>&1 && ls -l…
Physio Report Parab Final
Word Document · DOCX
Generate a physiotherapy assessment template for future stroke patients
~/physio-report/generate_assessment_template.js
const {
Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell,
AlignmentType, HeadingLevel, LevelFormat, BorderStyle, WidthType,
ShadingType, PageNumber, Header, Footer
} = require('docx');
const fs = require('fs');
// ─── Borders ─────────────────────────────────────────────────────────────────
function noBorder() {
return { top:{style:BorderStyle.NONE}, bottom:{style:BorderStyle.NONE}, left:{style:BorderStyle.NONE}, right:{style:BorderStyle.NONE} };
}
function thinBorder() {
return { top:{style:BorderStyle.SINGLE,size:4,color:"888888"}, bottom:{style:BorderStyle.SINGLE,size:4,color:"888888"}, left:{style:BorderStyle.NONE}, right:{style:BorderStyle.NONE} };
}
function allBorder() {
return { top:{style:BorderStyle.SINGLE,size:4,color:"888888"}, bottom:{style:BorderStyle.SINGLE,size:4,color:"888888"}, left:{style:BorderStyle.SINGLE,size:4,color:"888888"}, right:{style:BorderStyle.SINGLE,size:4,color:"888888"} };
}
// ─── Helpers ─────────────────────────────────────────────────────────────────
function sp(b=60,a=60){ return new Paragraph({children:[new TextRun("")],spacing:{before:b,after:a}}); }
function secHead(text){
return new Paragraph({
children:[new TextRun({text:text.toUpperCase(), font:"Arial", bold:true, size:22, color:"000000"})],
spacing:{before:260,after:100},
border:{bottom:{style:BorderStyle.SINGLE,size:8,color:"000000",space:4}}
});
}
function subHead(text){
return new Paragraph({
children:[new TextRun({text, font:"Arial", bold:true, size:22, underline:{type:"single"}})],
spacing:{before:160,after:60}
});
}
function b(text){ return new TextRun({text, font:"Arial", size:22, bold:true}); }
function n(text){ return new TextRun({text, font:"Arial", size:22}); }
function ph(text){ return new TextRun({text:`[${text}]`, font:"Arial", size:22}); }
function bul(text){
return new Paragraph({
numbering:{reference:"bullets",level:0},
children:[n(text)], spacing:{before:40,after:40}
});
}
function line(label, width=8800){
// label + underline fill
return new Paragraph({
children:[
new TextRun({text:label+" ", font:"Arial", size:22, bold:true}),
new TextRun({text:"_".repeat(Math.max(10, Math.floor((width - label.length*7)/8))), font:"Arial", size:22})
],
spacing:{before:100,after:60}
});
}
function checkLine(label){
return new Paragraph({
children:[new TextRun({text:"\u2610 "+label, font:"Arial", size:22})],
spacing:{before:60,after:40}
});
}
function checkRow(...items){
// row of checkboxes inline
return new Paragraph({
children: items.flatMap(it => [
new TextRun({text:"\u2610 ", font:"Arial", size:22}),
new TextRun({text:it+" ", font:"Arial", size:22})
]),
spacing:{before:60,after:60}
});
}
// Label + blank field row in a 2-col table
function fieldRow(lbl, val=""){
return new TableRow({ children:[
new TableCell({
width:{size:2800,type:WidthType.DXA},
children:[new Paragraph({children:[b(lbl)], spacing:{before:70,after:70}})],
borders:thinBorder()
}),
new TableCell({
width:{size:6000,type:WidthType.DXA},
children:[new Paragraph({children:[n(val || "________________________________")], spacing:{before:70,after:70}})],
borders:thinBorder()
})
]});
}
// ROM table row: movement | normal | AROM | PROM | notes
function romRow(movement, normal){
return new TableRow({ children:[
tc(movement, 2000, true),
tc(normal, 1400),
tc("", 1400),
tc("", 1400),
tc("", 2600)
]});
}
function tc(text, w, bold=false){
return new TableCell({
width:{size:w,type:WidthType.DXA},
children:[new Paragraph({children:[new TextRun({text, font:"Arial", size:21, bold})], spacing:{before:70,after:70}, indent:{left:80}})],
borders:allBorder()
});
}
function tcHead(text, w){
return new TableCell({
width:{size:w,type:WidthType.DXA},
shading:{type:ShadingType.SOLID,color:"DDDDDD"},
children:[new Paragraph({children:[b(text)], spacing:{before:70,after:70}, indent:{left:80}})],
borders:allBorder()
});
}
// Muscle power row
function mpRow(muscle, l, r){
return new TableRow({ children:[
tc(muscle, 4400, false),
tc(l || "", 2200),
tc(r || "", 2200)
]});
}
// Simple 2-col table no border
function infoTable(rows){ return new Table({width:{size:8800,type:WidthType.DXA}, rows}); }
// ─── DOCUMENT ─────────────────────────────────────────────────────────────────
const doc = new Document({
numbering:{config:[{reference:"bullets",levels:[{
level:0,format:LevelFormat.BULLET,text:"\u2022",alignment:AlignmentType.LEFT,
style:{paragraph:{indent:{left:640,hanging:320}}}
}]}]},
styles:{
default:{document:{run:{font:"Arial",size:22}}},
paragraphStyles:[
{id:"Heading1",name:"Heading 1",basedOn:"Normal",next:"Normal",quickFormat:true,
run:{size:28,bold:true,font:"Arial",color:"000000"},
paragraph:{spacing:{before:0,after:160},outlineLevel:0}},
{id:"Heading2",name:"Heading 2",basedOn:"Normal",next:"Normal",quickFormat:true,
run:{size:22,bold:true,font:"Arial",color:"000000"},
paragraph:{spacing:{before:260,after:100},outlineLevel:1}}
]
},
sections:[{
properties:{page:{margin:{top:900,bottom:900,left:1100,right:1100}}},
headers:{default: new Header({children:[
new Paragraph({
alignment:AlignmentType.RIGHT,
children:[new TextRun({text:"PHYSIOTHERAPY STROKE ASSESSMENT | CONFIDENTIAL", font:"Arial", size:18, italics:true})],
border:{bottom:{style:BorderStyle.SINGLE,size:4,color:"000000",space:4}}
})
]})},
footers:{default: new Footer({children:[
new Paragraph({
alignment:AlignmentType.CENTER,
children:[
new TextRun({text:"[Clinic Name] | [Contact] | Page ", font:"Arial", size:18}),
new TextRun({children:[PageNumber.CURRENT], font:"Arial", size:18}),
new TextRun({text:" of ", font:"Arial", size:18}),
new TextRun({children:[PageNumber.TOTAL_PAGES], font:"Arial", size:18})
],
border:{top:{style:BorderStyle.SINGLE,size:4,color:"000000",space:4}}
})
]})},
children:[
// ── TITLE ────────────────────────────────────────────────────────────
new Paragraph({
alignment:AlignmentType.CENTER,
children:[new TextRun({text:"PHYSIOTHERAPY ASSESSMENT FORM", font:"Arial", size:32, bold:true})],
spacing:{before:100,after:60}
}),
new Paragraph({
alignment:AlignmentType.CENTER,
children:[n("Post-Stroke Rehabilitation | Initial Assessment")],
spacing:{before:0,after:40}
}),
new Paragraph({
alignment:AlignmentType.CENTER,
children:[n("[Clinic Name] | [Address] | Tel: [Number]")],
spacing:{before:0,after:200}
}),
// ══════════════════════════════════════════════════════════════════════
// 1. PATIENT DETAILS
// ══════════════════════════════════════════════════════════════════════
secHead("1. Patient Details"),
infoTable([
fieldRow("Patient Name:"),
fieldRow("Date of Birth:"," Age: ____"),
fieldRow("Gender:","Male / Female / Other"),
fieldRow("Address:"),
fieldRow("Contact Number:"),
fieldRow("Referring Doctor:"),
fieldRow("Hospital / Clinic:"),
fieldRow("Consultant:"),
fieldRow("Date of Stroke:"),
fieldRow("Date of Admission:"),
fieldRow("Date of Discharge:"),
fieldRow("Date of Assessment:"),
fieldRow("Session Number:"),
fieldRow("Physiotherapist:")
]),
sp(100,60),
// ══════════════════════════════════════════════════════════════════════
// 2. MEDICAL BACKGROUND
// ══════════════════════════════════════════════════════════════════════
secHead("2. Medical Background"),
subHead("Stroke Type:"),
checkRow("Ischaemic","Haemorrhagic","TIA","Unknown"),
sp(40,20),
subHead("Lesion Site (from MRI/CT):"),
line(""),
line(""),
subHead("Side Affected:"),
checkRow("Right hemiplegia / hemiparesis","Left hemiplegia / hemiparesis","Bilateral"),
sp(40,20),
subHead("Past Medical History:"),
checkRow("Hypertension","Diabetes Mellitus","Dyslipidaemia","Atrial Fibrillation"),
checkRow("Previous Stroke / TIA","Cardiac Disease","Renal Disease","Other: ____________"),
sp(40,20),
subHead("Current Medications (relevant):"),
line("Antiplatelet:"),
line("Anticoagulant:"),
line("Antihypertensive:"),
line("Antidiabetic:"),
line("Other:"),
subHead("Precautions / Contraindications:"),
checkRow("Varicose veins","DVT risk","Osteoporosis","Cardiac precautions"),
checkRow("Dysphagia","Falls risk","Skin integrity","Other: ____________"),
sp(100,60),
// ══════════════════════════════════════════════════════════════════════
// 3. SUBJECTIVE ASSESSMENT
// ══════════════════════════════════════════════════════════════════════
secHead("3. Subjective Assessment"),
subHead("Chief Complaints:"),
line(""),
line(""),
line(""),
subHead("Pain (NRS 0-10):"),
new Paragraph({children:[b("At rest: ___/10 With activity: ___/10 Location: ________________________")], spacing:{before:60,after:60}}),
subHead("Functional Limitations:"),
checkRow("Difficulty walking","Difficulty climbing stairs","Unable to use affected hand","Difficulty with self-care"),
checkRow("Difficulty speaking","Difficulty swallowing","Unable to sit unsupported","Other: ____________"),
subHead("Prior Level of Function (before stroke):"),
checkRow("Independent","Required assistance","Wheelchair user","Bed-bound"),
line("Details:"),
subHead("Social History:"),
line("Occupation:"),
line("Living situation:"),
line("Carer / Support:"),
sp(100,60),
// ══════════════════════════════════════════════════════════════════════
// 4. OBJECTIVE ASSESSMENT
// ══════════════════════════════════════════════════════════════════════
secHead("4. Objective Assessment"),
subHead("Vital Signs:"),
new Paragraph({children:[b("BP: ___/___ mmHg HR: ___ bpm SpO2: ___% Temp: ___°C")], spacing:{before:60,after:100}}),
// ── 4a. Neurological ─────────────────────────────────────────────────
subHead("4a. Neurological Status"),
new Paragraph({children:[b("Consciousness: "), n("\u2610 Alert \u2610 Confused \u2610 Drowsy")], spacing:{before:60,after:40}}),
new Paragraph({children:[b("Orientation: "), n("\u2610 Time \u2610 Place \u2610 Person")], spacing:{before:40,after:40}}),
new Paragraph({children:[b("Cognition: "), n("\u2610 Intact \u2610 Mildly impaired \u2610 Moderately impaired MoCA / MMSE score: ___/___")], spacing:{before:40,after:40}}),
new Paragraph({children:[b("Speech: "), n("\u2610 Normal \u2610 Dysarthria (mild / moderate / severe) \u2610 Aphasia (expressive / receptive) \u2610 Mute")], spacing:{before:40,after:40}}),
new Paragraph({children:[b("Facial Weakness: "), n("\u2610 Absent \u2610 Mild right \u2610 Mild left \u2610 Marked right \u2610 Marked left")], spacing:{before:40,after:40}}),
new Paragraph({children:[b("Visual: "), n("\u2610 Intact \u2610 Hemianopia \u2610 Neglect (left / right) \u2610 Diplopia")], spacing:{before:40,after:100}}),
// ── 4b. Tone ─────────────────────────────────────────────────────────
subHead("4b. Muscle Tone (Modified Ashworth Scale: 0 / 1 / 1+ / 2 / 3 / 4)"),
new Table({
width:{size:8800,type:WidthType.DXA},
rows:[
new TableRow({children:[tcHead("Region",3200), tcHead("Right",2800), tcHead("Left",2800)]}),
mpRow("Upper Limb — overall"),
mpRow("Shoulder"),
mpRow("Elbow"),
mpRow("Wrist / Fingers"),
mpRow("Lower Limb — overall"),
mpRow("Hip"),
mpRow("Knee"),
mpRow("Ankle / Foot")
]
}),
sp(40,40),
// ── 4c. Muscle Power ──────────────────────────────────────────────────
subHead("4c. Muscle Power (Oxford Grading: 0-5)"),
new Table({
width:{size:8800,type:WidthType.DXA},
rows:[
new TableRow({children:[tcHead("Muscle Group / Movement",4400), tcHead("Right",2200), tcHead("Left",2200)]}),
mpRow("Shoulder flexion"),
mpRow("Shoulder abduction"),
mpRow("Elbow flexion"),
mpRow("Elbow extension"),
mpRow("Wrist extension"),
mpRow("Grip strength"),
mpRow("Hip flexion"),
mpRow("Knee extension"),
mpRow("Ankle dorsiflexion"),
mpRow("Ankle plantarflexion")
]
}),
sp(40,40),
new Paragraph({children:[n("Grading reference: 0=no contraction | 1=flicker | 2=movement with gravity eliminated | 3=movement against gravity | 4=movement against some resistance | 5=normal")], spacing:{before:40,after:80}}),
// ── 4d. Upper Limb ROM ────────────────────────────────────────────────
subHead("4d. Range of Motion — Upper Limb (Right / Affected Side)"),
new Table({
width:{size:8800,type:WidthType.DXA},
rows:[
new TableRow({children:[tcHead("Movement",2000), tcHead("Normal",1400), tcHead("AROM",1400), tcHead("PROM",1400), tcHead("Pain / Notes",2600)]}),
romRow("Shoulder Flexion","0-180°"),
romRow("Shoulder Abduction","0-180°"),
romRow("Shoulder Ext. Rotation","0-90°"),
romRow("Shoulder Int. Rotation","0-70°"),
romRow("Elbow Flexion","0-145°"),
romRow("Elbow Extension","145-0°"),
romRow("Forearm Supination","0-90°"),
romRow("Forearm Pronation","0-90°"),
romRow("Wrist Flexion","0-80°"),
romRow("Wrist Extension","0-70°"),
romRow("Finger Flexion","Full fist"),
romRow("Finger Extension","Full extension")
]
}),
sp(40,40),
// ── 4e. Lower Limb ROM ────────────────────────────────────────────────
subHead("4e. Range of Motion — Lower Limb (Right / Affected Side)"),
new Table({
width:{size:8800,type:WidthType.DXA},
rows:[
new TableRow({children:[tcHead("Movement",2000), tcHead("Normal",1400), tcHead("AROM",1400), tcHead("PROM",1400), tcHead("Pain / Notes",2600)]}),
romRow("Hip Flexion","0-120°"),
romRow("Hip Extension","0-30°"),
romRow("Hip Abduction","0-45°"),
romRow("Hip Adduction","0-30°"),
romRow("Knee Flexion","0-135°"),
romRow("Knee Extension","135-0°"),
romRow("Ankle Dorsiflexion","0-20°"),
romRow("Ankle Plantarflexion","0-50°"),
romRow("Subtalar Inversion","0-35°"),
romRow("Subtalar Eversion","0-25°")
]
}),
sp(40,40),
// ── 4f. Sensation ─────────────────────────────────────────────────────
subHead("4f. Sensation"),
new Table({
width:{size:8800,type:WidthType.DXA},
rows:[
new TableRow({children:[tcHead("Sensation",2600), tcHead("Right UL",1550), tcHead("Right LL",1550), tcHead("Left UL",1550), tcHead("Left LL",1550)]}),
new TableRow({children:[tc("Light touch",2600),tc("",1550),tc("",1550),tc("",1550),tc("",1550)]}),
new TableRow({children:[tc("Proprioception",2600),tc("",1550),tc("",1550),tc("",1550),tc("",1550)]}),
new TableRow({children:[tc("Pain / Pinprick",2600),tc("",1550),tc("",1550),tc("",1550),tc("",1550)]}),
new TableRow({children:[tc("Vibration",2600),tc("",1550),tc("",1550),tc("",1550),tc("",1550)]})
]
}),
new Paragraph({children:[n("Record: I = Intact | R = Reduced | A = Absent")], spacing:{before:60,after:80}}),
// ── 4g. Reflexes ─────────────────────────────────────────────────────
subHead("4g. Reflexes"),
new Table({
width:{size:8800,type:WidthType.DXA},
rows:[
new TableRow({children:[tcHead("Reflex",3200), tcHead("Right",2800), tcHead("Left",2800)]}),
new TableRow({children:[tc("Biceps jerk",3200),tc("",2800),tc("",2800)]}),
new TableRow({children:[tc("Triceps jerk",3200),tc("",2800),tc("",2800)]}),
new TableRow({children:[tc("Knee jerk",3200),tc("",2800),tc("",2800)]}),
new TableRow({children:[tc("Ankle jerk",3200),tc("",2800),tc("",2800)]}),
new TableRow({children:[tc("Plantar response (Babinski)",3200),tc("",2800),tc("",2800)]})
]
}),
new Paragraph({children:[n("Record: 0 = absent | 1+ = diminished | 2+ = normal | 3+ = brisk | 4+ = clonus")], spacing:{before:60,after:80}}),
// ── 4h. Balance ───────────────────────────────────────────────────────
subHead("4h. Balance Assessment"),
new Paragraph({children:[b("Sitting Balance (static): "), n("\u2610 Unable \u2610 With support \u2610 Independent")], spacing:{before:60,after:40}}),
new Paragraph({children:[b("Sitting Balance (dynamic): "), n("\u2610 Unable \u2610 With support \u2610 Independent")], spacing:{before:40,after:40}}),
new Paragraph({children:[b("Standing Balance (static): "), n("\u2610 Unable \u2610 With support \u2610 Independent Duration: ___ sec")], spacing:{before:40,after:40}}),
new Paragraph({children:[b("Standing Balance (dynamic): "), n("\u2610 Unable \u2610 With support \u2610 Independent")], spacing:{before:40,after:80}}),
new Paragraph({children:[b("Mini BESTest Score: "), n("_____ / 28")], spacing:{before:60,after:40}}),
new Paragraph({children:[n("(0-9 = Severe | 10-19 = Moderate | 20-24 = Mild-Moderate | 25-28 = Mild / Normal)")], spacing:{before:0,after:60}}),
new Paragraph({children:[b("Berg Balance Scale (BBS): "), n("_____ / 56 (< 45 = fall risk)")], spacing:{before:60,after:40}}),
new Paragraph({children:[b("Timed Up and Go (TUG): "), n("_____ seconds (< 12 sec = low fall risk | > 20 sec = high fall risk)")], spacing:{before:40,after:100}}),
// ── 4i. Gait ─────────────────────────────────────────────────────────
subHead("4i. Gait Assessment"),
new Paragraph({children:[b("Ambulatory: "), n("\u2610 Yes \u2610 No \u2610 With assistance")], spacing:{before:60,after:40}}),
new Paragraph({children:[b("Gait Pattern: "), n("\u2610 Normal \u2610 Hemiplegic \u2610 Circumduction \u2610 Scissor \u2610 Steppage")], spacing:{before:40,after:40}}),
new Paragraph({children:[b("Assistive Device: "), n("\u2610 None \u2610 Walking stick \u2610 Tripod \u2610 Walking frame \u2610 Wheelchair")], spacing:{before:40,after:40}}),
new Paragraph({children:[b("Stair Climbing: "), n("\u2610 Unable \u2610 With rail and assistance \u2610 With rail only \u2610 Independent")], spacing:{before:40,after:40}}),
line("Gait notes:"),
// ── 4j. Functional ────────────────────────────────────────────────────
subHead("4j. Functional Assessment"),
new Table({
width:{size:8800,type:WidthType.DXA},
rows:[
new TableRow({children:[tcHead("Activity",4000), tcHead("Independence Level",4800)]}),
new TableRow({children:[tc("Bed mobility (rolling, bridging)",4000), tc("\u2610 Independent \u2610 Min assist \u2610 Mod assist \u2610 Max assist \u2610 Dependent",4800)]}),
new TableRow({children:[tc("Supine to sitting",4000), tc("\u2610 Independent \u2610 Min assist \u2610 Mod assist \u2610 Max assist \u2610 Dependent",4800)]}),
new TableRow({children:[tc("Sit to stand",4000), tc("\u2610 Independent \u2610 Min assist \u2610 Mod assist \u2610 Max assist \u2610 Dependent",4800)]}),
new TableRow({children:[tc("Transfer (bed to chair)",4000), tc("\u2610 Independent \u2610 Min assist \u2610 Mod assist \u2610 Max assist \u2610 Dependent",4800)]}),
new TableRow({children:[tc("Ambulation",4000), tc("\u2610 Independent \u2610 Min assist \u2610 Mod assist \u2610 Max assist \u2610 Dependent",4800)]}),
new TableRow({children:[tc("Dressing",4000), tc("\u2610 Independent \u2610 Min assist \u2610 Mod assist \u2610 Max assist \u2610 Dependent",4800)]}),
new TableRow({children:[tc("Feeding",4000), tc("\u2610 Independent \u2610 Min assist \u2610 Mod assist \u2610 Max assist \u2610 Dependent",4800)]})
]
}),
sp(100,60),
// ══════════════════════════════════════════════════════════════════════
// 5. SPECIFIC STROKE ASSESSMENTS
// ══════════════════════════════════════════════════════════════════════
secHead("5. Specific Stroke Assessments"),
subHead("Fugl-Meyer Assessment — Upper Extremity (FMA-UE):"),
new Paragraph({children:[b("Score: _____ / 66")], spacing:{before:60,after:40}}),
new Paragraph({children:[n("(0-19 = Severe | 20-34 = Marked | 35-49 = Moderate | 50-65 = Mild | 66 = Normal)")], spacing:{before:0,after:80}}),
subHead("Brunnstrom Stage of Recovery:"),
new Table({
width:{size:8800,type:WidthType.DXA},
rows:[
new TableRow({children:[tcHead("Region",2200), tcHead("Stage (I - VI)",3300), tcHead("Notes",3300)]}),
new TableRow({children:[tc("Upper Limb",2200),tc("",3300),tc("",3300)]}),
new TableRow({children:[tc("Hand",2200),tc("",3300),tc("",3300)]}),
new TableRow({children:[tc("Lower Limb",2200),tc("",3300),tc("",3300)]})
]
}),
new Paragraph({children:[n("Stage I = Flaccidity | II = Spasticity begins | III = Spasticity peaks | IV = Spasticity decreasing | V = Complex movements | VI = Normal")], spacing:{before:60,after:80}}),
subHead("Barthel Index:"),
new Paragraph({children:[b("Score: _____ / 100 (0-40 = Severe | 41-60 = Moderate | 61-90 = Mild | 91-99 = Minimal | 100 = Independent)")], spacing:{before:60,after:100}}),
subHead("Modified Rankin Scale (mRS):"),
new Paragraph({children:[b("Grade: _____ (0 = No symptoms | 1 = No significant disability | 2 = Slight disability | 3 = Moderate | 4 = Moderately severe | 5 = Severe | 6 = Death)")], spacing:{before:60,after:100}}),
sp(60,40),
// ══════════════════════════════════════════════════════════════════════
// 6. PHYSIOTHERAPY DIAGNOSIS
// ══════════════════════════════════════════════════════════════════════
secHead("6. Physiotherapy Diagnosis"),
line("Primary problem:"),
line("Contributing factors:"),
line(""),
sp(100,60),
// ══════════════════════════════════════════════════════════════════════
// 7. GOALS
// ══════════════════════════════════════════════════════════════════════
secHead("7. Goal Setting"),
subHead("Short-Term Goals (2-4 weeks):"),
new Paragraph({children:[n("1. _______________________________________________________________________________________")], spacing:{before:60,after:60}}),
new Paragraph({children:[n("2. _______________________________________________________________________________________")], spacing:{before:60,after:60}}),
new Paragraph({children:[n("3. _______________________________________________________________________________________")], spacing:{before:60,after:100}}),
subHead("Long-Term Goals (3-6 months):"),
new Paragraph({children:[n("1. _______________________________________________________________________________________")], spacing:{before:60,after:60}}),
new Paragraph({children:[n("2. _______________________________________________________________________________________")], spacing:{before:60,after:60}}),
new Paragraph({children:[n("3. _______________________________________________________________________________________")], spacing:{before:60,after:100}}),
// ══════════════════════════════════════════════════════════════════════
// 8. TREATMENT PLAN
// ══════════════════════════════════════════════════════════════════════
secHead("8. Physiotherapy Treatment Plan"),
subHead("Upper Limb:"),
checkLine("Passive ROM — shoulder, elbow, wrist, fingers"),
checkLine("Active-assisted ROM — shoulder, elbow, wrist, fingers"),
checkLine("Active ROM with Theraband resistance — elbow, wrist, fingers | Reps: ______ Band colour: ______"),
checkLine("Shoulder AROM with weight cuff | Weight: ______ Reps: ______"),
checkLine("Scapular exercises — protraction, retraction, depression"),
checkLine("Mirror therapy"),
checkLine("Task-specific training — reaching, gripping, pinching"),
checkLine("NMES / FES | Area: ______"),
checkLine("Shoulder subluxation management — sling / taping"),
checkLine("Other: ________________________________"),
sp(40,20),
subHead("Lower Limb:"),
checkLine("Passive ROM — hip, knee, ankle | Position: \u2610 Supine \u2610 Elevated (varicose veins)"),
checkLine("Active-assisted ROM — hip, knee, ankle | Reps: ______"),
checkLine("Ankle toe pumps and ankle circles | Reps: ______"),
checkLine("Bridging / hip extension exercises | Reps: ______"),
checkLine("Sit-to-stand practice | Sets / Reps: ______"),
checkLine("Treadmill training | Speed: ______ Duration: ______"),
checkLine("Other: ________________________________"),
sp(40,20),
subHead("Facial and Oral Motor Exercises:"),
checkLine("Lip pursing and lip retraction | Reps: ______"),
checkLine("Cheek puffing and cheek sucking | Reps: ______"),
checkLine("Smile and symmetrical facial expression practice | Reps: ______"),
checkLine("Tongue protrusion and retraction | Reps: ______"),
checkLine("Tongue lateral movements (left and right) | Reps: ______"),
checkLine("Tongue to palate press | Reps: ______"),
checkLine("Jaw opening and closing | Reps: ______"),
checkLine("SLT referral recommended \u2610 Yes \u2610 No"),
sp(40,20),
subHead("Balance and Gait:"),
checkLine("Static sitting balance on plinth"),
checkLine("Dynamic sitting balance — trunk rotation, lateral reach"),
checkLine("Static standing balance — parallel bars / with support"),
checkLine("Dynamic standing — weight shifting, stepping"),
checkLine("Sit-to-stand | Reps: ______"),
checkLine("Gait re-education | Assistance level: ______"),
checkLine("Stair climbing | Flights: ______ Rail: \u2610 Yes \u2610 No Assistance: \u2610 Yes \u2610 No"),
checkLine("Outdoor / uneven terrain walking"),
checkLine("Other: ________________________________"),
sp(40,20),
subHead("Other Interventions:"),
checkLine("TENS | Area: ______ Duration: ______"),
checkLine("Respiratory physiotherapy"),
checkLine("Hydrotherapy"),
checkLine("HEP (Home Exercise Programme) issued \u2610 Yes \u2610 No"),
checkLine("Carer training provided \u2610 Yes \u2610 No"),
checkLine("Positioning advice given \u2610 Yes \u2610 No"),
sp(100,60),
// ══════════════════════════════════════════════════════════════════════
// 9. MDT REFERRALS
// ══════════════════════════════════════════════════════════════════════
secHead("9. MDT Referrals"),
new Table({
width:{size:8800,type:WidthType.DXA},
rows:[
new TableRow({children:[tcHead("Team",2800), tcHead("Referred",1500), tcHead("Date",1800), tcHead("Reason",2700)]}),
new TableRow({children:[tc("Speech and Language Therapy",2800),tc("\u2610 Yes \u2610 No",1500),tc("",1800),tc("",2700)]}),
new TableRow({children:[tc("Occupational Therapy",2800),tc("\u2610 Yes \u2610 No",1500),tc("",1800),tc("",2700)]}),
new TableRow({children:[tc("Orthotics",2800),tc("\u2610 Yes \u2610 No",1500),tc("",1800),tc("",2700)]}),
new TableRow({children:[tc("Neuropsychology",2800),tc("\u2610 Yes \u2610 No",1500),tc("",1800),tc("",2700)]}),
new TableRow({children:[tc("Dietitian",2800),tc("\u2610 Yes \u2610 No",1500),tc("",1800),tc("",2700)]}),
new TableRow({children:[tc("Social Work",2800),tc("\u2610 Yes \u2610 No",1500),tc("",1800),tc("",2700)]}),
new TableRow({children:[tc("Other: ____________",2800),tc("\u2610 Yes \u2610 No",1500),tc("",1800),tc("",2700)]})
]
}),
sp(100,60),
// ══════════════════════════════════════════════════════════════════════
// 10. PHYSIOTHERAPIST SIGN-OFF
// ══════════════════════════════════════════════════════════════════════
secHead("10. Physiotherapist Details"),
infoTable([
fieldRow("Name:"),
fieldRow("Qualifications:"),
fieldRow("Registration No.:"),
fieldRow("Clinic:"),
fieldRow("Date:"),
fieldRow("Signature:","_________________________________")
]),
sp(60,40),
new Paragraph({
alignment:AlignmentType.CENTER,
children:[new TextRun({text:"This assessment form is confidential and for clinical use only.", font:"Arial", size:18, italics:true})],
spacing:{before:100,after:60}
})
]
}]
});
Packer.toBuffer(doc).then(buf => {
fs.writeFileSync('/home/daytona/workspace/physio-report/Stroke_Physio_Assessment_Template.docx', buf);
console.log('Done.');
}).catch(e => { console.error(e); process.exit(1); });
cd /home/daytona/workspace/physio-report && node generate_assessment_template.js…
ls -lh /home/daytona/workspace/physio-report/Stroke_Physio_Assessment_Template.d…
Stroke Physio Assessment Template
Word Document · DOCX
How to make physiotherapy management according to SMART goals . Give me reference and books
Search PubMed for research papers on SMART goals in stroke rehabilitation