@imranq2/fhirpatientsummary 1.0.30 → 1.0.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/index.cjs +129 -112
  2. package/dist/index.js +129 -112
  3. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -938,6 +938,12 @@ var TemplateUtilities = class {
938
938
  const escapedText = text.replace(/</g, "&lt;").replace(/>/g, "&gt;");
939
939
  return escapedText.replace(/\n/g, "<br />");
940
940
  }
941
+ capitalizeFirstLetter(text) {
942
+ if (!text || text.length === 0) {
943
+ return "";
944
+ }
945
+ return text.charAt(0).toUpperCase() + text.slice(1);
946
+ }
941
947
  /**
942
948
  * Renders note elements from a FHIR resource in a standardized format
943
949
  * Can render as simple comma-separated text or as styled HTML with timestamps
@@ -1435,7 +1441,8 @@ var PatientTemplate = class _PatientTemplate {
1435
1441
  static generateStaticNarrative(resources, timezone) {
1436
1442
  const templateUtilities = new TemplateUtilities(resources);
1437
1443
  const combinedPatient = this.combinePatients(resources);
1438
- return `<div>
1444
+ let html = `<p>This section merges all Patient resources into a single combined patient record, preferring non-empty values for each field.</p>`;
1445
+ html += `<div>
1439
1446
  <ul>
1440
1447
  <li><strong>Name(s):</strong>${this.renderNames(combinedPatient)}</li>
1441
1448
  <li><strong>Gender:</strong>${combinedPatient.gender ? this.capitalize(combinedPatient.gender) : ""}</li>
@@ -1447,6 +1454,7 @@ var PatientTemplate = class _PatientTemplate {
1447
1454
  <li><strong>Language(s):</strong>${this.renderCommunication(templateUtilities, combinedPatient)}</li>
1448
1455
  </ul>
1449
1456
  </div>`;
1457
+ return html;
1450
1458
  }
1451
1459
  /**
1452
1460
  * Combines multiple patient resources into a single patient object
@@ -1771,7 +1779,9 @@ var AllergyIntoleranceTemplate = class _AllergyIntoleranceTemplate {
1771
1779
  generateSummaryNarrative(resources, timezone) {
1772
1780
  const templateUtilities = new TemplateUtilities(resources);
1773
1781
  let isSummaryCreated = false;
1774
- let html = `
1782
+ let html = `<p>This list includes all AllergyIntolerance resources, with no additional filtering, sorted as provided.</p>
1783
+ `;
1784
+ html += `
1775
1785
  <div>
1776
1786
  <table>
1777
1787
  <thead>
@@ -1810,7 +1820,7 @@ var AllergyIntoleranceTemplate = class _AllergyIntoleranceTemplate {
1810
1820
  isSummaryCreated = true;
1811
1821
  html += `
1812
1822
  <tr>
1813
- <td>${data["allergen"] ?? ""}</td>
1823
+ <td>${templateUtilities.capitalizeFirstLetter(data["allergen"] ?? "")}</td>
1814
1824
  <td>${data["codeSystem"] ?? ""}</td>
1815
1825
  <td>${data["criticality"] ?? ""}</td>
1816
1826
  <td>${templateUtilities.renderTime(data["recordedDate"], timezone) ?? ""}</td>
@@ -1853,7 +1863,8 @@ var AllergyIntoleranceTemplate = class _AllergyIntoleranceTemplate {
1853
1863
  const dateB = b.onsetDateTime;
1854
1864
  return dateA && dateB ? new Date(dateB).getTime() - new Date(dateA).getTime() : 0;
1855
1865
  });
1856
- let html = "";
1866
+ let html = `<p>This list includes all AllergyIntolerance resources, with no additional filtering, sorted as provided.</p>
1867
+ `;
1857
1868
  html += `
1858
1869
  <div class="ActiveAllergies">
1859
1870
  <h3>Active</h3>
@@ -1927,8 +1938,8 @@ var AllergyIntoleranceTemplate = class _AllergyIntoleranceTemplate {
1927
1938
  let html = "";
1928
1939
  for (const allergy of allergies) {
1929
1940
  html += `
1930
- <tr id="${templateUtilities.narrativeLinkId(allergy.extension)}">
1931
- <td class="Name"><span class="AllergenName">${templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(allergy.code))}</span></td>
1941
+ <tr>
1942
+ <td class="Name"><span class="AllergenName">${templateUtilities.capitalizeFirstLetter(templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(allergy.code)))}</span></td>
1932
1943
  <td class="Status">${templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(allergy.clinicalStatus)) || ""}</td>
1933
1944
  <td class="CodeSystem">${templateUtilities.codeableConceptCoding(allergy.code)}</td>
1934
1945
  <td class="Category">${templateUtilities.renderTextAsHtml(templateUtilities.safeConcat(allergy.category)) || ""}</td>
@@ -1979,7 +1990,8 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
1979
1990
  let isSummaryCreated = false;
1980
1991
  const currentDate = now || /* @__PURE__ */ new Date();
1981
1992
  const twoYearsAgo = new Date(currentDate.getFullYear(), currentDate.getMonth() - 24, currentDate.getDate());
1982
- let html = `
1993
+ let html = "<p>This list includes all the medications that were ordered for the patient, the medications they filled from the pharmacy and the medications they reported, filtered to past 2 years and sorted by start date.</p>";
1994
+ html += `
1983
1995
  <div>
1984
1996
  <table>
1985
1997
  <thead>
@@ -2044,7 +2056,7 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
2044
2056
  isSummaryCreated = true;
2045
2057
  html += `
2046
2058
  <tr>
2047
- <td>${templateUtilities.renderTextAsHtml(data["medication"])}</td>
2059
+ <td>${templateUtilities.capitalizeFirstLetter(templateUtilities.renderTextAsHtml(data["medication"]))}</td>
2048
2060
  <td>${templateUtilities.codeableConceptCoding(sectionCodeableConcept)}</td>
2049
2061
  <td>${templateUtilities.renderTextAsHtml(data["status"])}</td>
2050
2062
  <td>${templateUtilities.renderTextAsHtml(data["sig-prescriber"] || data["sig-pharmacy"])}</td>
@@ -2091,8 +2103,8 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
2091
2103
  static generateStaticNarrative(resources, timezone, now) {
2092
2104
  const templateUtilities = new TemplateUtilities(resources);
2093
2105
  let html = "";
2094
- const medicationRequests = this.getMedicationRequests(templateUtilities, resources);
2095
- const medicationStatements = this.getMedicationStatements(templateUtilities, resources);
2106
+ const medicationRequests = resources.filter((entry) => entry.resourceType === "MedicationRequest");
2107
+ const medicationStatements = resources.filter((entry) => entry.resourceType === "MedicationStatement");
2096
2108
  const allActiveMedications = [];
2097
2109
  const currentDate = now || /* @__PURE__ */ new Date();
2098
2110
  const twoYearsAgo = new Date(currentDate);
@@ -2100,10 +2112,10 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
2100
2112
  let skippedMedications = 0;
2101
2113
  const allMedications = [];
2102
2114
  medicationRequests.forEach((mr) => {
2103
- allMedications.push({ type: "request", resource: mr.resource, extension: mr.extension });
2115
+ allMedications.push({ type: "request", resource: mr });
2104
2116
  });
2105
2117
  medicationStatements.forEach((ms) => {
2106
- allMedications.push({ type: "statement", resource: ms.resource, extension: ms.extension });
2118
+ allMedications.push({ type: "statement", resource: ms });
2107
2119
  });
2108
2120
  for (const med of allMedications) {
2109
2121
  let dateString;
@@ -2160,36 +2172,6 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
2160
2172
  }
2161
2173
  return "";
2162
2174
  }
2163
- /**
2164
- * Extract MedicationRequest resources
2165
- * @param templateUtilities - Instance of TemplateUtilities for utility functions
2166
- * @param resources - FHIR Medication resources
2167
- * @returns Array of MedicationRequest resources
2168
- */
2169
- static getMedicationRequests(templateUtilities, resources) {
2170
- if (resources.length === 0) {
2171
- return [];
2172
- }
2173
- return resources.filter((entry) => entry.resourceType === "MedicationRequest").map((entry) => ({
2174
- resource: entry,
2175
- extension: templateUtilities.narrativeLinkExtension(entry)
2176
- }));
2177
- }
2178
- /**
2179
- * Extract MedicationStatement resources
2180
- * @param templateUtilities - Instance of TemplateUtilities for utility functions
2181
- * @param resources - FHIR Medication resources
2182
- * @returns Array of MedicationStatement resources
2183
- */
2184
- static getMedicationStatements(templateUtilities, resources) {
2185
- if (resources.length === 0) {
2186
- return [];
2187
- }
2188
- return resources.filter((entry) => entry.resourceType === "MedicationStatement").map((entry) => ({
2189
- resource: entry,
2190
- extension: templateUtilities.narrativeLinkExtension(entry)
2191
- }));
2192
- }
2193
2175
  /**
2194
2176
  * Render HTML table for combined MedicationRequest and MedicationStatement resources
2195
2177
  * @param templateUtilities - Instance of TemplateUtilities for utility functions
@@ -2213,7 +2195,6 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
2213
2195
  </thead>
2214
2196
  <tbody>`;
2215
2197
  for (const medication of medications) {
2216
- const narrativeLinkId = templateUtilities.narrativeLinkId(medication.extension);
2217
2198
  let type;
2218
2199
  let medicationName;
2219
2200
  let sig;
@@ -2260,9 +2241,9 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
2260
2241
  }
2261
2242
  }
2262
2243
  html += `
2263
- <tr${narrativeLinkId ? ` id="${narrativeLinkId}"` : ""}>
2244
+ <tr>
2264
2245
  <td>${type}</td>
2265
- <td>${medicationName}<ul></ul></td>
2246
+ <td>${templateUtilities.capitalizeFirstLetter(medicationName)}</td>
2266
2247
  <td>${codeSystemDisplay}</td>
2267
2248
  <td>${sig}</td>
2268
2249
  <td>${dispenseQuantity}</td>
@@ -2305,6 +2286,7 @@ var ImmunizationsTemplate = class _ImmunizationsTemplate {
2305
2286
  let isSummaryCreated = false;
2306
2287
  let html = `
2307
2288
  <div>
2289
+ <p>This list includes all vaccinations, sorted by occurrence date (most recent first).</p>
2308
2290
  <table>
