@checkstack/notification-teams-backend 0.0.30 → 0.0.31

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/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @checkstack/notification-teams-backend
2
2
 
3
+ ## 0.0.31
4
+
5
+ ### Patch Changes
6
+
7
+ - 32d52c6: Bulk notifications affecting multiple systems and collapse lifecycle events into a single card.
8
+
9
+ Notifications now carry an optional `subjects` array (the entities they affect) and an optional `collapseKey` (so related notifications collapse into one row per recipient). Incidents, maintenances, anomalies, healthchecks, and dependency-impact events route through these new fields, so an incident affecting three systems produces one in-app notification + one external send per subscriber instead of three. Lifecycle updates for the same entity (created → updated → resolved) also collapse, with an expandable "+N updates" timeline.
10
+
11
+ Subject kinds are namespaced as `<pluginId>.<localKind>` and built via type-safe helpers exported from each domain's common package (`createSystemSubject`, `incidentCollapseKey`, etc.). The frontend kind registry (`registerSubjectKind`) lets plugins bind icon + label for their kinds; unknown kinds fall back to a generic chip.
12
+
13
+ All notification strategies (SMTP, Slack, Discord, Teams, Telegram, Pushover, Gotify, Webex, Backstage) render the affected subjects natively in their format (HTML cards, Slack blocks, Discord embed fields, adaptive cards, markdown lists, etc.).
14
+
15
+ - Updated dependencies [32d52c6]
16
+ - Updated dependencies [32d52c6]
17
+ - Updated dependencies [32d52c6]
18
+ - Updated dependencies [32d52c6]
19
+ - @checkstack/notification-backend@1.0.0
20
+ - @checkstack/backend-api@0.14.0
21
+
3
22
  ## 0.0.30
4
23
 
5
24
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@checkstack/notification-teams-backend",
3
- "version": "0.0.30",
3
+ "version": "0.0.31",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "checkstack": {
@@ -15,9 +15,9 @@
15
15
  "lint": "eslint src --ext .ts"
16
16
  },
17
17
  "dependencies": {
18
- "@checkstack/backend-api": "0.13.0",
18
+ "@checkstack/backend-api": "0.13.1",
19
19
  "@checkstack/common": "0.7.0",
20
- "@checkstack/notification-backend": "0.2.0",
20
+ "@checkstack/notification-backend": "0.2.1",
21
21
  "zod": "^4.2.1"
22
22
  },
23
23
  "devDependencies": {
package/src/index.ts CHANGED
@@ -6,6 +6,7 @@ import {
6
6
  type NotificationStrategy,
7
7
  type NotificationSendContext,
8
8
  type NotificationDeliveryResult,
9
+ type NotificationSubject,
9
10
  type StrategyOAuthConfig,
10
11
  } from "@checkstack/backend-api";
11
12
  import { notificationStrategyExtensionPoint } from "@checkstack/notification-backend";
@@ -97,10 +98,18 @@ interface AdaptiveCardOptions {
97
98
  body?: string;
98
99
  importance: "info" | "warning" | "critical";
99
100
  action?: { label: string; url: string };
101
+ subjects?: NotificationSubject[];
100
102
  }
101
103
 
104
+ const SUBJECT_STATUS_EMOJI = {
105
+ healthy: "🟢",
106
+ degraded: "🟡",
107
+ unhealthy: "🔴",
108
+ unknown: "⚪",
109
+ } as const;
110
+
102
111
  function buildAdaptiveCard(options: AdaptiveCardOptions): object {
103
- const { title, body, importance, action } = options;
112
+ const { title, body, importance, action, subjects } = options;
104
113
 
105
114
  const importanceColors: Record<string, string> = {
106
115
  info: "accent",
@@ -133,6 +142,32 @@ function buildAdaptiveCard(options: AdaptiveCardOptions): object {
133
142
  });
134
143
  }
135
144
 
145
+ if (subjects && subjects.length > 0) {
146
+ // Affected entities rendered as a FactSet — names link to URLs when
147
+ // present; status maps to a colored circle.
148
+ bodyElements.push(
149
+ {
150
+ type: "TextBlock",
151
+ text: "**Affected**",
152
+ weight: "bolder",
153
+ spacing: "medium",
154
+ wrap: true,
155
+ },
156
+ {
157
+ type: "FactSet",
158
+ facts: subjects.map((subject) => {
159
+ const prefix = subject.status
160
+ ? `${SUBJECT_STATUS_EMOJI[subject.status]} `
161
+ : "";
162
+ return {
163
+ title: prefix + subject.name,
164
+ value: subject.url ? `[Open](${subject.url})` : "—",
165
+ };
166
+ }),
167
+ },
168
+ );
169
+ }
170
+
136
171
  const card: Record<string, unknown> = {
137
172
  type: "AdaptiveCard",
138
173
  $schema: "http://adaptivecards.io/schemas/adaptive-card.json",
@@ -299,6 +334,7 @@ const teamsStrategy: NotificationStrategy<TeamsConfig> = {
299
334
  body: notification.body,
300
335
  importance: notification.importance,
301
336
  action: notification.action,
337
+ subjects: notification.subjects,
302
338
  });
303
339
 
304
340
  // Step 3: Send message to the chat