@imranq2/fhirpatientsummary 1.0.34 → 1.0.36

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.
package/dist/index.cjs CHANGED
@@ -200,7 +200,9 @@ var IPSSectionSummaryCompositionFilter = {
200
200
  };
201
201
  var IPSSectionSummaryIPSCompositionFilter = {
202
202
  ["Patient" /* PATIENT */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => codingMatches(c, "ips_patient_summary_document", IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM)),
203
- ["VitalSignsSection" /* VITAL_SIGNS */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => codingMatches(c, "ips_vital_summary_document", IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM))
203
+ ["VitalSignsSection" /* VITAL_SIGNS */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => codingMatches(c, "ips_vital_summary_document", IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM)),
204
+ ["SocialHistorySection" /* SOCIAL_HISTORY */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => codingMatches(c, "ips_social_history_summary_document", IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM)),
205
+ ["FunctionalStatusSection" /* FUNCTIONAL_STATUS */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => codingMatches(c, ["ips_functional_status_condition_summary_document", "ips_functional_status_clinical_impression_summary_document"], IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM))
204
206
  };
205
207
  var IPSSectionResourceHelper = class {
206
208
  static getResourceFilterForSection(section) {
@@ -3670,6 +3672,61 @@ var SocialHistoryTemplate = class _SocialHistoryTemplate {
3670
3672
  generateNarrative(resources, timezone) {
3671
3673
  return _SocialHistoryTemplate.generateStaticNarrative(resources, timezone);
3672
3674
  }
3675
+ /**
3676
+ * Generate HTML narrative for social history using summary
3677
+ * @param resources - FHIR Composition resources
3678
+ * @param timezone - Optional timezone to use for date formatting (e.g., 'America/New_York', 'Europe/London')
3679
+ * @returns HTML string for rendering
3680
+ */
3681
+ generateSummaryNarrative(resources, timezone) {
3682
+ const templateUtilities = new TemplateUtilities(resources);
3683
+ let isSummaryCreated = false;
3684
+ let html = `<p>This list includes all information about the patient's social history, sorted by effective date (most recent first).</p>
3685
+ `;
3686
+ html += `
3687
+ <div>
3688
+ <table>
3689
+ <thead>
3690
+ <tr>
3691
+ <th>Name</th>
3692
+ <th>Code (System)</th>
3693
+ <th>Result</th>
3694
+ <th>Date</th>
3695
+ <th>Comments</th>
3696
+ </tr>
3697
+ </thead>
3698
+ <tbody>`;
3699
+ for (const resourceItem of resources) {
3700
+ for (const rowData of resourceItem.section ?? []) {
3701
+ const sectionCodeableConcept = rowData.code;
3702
+ const data = {};
3703
+ data["codeSystem"] = templateUtilities.codeableConceptCoding(sectionCodeableConcept);
3704
+ for (const columnData of rowData.section ?? []) {
3705
+ const columnTitle = columnData.title;
3706
+ if (columnTitle) {
3707
+ data[columnTitle] = templateUtilities.renderTextAsHtml(columnData.text?.div ?? "");
3708
+ }
3709
+ }
3710
+ if (data["Social History Name"]?.toLowerCase() === "unknown") {
3711
+ continue;
3712
+ }
3713
+ isSummaryCreated = true;
3714
+ html += `
3715
+ <tr>
3716
+ <td>${templateUtilities.capitalizeFirstLetter(data["Social History Name"] ?? "")}</td>
3717
+ <td>${data["codeSystem"] ?? ""}</td>
3718
+ <td>${templateUtilities.extractObservationSummaryValue(data, timezone) ?? ""}</td>
3719
+ <td>${templateUtilities.extractObservationSummaryEffectiveTime(data, timezone) ?? ""}</td>
3720
+ <td>${data["Notes"] ?? ""}</td>
3721
+ </tr>`;
3722
+ }
3723
+ }
3724
+ html += `
3725
+ </tbody>
3726
+ </table>
3727
+ </div>`;
3728
+ return isSummaryCreated ? html : void 0;
3729
+ }
3673
3730
  /**
3674
3731
  * Internal static implementation that actually generates the narrative
3675
3732
  * @param resources - FHIR Observation resources
@@ -3977,6 +4034,130 @@ var FunctionalStatusTemplate = class _FunctionalStatusTemplate {
3977
4034
  generateNarrative(resources, timezone) {
3978
4035
  return _FunctionalStatusTemplate.generateStaticNarrative(resources, timezone);
3979
4036
  }
4037
+ /**
4038
+ * Generate HTML narrative for Functional Status Condition & ClinicalImpression resources using summary
4039
+ * @param resources - FHIR Composition resources
4040
+ * @param timezone - Optional timezone to use for date formatting (e.g., 'America/New_York', 'Europe/London')
4041
+ * @param now - Optional current date for filtering
4042
+ * @returns HTML string for rendering
4043
+ */
4044
+ generateSummaryNarrative(resources, timezone) {
4045
+ const templateUtilities = new TemplateUtilities(resources);
4046
+ let html = `
4047
+ <div>
4048
+ <p>This section summarizes key conditions and assessments related to the person's functional status and ability to perform daily activities.</p>`;
4049
+ let conditionHtml = `
4050
+ <div>
4051
+ <h3>Conditions</h3>
4052
+ <table>
4053
+ <thead>
4054
+ <tr>
4055
+ <th>Problem</th>
4056
+ <th>Code (System)</th>
4057
+ <th>Onset Date</th>
4058
+ <th>Recorded Date</th>
4059
+ </tr>
4060
+ </thead>
4061
+ <tbody>`;
4062
+ let clinicalImpressionsHtml = `
4063
+ <div>
4064
+ <h3>Clinical Impressions</h3>
4065
+ <table>
4066
+ <thead>
4067
+ <tr>
4068
+ <th>Name</th>
4069
+ <th>Date</th>
4070
+ <th>Code (System)</th>
4071
+ <th>Description</th>
4072
+ <th>Summary</th>
4073
+ </tr>
4074
+ </thead>
4075
+ <tbody>`;
4076
+ const conditionsAdded = /* @__PURE__ */ new Set();
4077
+ const clinicalImpressionsAdded = /* @__PURE__ */ new Set();
4078
+ for (const resourceItem of resources) {
4079
+ for (const rowData of resourceItem.section ?? []) {
4080
+ const sectionCodeableConcept = rowData.code;
4081
+ const data = {};
4082
+ for (const columnData of rowData.section ?? []) {
4083
+ if (columnData.title) {
4084
+ data[columnData.title] = templateUtilities.renderTextAsHtml(
4085
+ columnData.text?.div ?? ""
4086
+ );
4087
+ }
4088
+ }
4089
+ if (resourceItem.title === "Condition|Condition Summary Grouped by Functional Status Code") {
4090
+ let date = data["onsetDateTime"] ? templateUtilities.renderTime(data["onsetDateTime"], timezone) : "";
4091
+ if (!date && data["onsetPeriod.start"]) {
4092
+ date = templateUtilities.renderTime(
4093
+ data["onsetPeriod.start"],
4094
+ timezone
4095
+ );
4096
+ if (data["onsetPeriod.end"]) {
4097
+ date += " - " + templateUtilities.renderTime(data["onsetPeriod.end"], timezone);
4098
+ }
4099
+ }
4100
+ const problem = data["Condition Name"];
4101
+ if (problem && !conditionsAdded.has(problem)) {
4102
+ if (problem.toLowerCase() === "unknown") {
4103
+ continue;
4104
+ }
4105
+ conditionsAdded.add(problem);
4106
+ conditionHtml += `
4107
+ <tr>
4108
+ <td>${templateUtilities.capitalizeFirstLetter(problem)}</td>
4109
+ <td>${templateUtilities.codeableConceptCoding(sectionCodeableConcept)}</td>
4110
+ <td>${date}</td>
4111
+ <td>${templateUtilities.renderTime(data["recordedDate"], timezone) ?? ""}</td>
4112
+ </tr>`;
4113
+ }
4114
+ } else if (resourceItem.title === "Clinical Impression|Clinical Impression Summary") {
4115
+ let date = data["effectiveDateTime"] ? templateUtilities.renderTime(data["effectiveDateTime"], timezone) : "";
4116
+ if (!date && data["effectivePeriod.start"]) {
4117
+ date = templateUtilities.renderTime(
4118
+ data["effectivePeriod.start"],
4119
+ timezone
4120
+ );
4121
+ if (data["effectivePeriod.end"]) {
4122
+ date += " - " + templateUtilities.renderTime(data["effectivePeriod.end"], timezone);
4123
+ }
4124
+ }
4125
+ const name = data["Clinical Impression Name"];
4126
+ if (name && !clinicalImpressionsAdded.has(name)) {
4127
+ if (name?.toLowerCase() === "unknown") {
4128
+ continue;
4129
+ }
4130
+ clinicalImpressionsAdded.add(name);
4131
+ clinicalImpressionsHtml += `
4132
+ <tr>
4133
+ <td>${templateUtilities.capitalizeFirstLetter(name)}</td>
4134
+ <td>${date ?? ""}</td>
4135
+ <td>${templateUtilities.codeableConceptCoding(sectionCodeableConcept)}</td>
4136
+ <td>${data["Description"] ?? ""}</td>
4137
+ <td>${data["Summary"] ?? ""}</td>
4138
+ </tr>`;
4139
+ }
4140
+ }
4141
+ }
4142
+ }
4143
+ if (conditionsAdded.size > 0) {
4144
+ html += conditionHtml;
4145
+ html += `
4146
+ </tbody>
4147
+ </table>
4148
+ </div>`;
4149
+ }
4150
+ if (clinicalImpressionsAdded.size > 0) {
4151
+ html += clinicalImpressionsHtml;
4152
+ html += `
4153
+ </tbody>
4154
+ </table>
4155
+ </div>`;
4156
+ }
4157
+ html += `
4158
+ </div>`;
4159
+ return conditionsAdded.size > 0 || clinicalImpressionsAdded.size > 0 ? html : void 0;
4160
+ }
3980
4161
  /**
3981
4162
  * Internal static implementation that actually generates the narrative
3982
4163
  * @param resources - FHIR resources array containing Observation resources
package/dist/index.js CHANGED
@@ -172,7 +172,9 @@ var IPSSectionSummaryCompositionFilter = {
172
172
  };
173
173
  var IPSSectionSummaryIPSCompositionFilter = {
174
174
  ["Patient" /* PATIENT */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => codingMatches(c, "ips_patient_summary_document", IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM)),
175
- ["VitalSignsSection" /* VITAL_SIGNS */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => codingMatches(c, "ips_vital_summary_document", IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM))
175
+ ["VitalSignsSection" /* VITAL_SIGNS */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => codingMatches(c, "ips_vital_summary_document", IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM)),
176
+ ["SocialHistorySection" /* SOCIAL_HISTORY */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => codingMatches(c, "ips_social_history_summary_document", IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM)),
177
+ ["FunctionalStatusSection" /* FUNCTIONAL_STATUS */]: (resource) => resource.resourceType === "Composition" && resource.type?.coding?.some((c) => codingMatches(c, ["ips_functional_status_condition_summary_document", "ips_functional_status_clinical_impression_summary_document"], IPS_SUMMARY_COMPOSITION_TYPE_SYSTEM))
176
178
  };
177
179
  var IPSSectionResourceHelper = class {
178
180
  static getResourceFilterForSection(section) {
@@ -3642,6 +3644,61 @@ var SocialHistoryTemplate = class _SocialHistoryTemplate {
3642
3644
  generateNarrative(resources, timezone) {
3643
3645
  return _SocialHistoryTemplate.generateStaticNarrative(resources, timezone);
3644
3646
  }
3647
+ /**
3648
+ * Generate HTML narrative for social history using summary
3649
+ * @param resources - FHIR Composition resources
3650
+ * @param timezone - Optional timezone to use for date formatting (e.g., 'America/New_York', 'Europe/London')
3651
+ * @returns HTML string for rendering
3652
+ */
3653
+ generateSummaryNarrative(resources, timezone) {
3654
+ const templateUtilities = new TemplateUtilities(resources);
3655
+ let isSummaryCreated = false;
3656
+ let html = `<p>This list includes all information about the patient's social history, sorted by effective date (most recent first).</p>
3657
+ `;
3658
+ html += `
3659
+ <div>
3660
+ <table>
3661
+ <thead>
3662
+ <tr>
3663
+ <th>Name</th>
3664
+ <th>Code (System)</th>
3665
+ <th>Result</th>
3666
+ <th>Date</th>
3667
+ <th>Comments</th>
3668
+ </tr>
3669
+ </thead>
3670
+ <tbody>`;
3671
+ for (const resourceItem of resources) {
3672
+ for (const rowData of resourceItem.section ?? []) {
3673
+ const sectionCodeableConcept = rowData.code;
3674
+ const data = {};
3675
+ data["codeSystem"] = templateUtilities.codeableConceptCoding(sectionCodeableConcept);
3676
+ for (const columnData of rowData.section ?? []) {
3677
+ const columnTitle = columnData.title;
3678
+ if (columnTitle) {
3679
+ data[columnTitle] = templateUtilities.renderTextAsHtml(columnData.text?.div ?? "");
3680
+ }
3681
+ }
3682
+ if (data["Social History Name"]?.toLowerCase() === "unknown") {
3683
+ continue;
3684
+ }
3685
+ isSummaryCreated = true;
3686
+ html += `
3687
+ <tr>
3688
+ <td>${templateUtilities.capitalizeFirstLetter(data["Social History Name"] ?? "")}</td>
3689
+ <td>${data["codeSystem"] ?? ""}</td>
3690
+ <td>${templateUtilities.extractObservationSummaryValue(data, timezone) ?? ""}</td>
3691
+ <td>${templateUtilities.extractObservationSummaryEffectiveTime(data, timezone) ?? ""}</td>
3692
+ <td>${data["Notes"] ?? ""}</td>
3693
+ </tr>`;
3694
+ }
3695
+ }
3696
+ html += `
3697
+ </tbody>
3698
+ </table>
3699
+ </div>`;
3700
+ return isSummaryCreated ? html : void 0;
3701
+ }
3645
3702
  /**
3646
3703
  * Internal static implementation that actually generates the narrative
3647
3704
  * @param resources - FHIR Observation resources
@@ -3949,6 +4006,130 @@ var FunctionalStatusTemplate = class _FunctionalStatusTemplate {
3949
4006
  generateNarrative(resources, timezone) {
3950
4007
  return _FunctionalStatusTemplate.generateStaticNarrative(resources, timezone);
3951
4008
  }
4009
+ /**
4010
+ * Generate HTML narrative for Functional Status Condition & ClinicalImpression resources using summary
4011
+ * @param resources - FHIR Composition resources
4012
+ * @param timezone - Optional timezone to use for date formatting (e.g., 'America/New_York', 'Europe/London')
4013
+ * @param now - Optional current date for filtering
4014
+ * @returns HTML string for rendering
4015
+ */
4016
+ generateSummaryNarrative(resources, timezone) {
4017
+ const templateUtilities = new TemplateUtilities(resources);
4018
+ let html = `
4019
+ <div>
4020
+ <p>This section summarizes key conditions and assessments related to the person's functional status and ability to perform daily activities.</p>`;
4021
+ let conditionHtml = `
4022
+ <div>
4023
+ <h3>Conditions</h3>
4024
+ <table>
4025
+ <thead>
4026
+ <tr>
4027
+ <th>Problem</th>
4028
+ <th>Code (System)</th>
4029
+ <th>Onset Date</th>
4030
+ <th>Recorded Date</th>
4031
+ </tr>
4032
+ </thead>
4033
+ <tbody>`;
4034
+ let clinicalImpressionsHtml = `
4035
+ <div>
4036
+ <h3>Clinical Impressions</h3>
4037
+ <table>
4038
+ <thead>
4039
+ <tr>
4040
+ <th>Name</th>
4041
+ <th>Date</th>
4042
+ <th>Code (System)</th>
4043
+ <th>Description</th>
4044
+ <th>Summary</th>
4045
+ </tr>
4046
+ </thead>
4047
+ <tbody>`;
4048
+ const conditionsAdded = /* @__PURE__ */ new Set();
4049
+ const clinicalImpressionsAdded = /* @__PURE__ */ new Set();
4050
+ for (const resourceItem of resources) {
4051
+ for (const rowData of resourceItem.section ?? []) {
4052
+ const sectionCodeableConcept = rowData.code;
4053
+ const data = {};
4054
+ for (const columnData of rowData.section ?? []) {
4055
+ if (columnData.title) {
4056
+ data[columnData.title] = templateUtilities.renderTextAsHtml(
4057
+ columnData.text?.div ?? ""
4058
+ );
4059
+ }
4060
+ }
4061
+ if (resourceItem.title === "Condition|Condition Summary Grouped by Functional Status Code") {
4062
+ let date = data["onsetDateTime"] ? templateUtilities.renderTime(data["onsetDateTime"], timezone) : "";
4063
+ if (!date && data["onsetPeriod.start"]) {
4064
+ date = templateUtilities.renderTime(
4065
+ data["onsetPeriod.start"],
4066
+ timezone
4067
+ );
4068
+ if (data["onsetPeriod.end"]) {
4069
+ date += " - " + templateUtilities.renderTime(data["onsetPeriod.end"], timezone);
4070
+ }
4071
+ }
4072
+ const problem = data["Condition Name"];
4073
+ if (problem && !conditionsAdded.has(problem)) {
4074
+ if (problem.toLowerCase() === "unknown") {
4075
+ continue;
4076
+ }
4077
+ conditionsAdded.add(problem);
4078
+ conditionHtml += `
4079
+ <tr>
4080
+ <td>${templateUtilities.capitalizeFirstLetter(problem)}</td>
4081
+ <td>${templateUtilities.codeableConceptCoding(sectionCodeableConcept)}</td>
4082
+ <td>${date}</td>
4083
+ <td>${templateUtilities.renderTime(data["recordedDate"], timezone) ?? ""}</td>
4084
+ </tr>`;
4085
+ }
4086
+ } else if (resourceItem.title === "Clinical Impression|Clinical Impression Summary") {
4087
+ let date = data["effectiveDateTime"] ? templateUtilities.renderTime(data["effectiveDateTime"], timezone) : "";
4088
+ if (!date && data["effectivePeriod.start"]) {
4089
+ date = templateUtilities.renderTime(
4090
+ data["effectivePeriod.start"],
4091
+ timezone
4092
+ );
4093
+ if (data["effectivePeriod.end"]) {
4094
+ date += " - " + templateUtilities.renderTime(data["effectivePeriod.end"], timezone);
4095
+ }
4096
+ }
4097
+ const name = data["Clinical Impression Name"];
4098
+ if (name && !clinicalImpressionsAdded.has(name)) {
4099
+ if (name?.toLowerCase() === "unknown") {
4100
+ continue;
4101
+ }
4102
+ clinicalImpressionsAdded.add(name);
4103
+ clinicalImpressionsHtml += `
4104
+ <tr>
4105
+ <td>${templateUtilities.capitalizeFirstLetter(name)}</td>
4106
+ <td>${date ?? ""}</td>
4107
+ <td>${templateUtilities.codeableConceptCoding(sectionCodeableConcept)}</td>
4108
+ <td>${data["Description"] ?? ""}</td>
4109
+ <td>${data["Summary"] ?? ""}</td>
4110
+ </tr>`;
4111
+ }
4112
+ }
4113
+ }
4114
+ }
4115
+ if (conditionsAdded.size > 0) {
4116
+ html += conditionHtml;
4117
+ html += `
4118
+ </tbody>
4119
+ </table>
4120
+ </div>`;
4121
+ }
4122
+ if (clinicalImpressionsAdded.size > 0) {
4123
+ html += clinicalImpressionsHtml;
4124
+ html += `
4125
+ </tbody>
4126
+ </table>
4127
+ </div>`;
4128
+ }
4129
+ html += `
4130
+ </div>`;
4131
+ return conditionsAdded.size > 0 || clinicalImpressionsAdded.size > 0 ? html : void 0;
4132
+ }
3952
4133
  /**
3953
4134
  * Internal static implementation that actually generates the narrative
3954
4135
  * @param resources - FHIR resources array containing Observation resources
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imranq2/fhirpatientsummary",
3
- "version": "1.0.34",
3
+ "version": "1.0.36",
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",