2309
2291
  <thead>
2310
2292
  <tr>
@@ -2343,7 +2325,7 @@ var ImmunizationsTemplate = class _ImmunizationsTemplate {
2343
2325
  isSummaryCreated = true;
2344
2326
  html += `
2345
2327
  <tr>
2346
- <td>${data["immunization"] ?? ""}</td>
2328
+ <td>${templateUtilities.capitalizeFirstLetter(data["immunization"] ?? "")}</td>
2347
2329
  <td>${data["codeSystem"] ?? ""}</td>
2348
2330
  <td>${data["status"] ?? ""}</td>
2349
2331
  <td>${templateUtilities.renderTime(data["occurrenceDateTime"], timezone) ?? ""}</td>
@@ -2387,8 +2369,8 @@ var ImmunizationsTemplate = class _ImmunizationsTemplate {
2387
2369
  for (const resourceItem of immunizations) {
2388
2370
  const imm = resourceItem;
2389
2371
  html += `
2390
- <tr id="${templateUtilities.narrativeLinkId(imm)}">
2391
- <td>${templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(imm.vaccineCode))}</td>
2372
+ <tr>
2373
+ <td>${templateUtilities.capitalizeFirstLetter(templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(imm.vaccineCode)))}</td>
2392
2374
  <td>${templateUtilities.codeableConceptCoding(imm.vaccineCode)}</td>
2393
2375
  <td>${imm.status || ""}</td>
2394
2376
  <td>${templateUtilities.concatDoseNumber(imm.protocolApplied)}</td>
