@wopr-network/platform-core 1.14.6 → 1.14.7

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.
@@ -41,8 +41,8 @@ _[PENDING: Describe what fixed the issue and how service was restored.]_`,
41
41
  actionItems: `| Action | Owner | Due Date | Priority |
42
42
  |--------|-------|----------|----------|
43
43
  | _[PENDING: Add action item]_ | _[PENDING: Owner]_ | _[PENDING: Date]_ | P1 |
44
- | Improve detection alert thresholds | on-call-engineer | TBD | P2 |
45
- | Add runbook link to alert notification | on-call-engineer | TBD | P2 |`,
44
+ | Improve detection alert thresholds | on-call-engineer | ${actionItemDueDate(incident)} | P2 |
45
+ | Add runbook link to alert notification | on-call-engineer | ${actionItemDueDate(incident)} | P2 |`,
46
46
  lessonsLearned: `**What went well:**
47
47
  - _[PENDING: What worked well in detection and response?]_
48
48
 
@@ -124,3 +124,9 @@ function formatDuration(ms) {
124
124
  return `${hours}h`;
125
125
  return `${hours}h ${remainingMinutes}m`;
126
126
  }
127
+ function actionItemDueDate(incident) {
128
+ const base = incident.resolvedAt ?? incident.startedAt;
129
+ const offsetDays = incident.severity === "SEV1" ? 7 : 14;
130
+ const due = new Date(base.getTime() + offsetDays * 24 * 60 * 60 * 1000);
131
+ return due.toISOString().split("T")[0];
132
+ }
@@ -101,4 +101,39 @@ describe("generatePostMortemTemplate", () => {
101
101
  expect(report.sections.actionItems).not.toContain("TODO");
102
102
  expect(report.sections.lessonsLearned).not.toContain("TODO");
103
103
  });
104
+ it("action items derive due dates from resolvedAt for resolved incidents", () => {
105
+ const report = generatePostMortemTemplate(makeIncident({
106
+ resolvedAt: new Date("2026-01-15T13:00:00Z"),
107
+ severity: "SEV1",
108
+ }));
109
+ // SEV1: 7-day offset from resolvedAt → 2026-01-22
110
+ expect(report.sections.actionItems).toContain("2026-01-22");
111
+ expect(report.sections.actionItems).not.toContain("TBD");
112
+ });
113
+ it("action items derive due dates from startedAt for ongoing incidents", () => {
114
+ const report = generatePostMortemTemplate(makeIncident({
115
+ resolvedAt: null,
116
+ startedAt: new Date("2026-01-15T12:00:00Z"),
117
+ severity: "SEV1",
118
+ }));
119
+ // SEV1: 7-day offset from startedAt → 2026-01-22
120
+ expect(report.sections.actionItems).toContain("2026-01-22");
121
+ expect(report.sections.actionItems).not.toContain("TBD");
122
+ });
123
+ it("SEV2 action items use 14-day offset", () => {
124
+ const report = generatePostMortemTemplate(makeIncident({
125
+ resolvedAt: new Date("2026-01-15T13:00:00Z"),
126
+ severity: "SEV2",
127
+ }));
128
+ // SEV2: 14-day offset from resolvedAt → 2026-01-29
129
+ expect(report.sections.actionItems).toContain("2026-01-29");
130
+ });
131
+ it("SEV3 action items use 14-day offset", () => {
132
+ const report = generatePostMortemTemplate(makeIncident({
133
+ resolvedAt: new Date("2026-01-15T13:00:00Z"),
134
+ severity: "SEV3",
135
+ }));
136
+ // SEV3: 14-day offset from resolvedAt → 2026-01-29
137
+ expect(report.sections.actionItems).toContain("2026-01-29");
138
+ });
104
139
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wopr-network/platform-core",
3
- "version": "1.14.6",
3
+ "version": "1.14.7",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -121,4 +121,51 @@ describe("generatePostMortemTemplate", () => {
121
121
  expect(report.sections.actionItems).not.toContain("TODO");
122
122
  expect(report.sections.lessonsLearned).not.toContain("TODO");
123
123
  });
124
+
125
+ it("action items derive due dates from resolvedAt for resolved incidents", () => {
126
+ const report = generatePostMortemTemplate(
127
+ makeIncident({
128
+ resolvedAt: new Date("2026-01-15T13:00:00Z"),
129
+ severity: "SEV1",
130
+ }),
131
+ );
132
+ // SEV1: 7-day offset from resolvedAt → 2026-01-22
133
+ expect(report.sections.actionItems).toContain("2026-01-22");
134
+ expect(report.sections.actionItems).not.toContain("TBD");
135
+ });
136
+
137
+ it("action items derive due dates from startedAt for ongoing incidents", () => {
138
+ const report = generatePostMortemTemplate(
139
+ makeIncident({
140
+ resolvedAt: null,
141
+ startedAt: new Date("2026-01-15T12:00:00Z"),
142
+ severity: "SEV1",
143
+ }),
144
+ );
145
+ // SEV1: 7-day offset from startedAt → 2026-01-22
146
+ expect(report.sections.actionItems).toContain("2026-01-22");
147
+ expect(report.sections.actionItems).not.toContain("TBD");
148
+ });
149
+
150
+ it("SEV2 action items use 14-day offset", () => {
151
+ const report = generatePostMortemTemplate(
152
+ makeIncident({
153
+ resolvedAt: new Date("2026-01-15T13:00:00Z"),
154
+ severity: "SEV2",
155
+ }),
156
+ );
157
+ // SEV2: 14-day offset from resolvedAt → 2026-01-29
158
+ expect(report.sections.actionItems).toContain("2026-01-29");
159
+ });
160
+
161
+ it("SEV3 action items use 14-day offset", () => {
162
+ const report = generatePostMortemTemplate(
163
+ makeIncident({
164
+ resolvedAt: new Date("2026-01-15T13:00:00Z"),
165
+ severity: "SEV3",
166
+ }),
167
+ );
168
+ // SEV3: 14-day offset from resolvedAt → 2026-01-29
169
+ expect(report.sections.actionItems).toContain("2026-01-29");
170
+ });
124
171
  });
@@ -79,8 +79,8 @@ _[PENDING: Describe what fixed the issue and how service was restored.]_`,
79
79
  actionItems: `| Action | Owner | Due Date | Priority |
80
80
  |--------|-------|----------|----------|
81
81
  | _[PENDING: Add action item]_ | _[PENDING: Owner]_ | _[PENDING: Date]_ | P1 |
82
- | Improve detection alert thresholds | on-call-engineer | TBD | P2 |
83
- | Add runbook link to alert notification | on-call-engineer | TBD | P2 |`,
82
+ | Improve detection alert thresholds | on-call-engineer | ${actionItemDueDate(incident)} | P2 |
83
+ | Add runbook link to alert notification | on-call-engineer | ${actionItemDueDate(incident)} | P2 |`,
84
84
 
85
85
  lessonsLearned: `**What went well:**
86
86
  - _[PENDING: What worked well in detection and response?]_
@@ -165,3 +165,10 @@ function formatDuration(ms: number): string {
165
165
  if (remainingMinutes === 0) return `${hours}h`;
166
166
  return `${hours}h ${remainingMinutes}m`;
167
167
  }
168
+
169
+ function actionItemDueDate(incident: IncidentSummary): string {
170
+ const base = incident.resolvedAt ?? incident.startedAt;
171
+ const offsetDays = incident.severity === "SEV1" ? 7 : 14;
172
+ const due = new Date(base.getTime() + offsetDays * 24 * 60 * 60 * 1000);
173
+ return due.toISOString().split("T")[0];
174
+ }