@@ -2427,7 +2409,8 @@ var ProblemListTemplate = class _ProblemListTemplate {
2427
2409
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
2428
2410
  static generateStaticNarrative(resources, timezone) {
2429
2411
  const templateUtilities = new TemplateUtilities(resources);
2430
- let html = ``;
2412
+ let html = `<p>This list includes patient problems, sorted by recorded date (most recent first)</p>
2413
+ `;
2431
2414
  const activeConditions = resources.map((entry) => entry) || [];
2432
2415
  activeConditions.sort((a, b) => {
2433
2416
  if (!a.recordedDate && b.recordedDate) return -1;
@@ -2457,8 +2440,8 @@ var ProblemListTemplate = class _ProblemListTemplate {
2457
2440
  continue;
2458
2441
  }
2459
2442
  seenCodeAndSystems.add(codeAndSystem);
2460
- html += `<tr id="${templateUtilities.narrativeLinkId(cond)}">
2461
- <td class="Name">${conditionDisplay}</td>
2443
+ html += `<tr>
2444
+ <td class="Name">${templateUtilities.capitalizeFirstLetter(conditionDisplay)}</td>
2462
2445
  <td class="CodeSystem">${codeAndSystem}</td>
2463
2446
  <td class="OnsetDate">${templateUtilities.renderDate(cond.onsetDateTime)}</td>
2464
2447
  <td class="RecordedDate">${templateUtilities.renderDate(cond.recordedDate)}</td>
@@ -2491,7 +2474,9 @@ var VitalSignsTemplate = class _VitalSignsTemplate {
2491
2474
  generateSummaryNarrative(resources, timezone) {
2492
2475
  const templateUtilities = new TemplateUtilities(resources);
2493
2476
  let isSummaryCreated = false;
2494
- let html = `
2477
+ let html = `<p>This list includes the latest vital signs, sorted by effective date (most recent first).</p>
2478
+ `;
2479
+ html += `
2495
2480
  <div>
2496
2481
  <table>
2497
2482
  <thead>
@@ -2536,7 +2521,7 @@ var VitalSignsTemplate = class _VitalSignsTemplate {
2536
2521
  isSummaryCreated = true;
2537
2522
  html += `
2538
2523
  <tr>
2539
- <td>${data["Vital Name"] ?? ""}</td>
2524
+ <td>${templateUtilities.capitalizeFirstLetter(data["Vital Name"] ?? "")}</td>
2540
2525
  <td>${data["codeSystem"] ?? ""}</td>
2541
2526
  <td>${templateUtilities.extractObservationSummaryValue(data, timezone) ?? ""}</td>
2542
2527
  <td>${templateUtilities.extractObservationSummaryEffectiveTime(data, timezone) ?? ""}</td>
@@ -2564,7 +2549,9 @@ var VitalSignsTemplate = class _VitalSignsTemplate {
2564
2549
  const dateB = b.effectiveDateTime || b.effectivePeriod?.start;
2565
2550
  return dateA && dateB ? new Date(dateB).getTime() - new Date(dateA).getTime() : 0;
2566
2551
  });
2567
- let html = `
2552
+ let html = `<p>This list includes the latest vital signs, sorted by effective date (most recent first).</p>
2553
+ `;
2554
+ html += `
2568
2555
  <table>
2569
2556
  <thead>
2570
2557
  <tr>
@@ -2582,8 +2569,8 @@ var VitalSignsTemplate = class _VitalSignsTemplate {
2582
2569
  <tbody>`;
2583
2570
  for (const obs of observations) {
2584
2571
  html += `
2585
- <tr id="${templateUtilities.narrativeLinkId(obs)}">
2586
- <td>${templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(obs.code, "display"))}</td>
2572
+ <tr>
2573
+ <td>${templateUtilities.capitalizeFirstLetter(templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(obs.code, "display")))}</td>
2587
2574
  <td>${templateUtilities.codeableConceptCoding(obs.code)}</td>
2588
2575
  <td>${templateUtilities.extractObservationValue(obs)}</td>
2589
2576
  <td>${templateUtilities.extractObservationValueUnit(obs)}</td>
@@ -2620,7 +2607,7 @@ var MedicalDevicesTemplate = class _MedicalDevicesTemplate {
2620
2607
  */
2621
2608
  static generateStaticNarrative(resources, timezone) {
2622
2609
  const templateUtilities = new TemplateUtilities(resources);
2623
- let html = `
2610
+ let html = `<p>This list includes all DeviceUseStatement resources, sorted by recorded date (most recent first).</p>
2624
2611
  <table>
2625
2612
  <thead>
2626
2613
  <tr>
@@ -2636,10 +2623,12 @@ var MedicalDevicesTemplate = class _MedicalDevicesTemplate {
2636
2623
  const dateB = b.recordedOn;
2637
2624
  return typeof dateA === "string" && typeof dateB === "string" ? new Date(dateB).getTime() - new Date(dateA).getTime() : 0;
2638
2625
  });
2626
+ let isDeviceAdded = false;
2639
2627
  for (const dus of deviceStatements) {
2628
+ isDeviceAdded = true;
2640
2629
  html += `
2641
- <tr id="${templateUtilities.narrativeLinkId(dus)}">
2642
- <td>${templateUtilities.renderTextAsHtml(templateUtilities.renderDevice(dus.device))}</td>
2630
+ <tr>
2631
+ <td>${templateUtilities.capitalizeFirstLetter(templateUtilities.renderTextAsHtml(templateUtilities.renderDevice(dus.device)))}</td>
2643
2632
  <td>${templateUtilities.renderTextAsHtml(dus.status || "")}</td>
2644
2633
  <td>${templateUtilities.renderNotes(dus.note, timezone)}</td>
2645
2634
  <td>${templateUtilities.renderTextAsHtml(templateUtilities.renderRecorded(dus.recordedOn, timezone))}</td>
@@ -2648,7 +2637,7 @@ var MedicalDevicesTemplate = class _MedicalDevicesTemplate {
2648
2637
  html += `
2649
2638
  </tbody>
2650
2639
  </table>`;
2651
- return html;
2640
+ return isDeviceAdded ? html : void 0;
2652
2641
  }
2653
2642
  };
2654
2643
 
@@ -2999,11 +2988,12 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
2999
2988
  }
3000
2989
  }
3001
2990
  }
3002
- let html = `
3003
- <div>`;
2991
+ let html = `<p>This section includes Observations from the last 2 years (one per lab name, using code mapping) and DiagnosticReports with status 'final' issued in the last 2 years. Both are sorted by date (most recent first). Older results are counted and noted below the tables.</p>
2992
+ `;
3004
2993
  let observationhtml = `
3005
2994
  <div>
3006
2995
  <h3>Observations</h3>
2996
+ ${html}
3007
2997
  <table>
3008
2998
  <thead>
3009
2999
  <tr>
@@ -3019,6 +3009,7 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
3019
3009
  let diagnosticReporthtml = `
3020
3010
  <div>
3021
3011
  <h3>Diagnostic Reports</h3>
3012
+ ${html}
3022
3013
  <table>
3023
3014
  <thead>
3024
3015
  <tr>
@@ -3103,7 +3094,7 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
3103
3094
  this.formatSummaryObservationData(component);
3104
3095
  observationhtml += `
3105
3096
  <tr>
3106
- <td>${componentCode}</td>
3097
+ <td>${templateUtilities.capitalizeFirstLetter(componentCode)}</td>
3107
3098
  <td></td>
3108
3099
  <td>${templateUtilities.renderTextAsHtml(component["formattedValue"]) ?? ""}</td>
3109
3100
  <td>${templateUtilities.renderTextAsHtml(component["referenceRange"])?.trim() ?? ""}</td>
@@ -3120,7 +3111,7 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
3120
3111
  this.formatSummaryObservationData(data);
3121
3112
  observationhtml += `
3122
3113
  <tr>
3123
- <td>${data["code"] ?? ""}</td>
3114
+ <td>${templateUtilities.capitalizeFirstLetter(data["code"] ?? "")}</td>
3124
3115
  <td>${templateUtilities.codeableConceptCoding(sectionCodeableConcept)}</td>
3125
3116
  <td>${templateUtilities.renderTextAsHtml(data["formattedValue"]) ?? ""}</td>
3126
3117
  <td>${templateUtilities.renderTextAsHtml(data["referenceRange"])?.trim() ?? ""}</td>
@@ -3141,7 +3132,7 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
3141
3132
  diagnosticReportAdded.add(reportName);
3142
3133
  diagnosticReporthtml += `
3143
3134
  <tr>
3144
- <td>${data["report"] ?? ""}</td>
3135
+ <td>${templateUtilities.capitalizeFirstLetter(data["report"] ?? "")}</td>
3145
3136
  <td>${data["performer"] ?? ""}</td>
3146
3137
  <td>${templateUtilities.renderTime(data["issued"], timezone) ?? ""}</td>
3147
3138
  <td>${data["source"] ?? ""}</td>
@@ -3189,7 +3180,8 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
3189
3180
  const currentDate = now || /* @__PURE__ */ new Date();
3190
3181
  const twoYearsAgo = new Date(currentDate);
3191
3182
  twoYearsAgo.setFullYear(currentDate.getFullYear() - 2);
3192
- let html = "";
3183
+ let html = `<p>This section includes Observations from the last 2 years (one per lab name, using code mapping) and DiagnosticReports with status 'final' issued in the last 2 years. Both are sorted by date (most recent first). Older results are counted and noted below the tables.</p>
3184
+ `;
3193
3185
  let skippedObservations = 0;
3194
3186
  let skippedDiagnosticReports = 0;
3195
3187
  for (const resourceItem of resources) {
@@ -3340,8 +3332,8 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
3340
3332
  observationAdded.add(obsCodeDisplay);
3341
3333
  observationAdded.add(obsCodeAndSystem);
3342
3334
  html += `
3343
- <tr id="${templateUtilities.narrativeLinkId(obs)}">
3344
- <td>${obsCodeDisplay}</td>
3335
+ <tr>
3336
+ <td>${templateUtilities.capitalizeFirstLetter(obsCodeDisplay)}</td>
3345
3337
  <td>${templateUtilities.codeableConceptCoding(obs.code)}</td>
3346
3338
  <td>${templateUtilities.extractObservationValue(obs)}</td>
3347
3339
  <td>${templateUtilities.concatReferenceRange(obs.referenceRange)}</td>
@@ -3389,8 +3381,8 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
3389
3381
  resultCount = `${report.result.length} result${report.result.length !== 1 ? "s" : ""}`;
3390
3382
  }
3391
3383
  html += `
3392
- <tr id="${templateUtilities.narrativeLinkId(report)}">
3393
- <td>${reportName}</td>
3384
+ <tr>
3385
+ <td>${templateUtilities.capitalizeFirstLetter(reportName)}</td>
3394
3386
  <td>${codeAndSystem}</td>
3395
3387
  <td>${templateUtilities.firstFromCodeableConceptList(report.category)}</td>
3396
3388
  <td>${resultCount}</td>
@@ -3451,7 +3443,9 @@ var HistoryOfProceduresTemplate = class _HistoryOfProceduresTemplate {
3451
3443
  generateSummaryNarrative(resources, timezone) {
3452
3444
  const templateUtilities = new TemplateUtilities(resources);
3453
3445
  let isSummaryCreated = false;
3454
- let html = `
3446
+ let html = `<p>This list includes all Procedure resources, sorted by performed date (most recent first).</p>
3447
+ `;
3448
+ html += `
3455
3449
  <div>
3456
3450
  <table>
3457
3451
  <thead>
@@ -3490,7 +3484,7 @@ var HistoryOfProceduresTemplate = class _HistoryOfProceduresTemplate {
3490
3484
  isSummaryCreated = true;
3491
3485
  html += `
3492
3486
  <tr>
3493
- <td>${data["procedure"] ?? ""}</td>
3487
+ <td>${templateUtilities.capitalizeFirstLetter(data["procedure"] ?? "")}</td>
3494
3488
  <td>${data["codeSystem"] ?? ""}</td>
3495
3489
  <td>${data["performer"] ?? ""}</td>
3496
3490
  <td>${templateUtilities.renderTime(data["date"], timezone) ?? ""}</td>
@@ -3512,7 +3506,9 @@ var HistoryOfProceduresTemplate = class _HistoryOfProceduresTemplate {
3512
3506
  */
3513
3507
  static generateStaticNarrative(resources, timezone) {
3514
3508
  const templateUtilities = new TemplateUtilities(resources);
3515
- let html = `
3509
+ let html = `<p>This list includes all Procedure resources, sorted by performed date (most recent first).</p>
3510
+ `;
3511
+ html += `
3516
3512
  <table>
3517
3513
  <thead>
3518
3514
  <tr>
@@ -3527,12 +3523,12 @@ var HistoryOfProceduresTemplate = class _HistoryOfProceduresTemplate {
3527
3523
  for (const resourceItem of resources) {
3528
3524
  const proc = resourceItem;
3529
3525
  html += `
3530
- <tr id="${templateUtilities.narrativeLinkId(proc)}">
3531
- <td>${templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(proc.code, "display"))}</td>
3532
- <td>${templateUtilities.codeableConceptCoding(proc.code)}</td>
3526
+ <tr>
3527
+ <td>${templateUtilities.capitalizeFirstLetter(templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(proc.code, "display")))}</td>
3528
+ <td>${templateUtilities.codeableConceptCoding(proc.code)}</td>
3533
3529
  <td>${templateUtilities.renderNotes(proc.note, timezone)}</td>
3534
- <td>${proc.performedDateTime ? templateUtilities.renderTime(proc.performedDateTime, timezone) : proc.performedPeriod ? templateUtilities.renderPeriod(proc.performedPeriod, timezone) : ""}</td>
3535
- <td>${templateUtilities.getOwnerTag(proc)}</td>
3530
+ <td>${templateUtilities.renderTime(proc.performedDateTime || proc.performedPeriod?.start, timezone)}</td>
3531
+ <td>${templateUtilities.getOwnerTag(proc)}</td>
3536
3532
  </tr>`;
3537
3533
  }
3538
3534
  html += `
@@ -3567,7 +3563,9 @@ var SocialHistoryTemplate = class _SocialHistoryTemplate {
3567
3563
  const dateB = b.effectiveDateTime || b.effectivePeriod?.start;
3568
3564
  return dateA && dateB ? new Date(dateB).getTime() - new Date(dateA).getTime() : 0;
3569
3565
  });
3570
- let html = `
3566
+ let html = `<p>This list includes all information about the patient's social history, sorted by effective date (most recent first).</p>
3567
+ `;
3568
+ html += `
3571
3569
  <table>
3572
3570
  <thead>
3573
3571
  <tr>
@@ -3581,17 +3579,22 @@ var SocialHistoryTemplate = class _SocialHistoryTemplate {
3581
3579
  </tr>
3582
3580
  </thead>
3583
3581
  <tbody>`;
3582
+ const addedObservations = /* @__PURE__ */ new Set();
3584
3583
  for (const obs of observations) {
3585
- html += `
3586
- <tr id="${templateUtilities.narrativeLinkId(obs)}">
3587
- <td>${templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(obs.code))}</td>
3588
- <td>${templateUtilities.codeableConceptCoding(obs.code)}</td>
3589
- <td>${templateUtilities.extractObservationValue(obs)}</td>
3590
- <td>${templateUtilities.extractObservationValueUnit(obs)}</td>
3591
- <td>${templateUtilities.renderNotes(obs.note, timezone)}</td>
3592
- <td>${obs.effectiveDateTime ? templateUtilities.renderTime(obs.effectiveDateTime, timezone) : obs.effectivePeriod ? templateUtilities.renderPeriod(obs.effectivePeriod, timezone) : ""}</td>
3593
- <td>${templateUtilities.getOwnerTag(obs)}</td>
3594
- </tr>`;
3584
+ const obsName = templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(obs.code));
3585
+ if (!addedObservations.has(obsName)) {
3586
+ addedObservations.add(obsName);
3587
+ html += `
3588
+ <tr>
3589
+ <td>${templateUtilities.capitalizeFirstLetter(obsName)}</td>
3590
+ <td>${templateUtilities.codeableConceptCoding(obs.code)}</td>
3591
+ <td>${templateUtilities.extractObservationValue(obs)}</td>
3592
+ <td>${templateUtilities.extractObservationValueUnit(obs)}</td>
3593
+ <td>${templateUtilities.renderNotes(obs.note, timezone)}</td>
3594
+ <td>${obs.effectiveDateTime ? templateUtilities.renderTime(obs.effectiveDateTime, timezone) : obs.effectivePeriod ? templateUtilities.renderPeriod(obs.effectivePeriod, timezone) : ""}</td>
3595
+ <td>${templateUtilities.getOwnerTag(obs)}</td>
3596
+ </tr>`;
3597
+ }
3595
3598
  }
3596
3599
  html += `
3597
3600
  </tbody>
@@ -3611,7 +3614,8 @@ var PastHistoryOfIllnessTemplate = class {
3611
3614
  */
3612
3615
  generateNarrative(resources, timezone, now) {
3613
3616
  const templateUtilities = new TemplateUtilities(resources);
3614
- let html = ``;
3617
+ let html = `<p>This list includes past problems for the patient with a recorded date within the last 5 years, sorted by recorded date (most recent first).</p>
3618
+ `;
3615
3619
  const resolvedConditions = resources.map((entry) => entry) || [];
3616
3620
  const currentDate = now || /* @__PURE__ */ new Date();
3617
3621
  const fiveYearsAgo = new Date(currentDate);
@@ -3648,8 +3652,8 @@ var PastHistoryOfIllnessTemplate = class {
3648
3652
  const conditionCode = templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(cond.code));
3649
3653
  if (!addedConditionCodes.has(conditionCode)) {
3650
3654
  addedConditionCodes.add(conditionCode);
3651
- html += `<tr id="${templateUtilities.narrativeLinkId(cond)}">
3652
- <td class="Name">${conditionCode}</td>
3655
+ html += `<tr>
3656
+ <td class="Name">${templateUtilities.capitalizeFirstLetter(conditionCode)}</td>
3653
3657
  <td class="CodeSystem">${templateUtilities.codeableConceptCoding(cond.code)}</td>
3654
3658
  <td class="OnsetDate">${templateUtilities.renderDate(cond.onsetDateTime)}</td>
3655
3659
  <td class="RecordedDate">${templateUtilities.renderDate(cond.recordedDate)}</td>
@@ -3684,7 +3688,9 @@ var PlanOfCareTemplate = class {
3684
3688
  const endB = b.period?.end ? new Date(b.period?.end).getTime() : 0;
3685
3689
  return endB - endA;
3686
3690
  });
3687
- let html = `
3691
+ let html = `<p>This list includes all CarePlan resources, sorted by planned end date (most recent first).</p>
3692
+ `;
3693
+ html += `
3688
3694
  <table>
3689
3695
  <thead>
3690
3696
  <tr>
@@ -3699,8 +3705,8 @@ var PlanOfCareTemplate = class {
3699
3705
  <tbody>`;
3700
3706
  for (const cp of carePlans) {
3701
3707
  html += `
3702
- <tr id="${templateUtilities.narrativeLinkId(cp)}">
3703
- <td>${cp.description || cp.title || ""}</td>
3708
+ <tr>
3709
+ <td>${templateUtilities.capitalizeFirstLetter(cp.description || cp.title || "")}</td>
3704
3710
  <td>${cp.intent || ""}</td>
3705
3711
  <td>${templateUtilities.concat(cp.note, "text")}</td>
3706
3712
  <td>${cp.period?.start ? templateUtilities.renderTime(cp.period?.start, timezone) : ""}</td>
@@ -3722,7 +3728,9 @@ var PlanOfCareTemplate = class {
3722
3728
  generateSummaryNarrative(resources, timezone) {
3723
3729
  const templateUtilities = new TemplateUtilities(resources);
3724
3730
  let isSummaryCreated = false;
3725
- let html = `
3731
+ let html = `<p>This list includes all CarePlan resources, sorted by planned end date (most recent first).</p>
3732
+ `;
3733
+ html += `
3726
3734
  <div>
3727
3735
  <table>
3728
3736
  <thead>
@@ -3749,7 +3757,7 @@ var PlanOfCareTemplate = class {
3749
3757
  isSummaryCreated = true;
3750
3758
  html += `
3751
3759
  <tr>
3752
- <td>${data["CarePlan Name"] ?? ""}</td>
3760
+ <td>${templateUtilities.capitalizeFirstLetter(data["CarePlan Name"] ?? "")}</td>
3753
3761
  <td>${templateUtilities.renderTime(data["created"], timezone) ?? ""}</td>
3754
3762
  <td>${templateUtilities.renderTime(data["period.start"], timezone) ?? ""}</td>
3755
3763
  <td>${templateUtilities.renderTime(data["period.end"], timezone) ?? ""}</td>
@@ -3784,7 +3792,7 @@ var FunctionalStatusTemplate = class _FunctionalStatusTemplate {
3784
3792
  */
3785
3793
  static generateStaticNarrative(resources, timezone) {
3786
3794
  const templateUtilities = new TemplateUtilities(resources);
3787
- let html = "";
3795
+ let html = `<p>This section summarizes key observations and assessments related to the person's functional status and ability to perform daily activities.</p>`;
3788
3796
  let functionalObservations = resources.filter((r) => r.resourceType === "Observation").filter((r) => {
3789
3797
  const hasFunctionalLoinc = r.code?.coding?.some(
3790
3798
  (c) => c.system?.toLowerCase().includes("loinc") && c.code === "47420-5"
@@ -3814,8 +3822,8 @@ var FunctionalStatusTemplate = class _FunctionalStatusTemplate {
3814
3822
  const date = observation.effectiveDateTime ? templateUtilities.renderDate(observation.effectiveDateTime) : observation.issued ? templateUtilities.renderDate(observation.issued) : "";
3815
3823
  const interpretation = observation.interpretation ? templateUtilities.codeableConceptDisplay(observation.interpretation[0]) : "";
3816
3824
  const comments = observation.comment || observation.note?.map((n) => n.text).join("; ") || "";
3817
- html += `<tr id="${templateUtilities.narrativeLinkId(observation)}">
3818
- <td>${obsName}</td>
3825
+ html += `<tr>
3826
+ <td>${templateUtilities.capitalizeFirstLetter(obsName)}</td>
3819
3827
  <td>${value ?? ""}</td>
3820
3828
  <td>${date}</td>
3821
3829
  <td>${interpretation}</td>
@@ -3845,7 +3853,7 @@ var FunctionalStatusTemplate = class _FunctionalStatusTemplate {
3845
3853
  }
3846
3854
  findingsHtml += "</ul>";
3847
3855
  }
3848
- html += `<tr id="${templateUtilities.narrativeLinkId(impression)}">
3856
+ html += `<tr>
3849
3857
  <td>${formattedDate}</td>
3850
3858
  <td>${impression.status || ""}</td>
3851
3859
  <td>${impression.description || ""}</td>
@@ -3908,7 +3916,8 @@ var PregnancyTemplate = class _PregnancyTemplate {
3908
3916
  if (!pregnancyStatusObs && !eddObs && historyObs.length === 0 && conditions.length === 0) {
3909
3917
  return `<p>No history of pregnancy found.</p>`;
3910
3918
  }
3911
- let html = `
3919
+ let html = `<p>This list includes Observation and Condition resources relevant to pregnancy, sorted by date (most recent first).</p>`;
3920
+ html += `
3912
3921
  <table>
3913
3922
  <thead>
3914
3923
  <tr>
@@ -3920,10 +3929,10 @@ var PregnancyTemplate = class _PregnancyTemplate {
3920
3929
  </tr>
3921
3930
  </thead>
3922
3931
  <tbody>`;
3923
- function renderRow({ id, result, comments, date, codeSystem, owner }) {
3932
+ function renderRow({ result, comments, date, codeSystem, owner }) {
3924
3933
  html += `
3925
- <tr id="${id}">
3926
- <td class="Result">${result}</td>
3934
+ <tr>
3935
+ <td class="Result">${templateUtilities.capitalizeFirstLetter(result)}</td>
3927
3936
  <td class="CodeSystem">${codeSystem}</td>
3928
3937
  <td class="Comments">${comments}</td>
3929
3938
  <td class="Date">${date}</td>
@@ -3954,9 +3963,9 @@ var PregnancyTemplate = class _PregnancyTemplate {
3954
3963
  if (!b.date) return -1;
3955
3964
  return new Date(b.date).getTime() - new Date(a.date).getTime();
3956
3965
  });
3966
+ const addedRows = /* @__PURE__ */ new Set();
3957
3967
  for (const { resource, date, type } of rowResources) {
3958
3968
  let result = "", comments = "", dateStr = "", codeSystem = "";
3959
- const id = templateUtilities.narrativeLinkId(resource);
3960
3969
  if (type === "status") {
3961
3970
  result = templateUtilities.renderTextAsHtml(templateUtilities.extractPregnancyStatus(resource));
3962
3971
  comments = templateUtilities.renderNotes(resource.note, timezone);
@@ -3978,8 +3987,12 @@ var PregnancyTemplate = class _PregnancyTemplate {
3978
3987
  dateStr = date ? templateUtilities.renderTextAsHtml(templateUtilities.renderTime(date, timezone)) : "";
3979
3988
  codeSystem = templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptCoding(resource.code));
3980
3989
  }
3981
- const owner = templateUtilities.getOwnerTag(resource);
3982
- renderRow({ id, result, comments, date: dateStr, codeSystem, owner });
3990
+ const rowKey = `${result}|${codeSystem}`;
3991
+ if (!addedRows.has(rowKey)) {
3992
+ addedRows.add(rowKey);
3993
+ const owner = templateUtilities.getOwnerTag(resource);
3994
+ renderRow({ result, comments, date: dateStr, codeSystem, owner });
3995
+ }
3983
3996
  }
3984
3997
  html += `
3985
3998
  </tbody>
@@ -4013,8 +4026,9 @@ var AdvanceDirectivesTemplate = class _AdvanceDirectivesTemplate {
4013
4026
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
4014
4027
  static generateStaticNarrative(resources, timezone) {
4015
4028
  const templateUtilities = new TemplateUtilities(resources);
4016
- let html = `
4017
- <table>
4029
+ let html = `<p>This list includes all Consent resources, sorted by date (most recent first).</p>
4030
+ `;
4031
+ html += `<table>
4018
4032
  <thead>
4019
4033
  <tr>
4020
4034
  <th>Scope</th>
@@ -4027,8 +4041,8 @@ var AdvanceDirectivesTemplate = class _AdvanceDirectivesTemplate {
4027
4041
  for (const resourceItem of resources) {
4028
4042
  const consent = resourceItem;
4029
4043
  html += `
4030
- <tr id="${templateUtilities.narrativeLinkId(consent)}">
4031
- <td>${templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(consent.scope, "display"))}</td>
4044
+ <tr>
4045
+ <td>${templateUtilities.capitalizeFirstLetter(templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(consent.scope, "display")))}</td>
4032
4046
  <td>${consent.status || ""}</td>
4033
4047
  <td>${consent.provision?.action ? templateUtilities.concatCodeableConcept(consent.provision.action) : ""}</td>
4034
4048
  <td>${consent.dateTime || ""}</td>
@@ -4343,14 +4357,17 @@ var ComprehensiveIPSCompositionBuilder = class {
4343
4357
  const summaryIPSCompositionFilter = useSummaryCompositions ? IPSSectionResourceHelper.getSummaryIPSCompositionFilterForSection(sectionType) : void 0;
4344
4358
  const sectionIPSSummary = summaryIPSCompositionFilter ? resources.filter((resource) => summaryIPSCompositionFilter(resource)) : [];
4345
4359
  if (sectionIPSSummary.length > 0) {
4360
+ console.log(`Using IPS summary composition for section: ${sectionType}`);
4346
4361
  await this.makeSectionFromSummaryAsync(sectionType, sectionIPSSummary, resources, timezone);
4347
4362
  continue;
4348
4363
  }
4349
4364
  const summaryCompositionFilter = useSummaryCompositions ? IPSSectionResourceHelper.getSummaryCompositionFilterForSection(sectionType) : void 0;
4350
4365
  const sectionSummary = summaryCompositionFilter ? resources.filter((resource) => summaryCompositionFilter(resource)) : [];
4351
4366
  if (sectionSummary.length > 0) {
4367
+ console.log(`Using summary composition for section: ${sectionType}`);
4352
4368
  await this.makeSectionFromSummaryAsync(sectionType, sectionSummary, resources, timezone);
4353
4369
  } else {
4370
+ console.log(`Using individual resources for section: ${sectionType}`);
4354
4371
  const sectionFilter = IPSSectionResourceHelper.getResourceFilterForSection(sectionType);
4355
4372
  const sectionResources = resources.filter((resource) => sectionFilter(resource));
4356
4373
  await this.makeSectionAsync(sectionType, sectionResources, timezone);
package/dist/index.js CHANGED
@@ -910,6 +910,12 @@ var TemplateUtilities = class {
910
910
  const escapedText = text.replace(/</g, "&lt;").replace(/>/g, "&gt;");
911
911
  return escapedText.replace(/\n/g, "<br />");
912
912
  }
913
+ capitalizeFirstLetter(text) {
914
+ if (!text || text.length === 0) {
915
+ return "";
916
+ }
917
+ return text.charAt(0).toUpperCase() + text.slice(1);
918
+ }
913
919
  /**
914
920
  * Renders note elements from a FHIR resource in a standardized format
915
921
  * Can render as simple comma-separated text or as styled HTML with timestamps
@@ -1407,7 +1413,8 @@ var PatientTemplate = class _PatientTemplate {
1407
1413
  static generateStaticNarrative(resources, timezone) {
1408
1414
  const templateUtilities = new TemplateUtilities(resources);
1409
1415
  const combinedPatient = this.combinePatients(resources);
1410
- return `<div>
1416
+ let html = `<p>This section merges all Patient resources into a single combined patient record, preferring non-empty values for each field.</p>`;
1417
+ html += `<div>
1411
1418
  <ul>
1412
1419
  <li><strong>Name(s):</strong>${this.renderNames(combinedPatient)}</li>
1413
1420
  <li><strong>Gender:</strong>${combinedPatient.gender ? this.capitalize(combinedPatient.gender) : ""}</li>
@@ -1419,6 +1426,7 @@ var PatientTemplate = class _PatientTemplate {
1419
1426
  <li><strong>Language(s):</strong>${this.renderCommunication(templateUtilities, combinedPatient)}</li>
1420
1427
  </ul>
1421
1428
  </div>`;
1429
+ return html;
1422
1430
  }
1423
1431
  /**
1424
1432
  * Combines multiple patient resources into a single patient object
@@ -1743,7 +1751,9 @@ var AllergyIntoleranceTemplate = class _AllergyIntoleranceTemplate {
1743
1751
  generateSummaryNarrative(resources, timezone) {
1744
1752
  const templateUtilities = new TemplateUtilities(resources);
1745
1753
  let isSummaryCreated = false;
1746
- let html = `
1754
+ let html = `<p>This list includes all AllergyIntolerance resources, with no additional filtering, sorted as provided.</p>
1755
+ `;
1756
+ html += `
1747
1757
  <div>
1748
1758
  <table>
1749
1759
  <thead>
@@ -1782,7 +1792,7 @@ var AllergyIntoleranceTemplate = class _AllergyIntoleranceTemplate {
1782
1792
  isSummaryCreated = true;
1783
1793
  html += `
1784
1794
  <tr>
1785
- <td>${data["allergen"] ?? ""}</td>
1795
+ <td>${templateUtilities.capitalizeFirstLetter(data["allergen"] ?? "")}</td>
1786
1796
  <td>${data["codeSystem"] ?? ""}</td>
1787
1797
  <td>${data["criticality"] ?? ""}</td>
1788
1798
  <td>${templateUtilities.renderTime(data["recordedDate"], timezone) ?? ""}</td>
@@ -1825,7 +1835,8 @@ var AllergyIntoleranceTemplate = class _AllergyIntoleranceTemplate {
1825
1835
  const dateB = b.onsetDateTime;
1826
1836
  return dateA && dateB ? new Date(dateB).getTime() - new Date(dateA).getTime() : 0;
1827
1837
  });
1828
- let html = "";
1838
+ let html = `<p>This list includes all AllergyIntolerance resources, with no additional filtering, sorted as provided.</p>
1839
+ `;
1829
1840
  html += `
1830
1841
  <div class="ActiveAllergies">
1831
1842
  <h3>Active</h3>
@@ -1899,8 +1910,8 @@ var AllergyIntoleranceTemplate = class _AllergyIntoleranceTemplate {
1899
1910
  let html = "";
1900
1911
  for (const allergy of allergies) {
1901
1912
  html += `
1902
- <tr id="${templateUtilities.narrativeLinkId(allergy.extension)}">
1903
- <td class="Name"><span class="AllergenName">${templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(allergy.code))}</span></td>
1913
+ <tr>
1914
+ <td class="Name"><span class="AllergenName">${templateUtilities.capitalizeFirstLetter(templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(allergy.code)))}</span></td>
1904
1915
  <td class="Status">${templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(allergy.clinicalStatus)) || ""}</td>
1905
1916
  <td class="CodeSystem">${templateUtilities.codeableConceptCoding(allergy.code)}</td>
1906
1917
  <td class="Category">${templateUtilities.renderTextAsHtml(templateUtilities.safeConcat(allergy.category)) || ""}</td>
@@ -1951,7 +1962,8 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
1951
1962
  let isSummaryCreated = false;
1952
1963
  const currentDate = now || /* @__PURE__ */ new Date();
1953
1964
  const twoYearsAgo = new Date(currentDate.getFullYear(), currentDate.getMonth() - 24, currentDate.getDate());
1954
- let html = `
1965
+ let html = "<p>This list includes all the medications that were ordered for the patient, the medications they filled from the pharmacy and the medications they reported, filtered to past 2 years and sorted by start date.</p>";
1966
+ html += `
1955
1967
  <div>
1956
1968
  <table>
1957
1969
  <thead>
@@ -2016,7 +2028,7 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
2016
2028
  isSummaryCreated = true;
2017
2029
  html += `
2018
2030
  <tr>
2019
- <td>${templateUtilities.renderTextAsHtml(data["medication"])}</td>
2031
+ <td>${templateUtilities.capitalizeFirstLetter(templateUtilities.renderTextAsHtml(data["medication"]))}</td>
2020
2032
  <td>${templateUtilities.codeableConceptCoding(sectionCodeableConcept)}</td>
2021
2033
  <td>${templateUtilities.renderTextAsHtml(data["status"])}</td>
2022
2034
  <td>${templateUtilities.renderTextAsHtml(data["sig-prescriber"] || data["sig-pharmacy"])}</td>
@@ -2063,8 +2075,8 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
2063
2075
  static generateStaticNarrative(resources, timezone, now) {
2064
2076
  const templateUtilities = new TemplateUtilities(resources);
2065
2077
  let html = "";
2066
- const medicationRequests = this.getMedicationRequests(templateUtilities, resources);
2067
- const medicationStatements = this.getMedicationStatements(templateUtilities, resources);
2078
+ const medicationRequests = resources.filter((entry) => entry.resourceType === "MedicationRequest");
2079
+ const medicationStatements = resources.filter((entry) => entry.resourceType === "MedicationStatement");
2068
2080
  const allActiveMedications = [];
2069
2081
  const currentDate = now || /* @__PURE__ */ new Date();
2070
2082
  const twoYearsAgo = new Date(currentDate);
@@ -2072,10 +2084,10 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
2072
2084
  let skippedMedications = 0;
2073
2085
  const allMedications = [];
2074
2086
  medicationRequests.forEach((mr) => {
2075
- allMedications.push({ type: "request", resource: mr.resource, extension: mr.extension });
2087
+ allMedications.push({ type: "request", resource: mr });
2076
2088
  });
2077
2089
  medicationStatements.forEach((ms) => {
2078
- allMedications.push({ type: "statement", resource: ms.resource, extension: ms.extension });
2090
+ allMedications.push({ type: "statement", resource: ms });
2079
2091
  });
2080
2092
  for (const med of allMedications) {
2081
2093
  let dateString;
@@ -2132,36 +2144,6 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
2132
2144
  }
2133
2145
  return "";
2134
2146
  }
2135
- /**
2136
- * Extract MedicationRequest resources
2137
- * @param templateUtilities - Instance of TemplateUtilities for utility functions
2138
- * @param resources - FHIR Medication resources
2139
- * @returns Array of MedicationRequest resources
2140
- */
2141
- static getMedicationRequests(templateUtilities, resources) {
2142
- if (resources.length === 0) {
2143
- return [];
2144
- }
2145
- return resources.filter((entry) => entry.resourceType === "MedicationRequest").map((entry) => ({
2146
- resource: entry,
2147
- extension: templateUtilities.narrativeLinkExtension(entry)
2148
- }));
2149
- }
2150
- /**
2151
- * Extract MedicationStatement resources
2152
- * @param templateUtilities - Instance of TemplateUtilities for utility functions
2153
- * @param resources - FHIR Medication resources
2154
- * @returns Array of MedicationStatement resources
2155
- */
2156
- static getMedicationStatements(templateUtilities, resources) {
2157
- if (resources.length === 0) {
2158
- return [];
2159
- }
2160
- return resources.filter((entry) => entry.resourceType === "MedicationStatement").map((entry) => ({
2161
- resource: entry,
2162
- extension: templateUtilities.narrativeLinkExtension(entry)
2163
- }));
2164
- }
2165
2147
  /**
2166
2148
  * Render HTML table for combined MedicationRequest and MedicationStatement resources
2167
2149
  * @param templateUtilities - Instance of TemplateUtilities for utility functions
@@ -2185,7 +2167,6 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
2185
2167
  </thead>
2186
2168
  <tbody>`;
2187
2169
  for (const medication of medications) {
2188
- const narrativeLinkId = templateUtilities.narrativeLinkId(medication.extension);
2189
2170
  let type;
2190
2171
  let medicationName;
2191
2172
  let sig;
@@ -2232,9 +2213,9 @@ var MedicationSummaryTemplate = class _MedicationSummaryTemplate {
2232
2213
  }
2233
2214
  }
2234
2215
  html += `
2235
- <tr${narrativeLinkId ? ` id="${narrativeLinkId}"` : ""}>
2216
+ <tr>
2236
2217
  <td>${type}</td>
2237
- <td>${medicationName}<ul></ul></td>
2218
+ <td>${templateUtilities.capitalizeFirstLetter(medicationName)}</td>
2238
2219
  <td>${codeSystemDisplay}</td>
2239
2220
  <td>${sig}</td>
2240
2221
  <td>${dispenseQuantity}</td>
@@ -2277,6 +2258,7 @@ var ImmunizationsTemplate = class _ImmunizationsTemplate {
2277
2258
  let isSummaryCreated = false;
2278
2259
  let html = `
2279
2260
  <div>
2261
+ <p>This list includes all vaccinations, sorted by occurrence date (most recent first).</p>
2280
2262
  <table>
2281
2263
  <thead>
2282
2264
  <tr>
@@ -2315,7 +2297,7 @@ var ImmunizationsTemplate = class _ImmunizationsTemplate {
2315
2297
  isSummaryCreated = true;
2316
2298
  html += `
2317
2299
  <tr>
2318
- <td>${data["immunization"] ?? ""}</td>
2300
+ <td>${templateUtilities.capitalizeFirstLetter(data["immunization"] ?? "")}</td>
2319
2301
  <td>${data["codeSystem"] ?? ""}</td>
2320
2302
  <td>${data["status"] ?? ""}</td>
2321
2303
  <td>${templateUtilities.renderTime(data["occurrenceDateTime"], timezone) ?? ""}</td>
@@ -2359,8 +2341,8 @@ var ImmunizationsTemplate = class _ImmunizationsTemplate {
2359
2341
  for (const resourceItem of immunizations) {
2360
2342
  const imm = resourceItem;
2361
2343
  html += `
2362
- <tr id="${templateUtilities.narrativeLinkId(imm)}">
2363
- <td>${templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(imm.vaccineCode))}</td>
2344
+ <tr>
2345
+ <td>${templateUtilities.capitalizeFirstLetter(templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(imm.vaccineCode)))}</td>
2364
2346
  <td>${templateUtilities.codeableConceptCoding(imm.vaccineCode)}</td>
2365
2347
  <td>${imm.status || ""}</td>
2366
2348
  <td>${templateUtilities.concatDoseNumber(imm.protocolApplied)}</td>
@@ -2399,7 +2381,8 @@ var ProblemListTemplate = class _ProblemListTemplate {
2399
2381
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
2400
2382
  static generateStaticNarrative(resources, timezone) {
2401
2383
  const templateUtilities = new TemplateUtilities(resources);
2402
- let html = ``;
2384
+ let html = `<p>This list includes patient problems, sorted by recorded date (most recent first)</p>
2385
+ `;
2403
2386
  const activeConditions = resources.map((entry) => entry) || [];
2404
2387
  activeConditions.sort((a, b) => {
2405
2388
  if (!a.recordedDate && b.recordedDate) return -1;
@@ -2429,8 +2412,8 @@ var ProblemListTemplate = class _ProblemListTemplate {
2429
2412
  continue;
2430
2413
  }
2431
2414
  seenCodeAndSystems.add(codeAndSystem);
2432
- html += `<tr id="${templateUtilities.narrativeLinkId(cond)}">
2433
- <td class="Name">${conditionDisplay}</td>
2415
+ html += `<tr>
2416
+ <td class="Name">${templateUtilities.capitalizeFirstLetter(conditionDisplay)}</td>
2434
2417
  <td class="CodeSystem">${codeAndSystem}</td>
2435
2418
  <td class="OnsetDate">${templateUtilities.renderDate(cond.onsetDateTime)}</td>
2436
2419
  <td class="RecordedDate">${templateUtilities.renderDate(cond.recordedDate)}</td>
@@ -2463,7 +2446,9 @@ var VitalSignsTemplate = class _VitalSignsTemplate {
2463
2446
  generateSummaryNarrative(resources, timezone) {
2464
2447
  const templateUtilities = new TemplateUtilities(resources);
2465
2448
  let isSummaryCreated = false;
2466
- let html = `
2449
+ let html = `<p>This list includes the latest vital signs, sorted by effective date (most recent first).</p>
2450
+ `;
2451
+ html += `
2467
2452
  <div>
2468
2453
  <table>
2469
2454
  <thead>
@@ -2508,7 +2493,7 @@ var VitalSignsTemplate = class _VitalSignsTemplate {
2508
2493
  isSummaryCreated = true;
2509
2494
  html += `
2510
2495
  <tr>
2511
- <td>${data["Vital Name"] ?? ""}</td>
2496
+ <td>${templateUtilities.capitalizeFirstLetter(data["Vital Name"] ?? "")}</td>
2512
2497
  <td>${data["codeSystem"] ?? ""}</td>
2513
2498
  <td>${templateUtilities.extractObservationSummaryValue(data, timezone) ?? ""}</td>
2514
2499
  <td>${templateUtilities.extractObservationSummaryEffectiveTime(data, timezone) ?? ""}</td>
@@ -2536,7 +2521,9 @@ var VitalSignsTemplate = class _VitalSignsTemplate {
2536
2521
  const dateB = b.effectiveDateTime || b.effectivePeriod?.start;
2537
2522
  return dateA && dateB ? new Date(dateB).getTime() - new Date(dateA).getTime() : 0;
2538
2523
  });
2539
- let html = `
2524
+ let html = `<p>This list includes the latest vital signs, sorted by effective date (most recent first).</p>
2525
+ `;
2526
+ html += `
2540
2527
  <table>
2541
2528
  <thead>
2542
2529
  <tr>
@@ -2554,8 +2541,8 @@ var VitalSignsTemplate = class _VitalSignsTemplate {
2554
2541
  <tbody>`;
2555
2542
  for (const obs of observations) {
2556
2543
  html += `
2557
- <tr id="${templateUtilities.narrativeLinkId(obs)}">
2558
- <td>${templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(obs.code, "display"))}</td>
2544
+ <tr>
2545
+ <td>${templateUtilities.capitalizeFirstLetter(templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(obs.code, "display")))}</td>
2559
2546
  <td>${templateUtilities.codeableConceptCoding(obs.code)}</td>
2560
2547
  <td>${templateUtilities.extractObservationValue(obs)}</td>
2561
2548
  <td>${templateUtilities.extractObservationValueUnit(obs)}</td>
@@ -2592,7 +2579,7 @@ var MedicalDevicesTemplate = class _MedicalDevicesTemplate {
2592
2579
  */
2593
2580
  static generateStaticNarrative(resources, timezone) {
2594
2581
  const templateUtilities = new TemplateUtilities(resources);
2595
- let html = `
2582
+ let html = `<p>This list includes all DeviceUseStatement resources, sorted by recorded date (most recent first).</p>
2596
2583
  <table>
2597
2584
  <thead>
2598
2585
  <tr>
@@ -2608,10 +2595,12 @@ var MedicalDevicesTemplate = class _MedicalDevicesTemplate {
2608
2595
  const dateB = b.recordedOn;
2609
2596
  return typeof dateA === "string" && typeof dateB === "string" ? new Date(dateB).getTime() - new Date(dateA).getTime() : 0;
2610
2597
  });
2598
+ let isDeviceAdded = false;
2611
2599
  for (const dus of deviceStatements) {
2600
+ isDeviceAdded = true;
2612
2601
  html += `
2613
- <tr id="${templateUtilities.narrativeLinkId(dus)}">
2614
- <td>${templateUtilities.renderTextAsHtml(templateUtilities.renderDevice(dus.device))}</td>
2602
+ <tr>
2603
+ <td>${templateUtilities.capitalizeFirstLetter(templateUtilities.renderTextAsHtml(templateUtilities.renderDevice(dus.device)))}</td>
2615
2604
  <td>${templateUtilities.renderTextAsHtml(dus.status || "")}</td>
2616
2605
  <td>${templateUtilities.renderNotes(dus.note, timezone)}</td>
2617
2606
  <td>${templateUtilities.renderTextAsHtml(templateUtilities.renderRecorded(dus.recordedOn, timezone))}</td>
@@ -2620,7 +2609,7 @@ var MedicalDevicesTemplate = class _MedicalDevicesTemplate {
2620
2609
  html += `
2621
2610
  </tbody>
2622
2611
  </table>`;
2623
- return html;
2612
+ return isDeviceAdded ? html : void 0;
2624
2613
  }
2625
2614
  };
2626
2615
 
@@ -2971,11 +2960,12 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
2971
2960
  }
2972
2961
  }
2973
2962
  }
2974
- let html = `
2975
- <div>`;
2963
+ let html = `<p>This section includes Observations from the last 2 years (one per lab name, using code mapping) and DiagnosticReports with status 'final' issued in the last 2 years. Both are sorted by date (most recent first). Older results are counted and noted below the tables.</p>
2964
+ `;
2976
2965
  let observationhtml = `
2977
2966
  <div>
2978
2967
  <h3>Observations</h3>
2968
+ ${html}
2979
2969
  <table>
2980
2970
  <thead>
2981
2971
  <tr>
@@ -2991,6 +2981,7 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
2991
2981
  let diagnosticReporthtml = `
2992
2982
  <div>
2993
2983
  <h3>Diagnostic Reports</h3>
2984
+ ${html}
2994
2985
  <table>
2995
2986
  <thead>
2996
2987
  <tr>
@@ -3075,7 +3066,7 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
3075
3066
  this.formatSummaryObservationData(component);
3076
3067
  observationhtml += `
3077
3068
  <tr>
3078
- <td>${componentCode}</td>
3069
+ <td>${templateUtilities.capitalizeFirstLetter(componentCode)}</td>
3079
3070
  <td></td>
3080
3071
  <td>${templateUtilities.renderTextAsHtml(component["formattedValue"]) ?? ""}</td>
3081
3072
  <td>${templateUtilities.renderTextAsHtml(component["referenceRange"])?.trim() ?? ""}</td>
@@ -3092,7 +3083,7 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
3092
3083
  this.formatSummaryObservationData(data);
3093
3084
  observationhtml += `
3094
3085
  <tr>
3095
- <td>${data["code"] ?? ""}</td>
3086
+ <td>${templateUtilities.capitalizeFirstLetter(data["code"] ?? "")}</td>
3096
3087
  <td>${templateUtilities.codeableConceptCoding(sectionCodeableConcept)}</td>
3097
3088
  <td>${templateUtilities.renderTextAsHtml(data["formattedValue"]) ?? ""}</td>
3098
3089
  <td>${templateUtilities.renderTextAsHtml(data["referenceRange"])?.trim() ?? ""}</td>
@@ -3113,7 +3104,7 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
3113
3104
  diagnosticReportAdded.add(reportName);
3114
3105
  diagnosticReporthtml += `
3115
3106
  <tr>
3116
- <td>${data["report"] ?? ""}</td>
3107
+ <td>${templateUtilities.capitalizeFirstLetter(data["report"] ?? "")}</td>
3117
3108
  <td>${data["performer"] ?? ""}</td>
3118
3109
  <td>${templateUtilities.renderTime(data["issued"], timezone) ?? ""}</td>
3119
3110
  <td>${data["source"] ?? ""}</td>
@@ -3161,7 +3152,8 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
3161
3152
  const currentDate = now || /* @__PURE__ */ new Date();
3162
3153
  const twoYearsAgo = new Date(currentDate);
3163
3154
  twoYearsAgo.setFullYear(currentDate.getFullYear() - 2);
3164
- let html = "";
3155
+ let html = `<p>This section includes Observations from the last 2 years (one per lab name, using code mapping) and DiagnosticReports with status 'final' issued in the last 2 years. Both are sorted by date (most recent first). Older results are counted and noted below the tables.</p>
3156
+ `;
3165
3157
  let skippedObservations = 0;
3166
3158
  let skippedDiagnosticReports = 0;
3167
3159
  for (const resourceItem of resources) {
@@ -3312,8 +3304,8 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
3312
3304
  observationAdded.add(obsCodeDisplay);
3313
3305
  observationAdded.add(obsCodeAndSystem);
3314
3306
  html += `
3315
- <tr id="${templateUtilities.narrativeLinkId(obs)}">
3316
- <td>${obsCodeDisplay}</td>
3307
+ <tr>
3308
+ <td>${templateUtilities.capitalizeFirstLetter(obsCodeDisplay)}</td>
3317
3309
  <td>${templateUtilities.codeableConceptCoding(obs.code)}</td>
3318
3310
  <td>${templateUtilities.extractObservationValue(obs)}</td>
3319
3311
  <td>${templateUtilities.concatReferenceRange(obs.referenceRange)}</td>
@@ -3361,8 +3353,8 @@ var DiagnosticResultsTemplate = class _DiagnosticResultsTemplate {
3361
3353
  resultCount = `${report.result.length} result${report.result.length !== 1 ? "s" : ""}`;
3362
3354
  }
3363
3355
  html += `
3364
- <tr id="${templateUtilities.narrativeLinkId(report)}">
3365
- <td>${reportName}</td>
3356
+ <tr>
3357
+ <td>${templateUtilities.capitalizeFirstLetter(reportName)}</td>
3366
3358
  <td>${codeAndSystem}</td>
3367
3359
  <td>${templateUtilities.firstFromCodeableConceptList(report.category)}</td>
3368
3360
  <td>${resultCount}</td>
@@ -3423,7 +3415,9 @@ var HistoryOfProceduresTemplate = class _HistoryOfProceduresTemplate {
3423
3415
  generateSummaryNarrative(resources, timezone) {
3424
3416
  const templateUtilities = new TemplateUtilities(resources);
3425
3417
  let isSummaryCreated = false;
3426
- let html = `
3418
+ let html = `<p>This list includes all Procedure resources, sorted by performed date (most recent first).</p>
3419
+ `;
3420
+ html += `
3427
3421
  <div>
3428
3422
  <table>
3429
3423
  <thead>
@@ -3462,7 +3456,7 @@ var HistoryOfProceduresTemplate = class _HistoryOfProceduresTemplate {
3462
3456
  isSummaryCreated = true;
3463
3457
  html += `
3464
3458
  <tr>
3465
- <td>${data["procedure"] ?? ""}</td>
3459
+ <td>${templateUtilities.capitalizeFirstLetter(data["procedure"] ?? "")}</td>
3466
3460
  <td>${data["codeSystem"] ?? ""}</td>
3467
3461
  <td>${data["performer"] ?? ""}</td>
3468
3462
  <td>${templateUtilities.renderTime(data["date"], timezone) ?? ""}</td>
@@ -3484,7 +3478,9 @@ var HistoryOfProceduresTemplate = class _HistoryOfProceduresTemplate {
3484
3478
  */
3485
3479
  static generateStaticNarrative(resources, timezone) {
3486
3480
  const templateUtilities = new TemplateUtilities(resources);
3487
- let html = `
3481
+ let html = `<p>This list includes all Procedure resources, sorted by performed date (most recent first).</p>
3482
+ `;
3483
+ html += `
3488
3484
  <table>
3489
3485
  <thead>
3490
3486
  <tr>
@@ -3499,12 +3495,12 @@ var HistoryOfProceduresTemplate = class _HistoryOfProceduresTemplate {
3499
3495
  for (const resourceItem of resources) {
3500
3496
  const proc = resourceItem;
3501
3497
  html += `
3502
- <tr id="${templateUtilities.narrativeLinkId(proc)}">
3503
- <td>${templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(proc.code, "display"))}</td>
3504
- <td>${templateUtilities.codeableConceptCoding(proc.code)}</td>
3498
+ <tr>
3499
+ <td>${templateUtilities.capitalizeFirstLetter(templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(proc.code, "display")))}</td>
3500
+ <td>${templateUtilities.codeableConceptCoding(proc.code)}</td>
3505
3501
  <td>${templateUtilities.renderNotes(proc.note, timezone)}</td>
3506
- <td>${proc.performedDateTime ? templateUtilities.renderTime(proc.performedDateTime, timezone) : proc.performedPeriod ? templateUtilities.renderPeriod(proc.performedPeriod, timezone) : ""}</td>
3507
- <td>${templateUtilities.getOwnerTag(proc)}</td>
3502
+ <td>${templateUtilities.renderTime(proc.performedDateTime || proc.performedPeriod?.start, timezone)}</td>
3503
+ <td>${templateUtilities.getOwnerTag(proc)}</td>
3508
3504
  </tr>`;
3509
3505
  }
3510
3506
  html += `
@@ -3539,7 +3535,9 @@ var SocialHistoryTemplate = class _SocialHistoryTemplate {
3539
3535
  const dateB = b.effectiveDateTime || b.effectivePeriod?.start;
3540
3536
  return dateA && dateB ? new Date(dateB).getTime() - new Date(dateA).getTime() : 0;
3541
3537
  });
3542
- let html = `
3538
+ let html = `<p>This list includes all information about the patient's social history, sorted by effective date (most recent first).</p>
3539
+ `;
3540
+ html += `
3543
3541
  <table>
3544
3542
  <thead>
3545
3543
  <tr>
@@ -3553,17 +3551,22 @@ var SocialHistoryTemplate = class _SocialHistoryTemplate {
3553
3551
  </tr>
3554
3552
  </thead>
3555
3553
  <tbody>`;
3554
+ const addedObservations = /* @__PURE__ */ new Set();
3556
3555
  for (const obs of observations) {
3557
- html += `
3558
- <tr id="${templateUtilities.narrativeLinkId(obs)}">
3559
- <td>${templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(obs.code))}</td>
3560
- <td>${templateUtilities.codeableConceptCoding(obs.code)}</td>
3561
- <td>${templateUtilities.extractObservationValue(obs)}</td>
3562
- <td>${templateUtilities.extractObservationValueUnit(obs)}</td>
3563
- <td>${templateUtilities.renderNotes(obs.note, timezone)}</td>
3564
- <td>${obs.effectiveDateTime ? templateUtilities.renderTime(obs.effectiveDateTime, timezone) : obs.effectivePeriod ? templateUtilities.renderPeriod(obs.effectivePeriod, timezone) : ""}</td>
3565
- <td>${templateUtilities.getOwnerTag(obs)}</td>
3566
- </tr>`;
3556
+ const obsName = templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(obs.code));
3557
+ if (!addedObservations.has(obsName)) {
3558
+ addedObservations.add(obsName);
3559
+ html += `
3560
+ <tr>
3561
+ <td>${templateUtilities.capitalizeFirstLetter(obsName)}</td>
3562
+ <td>${templateUtilities.codeableConceptCoding(obs.code)}</td>
3563
+ <td>${templateUtilities.extractObservationValue(obs)}</td>
3564
+ <td>${templateUtilities.extractObservationValueUnit(obs)}</td>
3565
+ <td>${templateUtilities.renderNotes(obs.note, timezone)}</td>
3566
+ <td>${obs.effectiveDateTime ? templateUtilities.renderTime(obs.effectiveDateTime, timezone) : obs.effectivePeriod ? templateUtilities.renderPeriod(obs.effectivePeriod, timezone) : ""}</td>
3567
+ <td>${templateUtilities.getOwnerTag(obs)}</td>
3568
+ </tr>`;
3569
+ }
3567
3570
  }
3568
3571
  html += `
3569
3572
  </tbody>
@@ -3583,7 +3586,8 @@ var PastHistoryOfIllnessTemplate = class {
3583
3586
  */
3584
3587
  generateNarrative(resources, timezone, now) {
3585
3588
  const templateUtilities = new TemplateUtilities(resources);
3586
- let html = ``;
3589
+ let html = `<p>This list includes past problems for the patient with a recorded date within the last 5 years, sorted by recorded date (most recent first).</p>
3590
+ `;
3587
3591
  const resolvedConditions = resources.map((entry) => entry) || [];
3588
3592
  const currentDate = now || /* @__PURE__ */ new Date();
3589
3593
  const fiveYearsAgo = new Date(currentDate);
@@ -3620,8 +3624,8 @@ var PastHistoryOfIllnessTemplate = class {
3620
3624
  const conditionCode = templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(cond.code));
3621
3625
  if (!addedConditionCodes.has(conditionCode)) {
3622
3626
  addedConditionCodes.add(conditionCode);
3623
- html += `<tr id="${templateUtilities.narrativeLinkId(cond)}">
3624
- <td class="Name">${conditionCode}</td>
3627
+ html += `<tr>
3628
+ <td class="Name">${templateUtilities.capitalizeFirstLetter(conditionCode)}</td>
3625
3629
  <td class="CodeSystem">${templateUtilities.codeableConceptCoding(cond.code)}</td>
3626
3630
  <td class="OnsetDate">${templateUtilities.renderDate(cond.onsetDateTime)}</td>
3627
3631
  <td class="RecordedDate">${templateUtilities.renderDate(cond.recordedDate)}</td>
@@ -3656,7 +3660,9 @@ var PlanOfCareTemplate = class {
3656
3660
  const endB = b.period?.end ? new Date(b.period?.end).getTime() : 0;
3657
3661
  return endB - endA;
3658
3662
  });
3659
- let html = `
3663
+ let html = `<p>This list includes all CarePlan resources, sorted by planned end date (most recent first).</p>
3664
+ `;
3665
+ html += `
3660
3666
  <table>
3661
3667
  <thead>
3662
3668
  <tr>
@@ -3671,8 +3677,8 @@ var PlanOfCareTemplate = class {
3671
3677
  <tbody>`;
3672
3678
  for (const cp of carePlans) {
3673
3679
  html += `
3674
- <tr id="${templateUtilities.narrativeLinkId(cp)}">
3675
- <td>${cp.description || cp.title || ""}</td>
3680
+ <tr>
3681
+ <td>${templateUtilities.capitalizeFirstLetter(cp.description || cp.title || "")}</td>
3676
3682
  <td>${cp.intent || ""}</td>
3677
3683
  <td>${templateUtilities.concat(cp.note, "text")}</td>
3678
3684
  <td>${cp.period?.start ? templateUtilities.renderTime(cp.period?.start, timezone) : ""}</td>
@@ -3694,7 +3700,9 @@ var PlanOfCareTemplate = class {
3694
3700
  generateSummaryNarrative(resources, timezone) {
3695
3701
  const templateUtilities = new TemplateUtilities(resources);
3696
3702
  let isSummaryCreated = false;
3697
- let html = `
3703
+ let html = `<p>This list includes all CarePlan resources, sorted by planned end date (most recent first).</p>
3704
+ `;
3705
+ html += `
3698
3706
  <div>
3699
3707
  <table>
3700
3708
  <thead>
@@ -3721,7 +3729,7 @@ var PlanOfCareTemplate = class {
3721
3729
  isSummaryCreated = true;
3722
3730
  html += `
3723
3731
  <tr>
3724
- <td>${data["CarePlan Name"] ?? ""}</td>
3732
+ <td>${templateUtilities.capitalizeFirstLetter(data["CarePlan Name"] ?? "")}</td>
3725
3733
  <td>${templateUtilities.renderTime(data["created"], timezone) ?? ""}</td>
3726
3734
  <td>${templateUtilities.renderTime(data["period.start"], timezone) ?? ""}</td>
3727
3735
  <td>${templateUtilities.renderTime(data["period.end"], timezone) ?? ""}</td>
@@ -3756,7 +3764,7 @@ var FunctionalStatusTemplate = class _FunctionalStatusTemplate {
3756
3764
  */
3757
3765
  static generateStaticNarrative(resources, timezone) {
3758
3766
  const templateUtilities = new TemplateUtilities(resources);
3759
- let html = "";
3767
+ let html = `<p>This section summarizes key observations and assessments related to the person's functional status and ability to perform daily activities.</p>`;
3760
3768
  let functionalObservations = resources.filter((r) => r.resourceType === "Observation").filter((r) => {
3761
3769
  const hasFunctionalLoinc = r.code?.coding?.some(
3762
3770
  (c) => c.system?.toLowerCase().includes("loinc") && c.code === "47420-5"
@@ -3786,8 +3794,8 @@ var FunctionalStatusTemplate = class _FunctionalStatusTemplate {
3786
3794
  const date = observation.effectiveDateTime ? templateUtilities.renderDate(observation.effectiveDateTime) : observation.issued ? templateUtilities.renderDate(observation.issued) : "";
3787
3795
  const interpretation = observation.interpretation ? templateUtilities.codeableConceptDisplay(observation.interpretation[0]) : "";
3788
3796
  const comments = observation.comment || observation.note?.map((n) => n.text).join("; ") || "";
3789
- html += `<tr id="${templateUtilities.narrativeLinkId(observation)}">
3790
- <td>${obsName}</td>
3797
+ html += `<tr>
3798
+ <td>${templateUtilities.capitalizeFirstLetter(obsName)}</td>
3791
3799
  <td>${value ?? ""}</td>
3792
3800
  <td>${date}</td>
3793
3801
  <td>${interpretation}</td>
@@ -3817,7 +3825,7 @@ var FunctionalStatusTemplate = class _FunctionalStatusTemplate {
3817
3825
  }
3818
3826
  findingsHtml += "</ul>";
3819
3827
  }
3820
- html += `<tr id="${templateUtilities.narrativeLinkId(impression)}">
3828
+ html += `<tr>
3821
3829
  <td>${formattedDate}</td>
3822
3830
  <td>${impression.status || ""}</td>
3823
3831
  <td>${impression.description || ""}</td>
@@ -3880,7 +3888,8 @@ var PregnancyTemplate = class _PregnancyTemplate {
3880
3888
  if (!pregnancyStatusObs && !eddObs && historyObs.length === 0 && conditions.length === 0) {
3881
3889
  return `<p>No history of pregnancy found.</p>`;
3882
3890
  }
3883
- let html = `
3891
+ let html = `<p>This list includes Observation and Condition resources relevant to pregnancy, sorted by date (most recent first).</p>`;
3892
+ html += `
3884
3893
  <table>
3885
3894
  <thead>
3886
3895
  <tr>
@@ -3892,10 +3901,10 @@ var PregnancyTemplate = class _PregnancyTemplate {
3892
3901
  </tr>
3893
3902
  </thead>
3894
3903
  <tbody>`;
3895
- function renderRow({ id, result, comments, date, codeSystem, owner }) {
3904
+ function renderRow({ result, comments, date, codeSystem, owner }) {
3896
3905
  html += `
3897
- <tr id="${id}">
3898
- <td class="Result">${result}</td>
3906
+ <tr>
3907
+ <td class="Result">${templateUtilities.capitalizeFirstLetter(result)}</td>
3899
3908
  <td class="CodeSystem">${codeSystem}</td>
3900
3909
  <td class="Comments">${comments}</td>
3901
3910
  <td class="Date">${date}</td>
@@ -3926,9 +3935,9 @@ var PregnancyTemplate = class _PregnancyTemplate {
3926
3935
  if (!b.date) return -1;
3927
3936
  return new Date(b.date).getTime() - new Date(a.date).getTime();
3928
3937
  });
3938
+ const addedRows = /* @__PURE__ */ new Set();
3929
3939
  for (const { resource, date, type } of rowResources) {
3930
3940
  let result = "", comments = "", dateStr = "", codeSystem = "";
3931
- const id = templateUtilities.narrativeLinkId(resource);
3932
3941
  if (type === "status") {
3933
3942
  result = templateUtilities.renderTextAsHtml(templateUtilities.extractPregnancyStatus(resource));
3934
3943
  comments = templateUtilities.renderNotes(resource.note, timezone);
@@ -3950,8 +3959,12 @@ var PregnancyTemplate = class _PregnancyTemplate {
3950
3959
  dateStr = date ? templateUtilities.renderTextAsHtml(templateUtilities.renderTime(date, timezone)) : "";
3951
3960
  codeSystem = templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptCoding(resource.code));
3952
3961
  }
3953
- const owner = templateUtilities.getOwnerTag(resource);
3954
- renderRow({ id, result, comments, date: dateStr, codeSystem, owner });
3962
+ const rowKey = `${result}|${codeSystem}`;
3963
+ if (!addedRows.has(rowKey)) {
3964
+ addedRows.add(rowKey);
3965
+ const owner = templateUtilities.getOwnerTag(resource);
3966
+ renderRow({ result, comments, date: dateStr, codeSystem, owner });
3967
+ }
3955
3968
  }
3956
3969
  html += `
3957
3970
  </tbody>
@@ -3985,8 +3998,9 @@ var AdvanceDirectivesTemplate = class _AdvanceDirectivesTemplate {
3985
3998
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
3986
3999
  static generateStaticNarrative(resources, timezone) {
3987
4000
  const templateUtilities = new TemplateUtilities(resources);
3988
- let html = `
3989
- <table>
4001
+ let html = `<p>This list includes all Consent resources, sorted by date (most recent first).</p>
4002
+ `;
4003
+ html += `<table>
3990
4004
  <thead>
3991
4005
  <tr>
3992
4006
  <th>Scope</th>
@@ -3999,8 +4013,8 @@ var AdvanceDirectivesTemplate = class _AdvanceDirectivesTemplate {
3999
4013
  for (const resourceItem of resources) {
4000
4014
  const consent = resourceItem;
4001
4015
  html += `
4002
- <tr id="${templateUtilities.narrativeLinkId(consent)}">
4003
- <td>${templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(consent.scope, "display"))}</td>
4016
+ <tr>
4017
+ <td>${templateUtilities.capitalizeFirstLetter(templateUtilities.renderTextAsHtml(templateUtilities.codeableConceptDisplay(consent.scope, "display")))}</td>
4004
4018
  <td>${consent.status || ""}</td>
4005
4019
  <td>${consent.provision?.action ? templateUtilities.concatCodeableConcept(consent.provision.action) : ""}</td>
4006
4020
  <td>${consent.dateTime || ""}</td>
@@ -4315,14 +4329,17 @@ var ComprehensiveIPSCompositionBuilder = class {
4315
4329
  const summaryIPSCompositionFilter = useSummaryCompositions ? IPSSectionResourceHelper.getSummaryIPSCompositionFilterForSection(sectionType) : void 0;
4316
4330
  const sectionIPSSummary = summaryIPSCompositionFilter ? resources.filter((resource) => summaryIPSCompositionFilter(resource)) : [];
4317
4331
  if (sectionIPSSummary.length > 0) {
4332
+ console.log(`Using IPS summary composition for section: ${sectionType}`);
4318
4333
  await this.makeSectionFromSummaryAsync(sectionType, sectionIPSSummary, resources, timezone);
4319
4334
  continue;
4320
4335
  }
4321
4336
  const summaryCompositionFilter = useSummaryCompositions ? IPSSectionResourceHelper.getSummaryCompositionFilterForSection(sectionType) : void 0;
4322
4337
  const sectionSummary = summaryCompositionFilter ? resources.filter((resource) => summaryCompositionFilter(resource)) : [];
4323
4338
  if (sectionSummary.length > 0) {
4339
+ console.log(`Using summary composition for section: ${sectionType}`);
4324
4340
  await this.makeSectionFromSummaryAsync(sectionType, sectionSummary, resources, timezone);
4325
4341
  } else {
4342
+ console.log(`Using individual resources for section: ${sectionType}`);
4326
4343
  const sectionFilter = IPSSectionResourceHelper.getResourceFilterForSection(sectionType);
4327
4344
  const sectionResources = resources.filter((resource) => sectionFilter(resource));
4328
4345
  await this.makeSectionAsync(sectionType, sectionResources, timezone);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imranq2/fhirpatientsummary",
3
- "version": "1.0.30",
3
+ "version": "1.0.32",
4
4
  "description": "A template for creating npm packages using TypeScript and VSCode",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",