@oneuptime/common 14.0.2 → 14.0.3

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 (166) hide show
  1. package/Models/DatabaseModels/AlertFeed.ts +2 -0
  2. package/Models/DatabaseModels/IncidentAlert.ts +540 -0
  3. package/Models/DatabaseModels/IncidentFeed.ts +2 -0
  4. package/Models/DatabaseModels/Index.ts +2 -0
  5. package/Models/DatabaseModels/Project.ts +60 -0
  6. package/Models/DatabaseModels/RumApplication.ts +52 -1
  7. package/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.ts +28 -0
  8. package/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.ts +89 -0
  9. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
  10. package/Server/Services/IncidentAlertService.ts +1811 -0
  11. package/Server/Services/IncidentService.ts +210 -10
  12. package/Server/Services/IncidentStateTimelineService.ts +24 -0
  13. package/Server/Services/Index.ts +2 -0
  14. package/Server/Utils/SessionReplay/SessionReplayGateCache.ts +24 -2
  15. package/Tests/App/Dashboard/BulkIncidentLinkActions.test.tsx +869 -0
  16. package/Tests/App/Dashboard/CephMetricTooltips.test.tsx +1777 -0
  17. package/Tests/App/Dashboard/CloudFleetSummary.test.ts +8 -0
  18. package/Tests/App/Dashboard/CloudMetricTooltips.test.tsx +887 -0
  19. package/Tests/App/Dashboard/ContainerHostMetricTooltips.test.tsx +1309 -0
  20. package/Tests/App/Dashboard/DiscoveryScanLivePage.test.tsx +39 -0
  21. package/Tests/App/Dashboard/DockerSwarmClustersListTooltips.test.tsx +414 -0
  22. package/Tests/App/Dashboard/DockerSwarmMetricTooltips.test.ts +796 -0
  23. package/Tests/App/Dashboard/DockerSwarmOverviewTooltips.test.tsx +747 -0
  24. package/Tests/App/Dashboard/ExceptionMonitorEnvironmentFilter.test.tsx +38 -18
  25. package/Tests/App/Dashboard/HostDetailViewTooltips.test.tsx +725 -0
  26. package/Tests/App/Dashboard/HostListColumnTooltips.test.tsx +472 -0
  27. package/Tests/App/Dashboard/HostMetricTooltips.test.ts +709 -0
  28. package/Tests/App/Dashboard/HostOverviewTooltips.test.tsx +698 -0
  29. package/Tests/App/Dashboard/HostTooltipHarness.ts +124 -0
  30. package/Tests/App/Dashboard/HostsListTooltips.test.tsx +395 -0
  31. package/Tests/App/Dashboard/IncidentAlertLinkDialog.test.tsx +691 -0
  32. package/Tests/App/Dashboard/IncidentAlertLinkHelpers.test.ts +458 -0
  33. package/Tests/App/Dashboard/IncidentAlertLinkPages.test.tsx +828 -0
  34. package/Tests/App/Dashboard/IncidentAlertLinkSideMenus.test.tsx +231 -0
  35. package/Tests/App/Dashboard/IncidentCreateFromAlerts.test.tsx +689 -0
  36. package/Tests/App/Dashboard/IoTMetricTooltips.test.tsx +1123 -0
  37. package/Tests/App/Dashboard/KubernetesClusterMetricTooltips.test.ts +837 -0
  38. package/Tests/App/Dashboard/KubernetesClusterOverviewTooltips.test.tsx +699 -0
  39. package/Tests/App/Dashboard/KubernetesContainersTabTooltips.test.tsx +320 -0
  40. package/Tests/App/Dashboard/KubernetesCostTooltips.test.tsx +502 -0
  41. package/Tests/App/Dashboard/KubernetesInsightsTooltips.test.tsx +222 -0
  42. package/Tests/App/Dashboard/KubernetesResourceMetricTooltips.test.ts +561 -0
  43. package/Tests/App/Dashboard/KubernetesResourcePagesTooltips.test.tsx +1168 -0
  44. package/Tests/App/Dashboard/LinkIncidentAlertModal.test.tsx +154 -0
  45. package/Tests/App/Dashboard/MetricDescriptionRules.ts +170 -0
  46. package/Tests/App/Dashboard/MetricDescriptionsCatalog.test.ts +206 -0
  47. package/Tests/App/Dashboard/MetricDescriptionsConsistency.test.ts +275 -0
  48. package/Tests/App/Dashboard/NetworkDeviceTooltips.test.tsx +852 -0
  49. package/Tests/App/Dashboard/NetworkDiagnosticsTooltips.test.tsx +556 -0
  50. package/Tests/App/Dashboard/NetworkMetricTooltips.test.ts +1348 -0
  51. package/Tests/App/Dashboard/NetworkSiteTooltips.test.tsx +679 -0
  52. package/Tests/App/Dashboard/ProxmoxMetricTooltips.test.ts +592 -0
  53. package/Tests/App/Dashboard/ProxmoxOverviewTooltips.test.tsx +1002 -0
  54. package/Tests/App/Dashboard/ProxmoxResourcePageTooltips.test.tsx +923 -0
  55. package/Tests/App/Dashboard/ResourceOverviewTileTooltips.test.tsx +1066 -0
  56. package/Tests/App/Dashboard/RumOverviewPage.test.tsx +1195 -0
  57. package/Tests/App/Dashboard/ServerlessMetricTooltips.test.tsx +474 -0
  58. package/Tests/App/Dashboard/ServiceMetricTooltips.test.tsx +772 -0
  59. package/Tests/App/Dashboard/SessionReplayAuditTable.test.tsx +56 -1
  60. package/Tests/App/Dashboard/TelemetryMetricsSignals.test.ts +1207 -0
  61. package/Tests/App/Dashboard/TelemetryResourceTabTooltips.test.tsx +437 -0
  62. package/Tests/App/Dashboard/VMwareMetricTooltips.test.ts +801 -0
  63. package/Tests/App/Dashboard/VMwareOverviewTooltips.test.tsx +601 -0
  64. package/Tests/App/Dashboard/VMwareResourcePagesTooltips.test.tsx +646 -0
  65. package/Tests/App/Dashboard/VMwareTooltipHarness.ts +145 -0
  66. package/Tests/Models/DatabaseModels/IncidentAlertModel.test.ts +554 -0
  67. package/Tests/Models/DatabaseModels/SessionReplayModels.test.ts +117 -0
  68. package/Tests/Server/Infrastructure/Postgres/AddIncidentAlertMigration.test.ts +341 -0
  69. package/Tests/Server/Infrastructure/Postgres/AddSessionReplaySameOriginTracePropagationMigration.test.ts +247 -0
  70. package/Tests/Server/Services/IncidentAlertPostgres.test.ts +903 -0
  71. package/Tests/Server/Services/IncidentAlertRegistration.test.ts +96 -0
  72. package/Tests/Server/Services/IncidentAlertService.test.ts +2225 -0
  73. package/Tests/Server/Services/IncidentAlertStateCascade.test.ts +970 -0
  74. package/Tests/Server/Services/IncidentCreateFromAlerts.test.ts +1284 -0
  75. package/Tests/Server/Utils/SessionReplay/SessionReplayGateCachePolicy.test.ts +103 -0
  76. package/Tests/Types/Rum/WebVitals.test.ts +173 -0
  77. package/Tests/UI/Components/FieldLabelInfoCardTooltip.test.tsx +413 -0
  78. package/Tests/UI/Components/InfoTooltip.test.tsx +242 -0
  79. package/Tests/UI/Components/ModelTable/BaseModelTableBulkDelete.test.tsx +207 -3
  80. package/Tests/UI/Components/ModelTable/BaseModelTableBulkDeleteVerb.test.tsx +367 -0
  81. package/Tests/UI/Components/ModelTable/BaseModelTableCreateButtonTitle.test.tsx +275 -0
  82. package/Tests/UI/Components/TableHeaderTooltip.test.tsx +662 -0
  83. package/Tests/UI/Rum/PrivacySummaryCard.test.tsx +166 -9
  84. package/Tests/UI/Rum/RecordingHealthTooltips.test.tsx +447 -0
  85. package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +164 -0
  86. package/Tests/UI/Rum/ReplayFrameCapture.test.ts +6750 -0
  87. package/Tests/UI/Rum/ReplayRail.test.tsx +723 -12
  88. package/Tests/UI/Rum/ReplayRailDetail.test.tsx +86 -0
  89. package/Tests/UI/Rum/ReplayScreenshot.test.ts +2124 -0
  90. package/Tests/UI/Rum/ReplayScreenshotActions.test.tsx +3288 -0
  91. package/Tests/UI/Rum/ReplayStage.test.tsx +62 -0
  92. package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +983 -2
  93. package/Tests/UI/Rum/SessionReplaySettingsPolicyLoading.test.tsx +149 -0
  94. package/Tests/UI/Rum/SessionReplaySetupGuide.test.tsx +107 -6
  95. package/Tests/UI/Rum/SessionReplayUsersTableTooltips.test.tsx +330 -0
  96. package/Tests/UI/Rum/UserFlowTooltips.test.tsx +886 -0
  97. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +10 -0
  98. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +2 -0
  99. package/Tests/UI/Utils/PermissionGate.test.ts +76 -0
  100. package/Tests/Utils/Incident/IncidentFromAlerts.test.ts +696 -0
  101. package/Tests/Utils/Rum/SessionTraceState.test.ts +239 -0
  102. package/Types/Incident/IncidentAlertLink.ts +38 -0
  103. package/Types/Permission.ts +48 -0
  104. package/Types/Rum/SessionReplay.ts +25 -6
  105. package/Types/Rum/WebVitals.ts +52 -0
  106. package/UI/Components/Detail/FieldLabel.tsx +8 -0
  107. package/UI/Components/InfoCard/InfoCard.tsx +47 -1
  108. package/UI/Components/ModelTable/BaseModelTable.tsx +95 -17
  109. package/UI/Components/ModelTable/Column.ts +5 -0
  110. package/UI/Components/Table/TableHeader.tsx +47 -2
  111. package/UI/Components/Table/Types/Column.ts +7 -0
  112. package/UI/Components/Tooltip/InfoTooltip.tsx +78 -0
  113. package/UI/Utils/PermissionGate.ts +11 -2
  114. package/Utils/Incident/IncidentFromAlerts.ts +516 -0
  115. package/Utils/Rum/SessionTraceState.ts +212 -0
  116. package/build/dist/Models/DatabaseModels/AlertFeed.js +2 -0
  117. package/build/dist/Models/DatabaseModels/AlertFeed.js.map +1 -1
  118. package/build/dist/Models/DatabaseModels/IncidentAlert.js +553 -0
  119. package/build/dist/Models/DatabaseModels/IncidentAlert.js.map +1 -0
  120. package/build/dist/Models/DatabaseModels/IncidentFeed.js +2 -0
  121. package/build/dist/Models/DatabaseModels/IncidentFeed.js.map +1 -1
  122. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  123. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  124. package/build/dist/Models/DatabaseModels/Project.js +62 -0
  125. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  126. package/build/dist/Models/DatabaseModels/RumApplication.js +53 -1
  127. package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
  128. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.js +20 -0
  129. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794800000000-AddSessionReplaySameOriginTracePropagation.js.map +1 -0
  130. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.js +42 -0
  131. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794900000000-AddIncidentAlert.js.map +1 -0
  132. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
  133. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  134. package/build/dist/Server/Services/IncidentAlertService.js +1370 -0
  135. package/build/dist/Server/Services/IncidentAlertService.js.map +1 -0
  136. package/build/dist/Server/Services/IncidentService.js +164 -12
  137. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  138. package/build/dist/Server/Services/IncidentStateTimelineService.js +21 -0
  139. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  140. package/build/dist/Server/Services/Index.js +2 -0
  141. package/build/dist/Server/Services/Index.js.map +1 -1
  142. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js +8 -0
  143. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js.map +1 -1
  144. package/build/dist/Types/Incident/IncidentAlertLink.js +34 -0
  145. package/build/dist/Types/Incident/IncidentAlertLink.js.map +1 -0
  146. package/build/dist/Types/Permission.js +42 -0
  147. package/build/dist/Types/Permission.js.map +1 -1
  148. package/build/dist/Types/Rum/WebVitals.js +25 -0
  149. package/build/dist/Types/Rum/WebVitals.js.map +1 -1
  150. package/build/dist/UI/Components/Detail/FieldLabel.js +2 -0
  151. package/build/dist/UI/Components/Detail/FieldLabel.js.map +1 -1
  152. package/build/dist/UI/Components/InfoCard/InfoCard.js +22 -1
  153. package/build/dist/UI/Components/InfoCard/InfoCard.js.map +1 -1
  154. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +66 -14
  155. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  156. package/build/dist/UI/Components/Table/TableHeader.js +18 -2
  157. package/build/dist/UI/Components/Table/TableHeader.js.map +1 -1
  158. package/build/dist/UI/Components/Tooltip/InfoTooltip.js +28 -0
  159. package/build/dist/UI/Components/Tooltip/InfoTooltip.js.map +1 -0
  160. package/build/dist/UI/Utils/PermissionGate.js +4 -2
  161. package/build/dist/UI/Utils/PermissionGate.js.map +1 -1
  162. package/build/dist/Utils/Incident/IncidentFromAlerts.js +306 -0
  163. package/build/dist/Utils/Incident/IncidentFromAlerts.js.map +1 -0
  164. package/build/dist/Utils/Rum/SessionTraceState.js +154 -0
  165. package/build/dist/Utils/Rum/SessionTraceState.js.map +1 -0
  166. package/package.json +1 -1
@@ -41,6 +41,8 @@ export enum AlertFeedEventType {
41
41
  OnCallNotification = "OnCallNotification",
42
42
  AddedToEpisode = "AddedToEpisode",
43
43
  RemovedFromEpisode = "RemovedFromEpisode",
44
+ LinkedToIncident = "LinkedToIncident",
45
+ UnlinkedFromIncident = "UnlinkedFromIncident",
44
46
  LabelRuleExecuted = "LabelRuleExecuted",
45
47
  OwnerRuleExecuted = "OwnerRuleExecuted",
46
48
  PrivacyRuleExecuted = "PrivacyRuleExecuted",
@@ -0,0 +1,540 @@
1
+ import Alert from "./Alert";
2
+ import Incident from "./Incident";
3
+ import Project from "./Project";
4
+ import User from "./User";
5
+ import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
6
+ import Route from "../../Types/API/Route";
7
+ import ColumnAccessControl from "../../Types/Database/AccessControl/ColumnAccessControl";
8
+ import OwnedThrough from "../../Types/Database/AccessControl/OwnedThrough";
9
+ import TableAccessControl from "../../Types/Database/AccessControl/TableAccessControl";
10
+ import CanAccessIfCanReadOn from "../../Types/Database/CanAccessIfCanReadOn";
11
+ import ColumnType from "../../Types/Database/ColumnType";
12
+ import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
13
+ import EnableDocumentation from "../../Types/Database/EnableDocumentation";
14
+ import EnableMCP from "../../Types/Database/EnableMCP";
15
+ import EnableWorkflow from "../../Types/Database/EnableWorkflow";
16
+ import TableColumn from "../../Types/Database/TableColumn";
17
+ import TableColumnType from "../../Types/Database/TableColumnType";
18
+ import TableMetadata from "../../Types/Database/TableMetadata";
19
+ import TenantColumn from "../../Types/Database/TenantColumn";
20
+ import UniqueColumnsTogether from "../../Types/Database/UniqueColumnsTogether";
21
+ import IconProp from "../../Types/Icon/IconProp";
22
+ import { INCIDENT_ALERT_ALREADY_LINKED_MESSAGE } from "../../Types/Incident/IncidentAlertLink";
23
+ import ObjectID from "../../Types/ObjectID";
24
+ import Permission from "../../Types/Permission";
25
+ import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
26
+
27
+ /*
28
+ * Links an alert to an incident (many-to-many): one incident can carry any
29
+ * number of alerts, and one alert can be linked to more than one incident.
30
+ * Linking is how responders say "these alerts are part of this incident" -
31
+ * either by linking alerts to an incident that is already open, or by
32
+ * declaring a new incident from the alerts, which links them as it is created.
33
+ *
34
+ * The link belongs to the incident: its read scope follows the incident's
35
+ * labels (CanAccessIfCanReadOn) and owners (OwnedThrough). Alert roles are
36
+ * listed next to incident roles so a responder who works alerts can see which
37
+ * incidents their alerts are linked to, and link them too when they can also
38
+ * read incidents: the service only creates a link when the caller can read
39
+ * both the alert and the incident.
40
+ *
41
+ * Rows are immutable - a link is created or removed, never edited - so every
42
+ * column has an empty update list. The table keeps its update permissions
43
+ * anyway so generated clients (Terraform) treat both ids as replace-on-change
44
+ * instead of silently ignoring an edit.
45
+ */
46
+ @EnableDocumentation()
47
+ @EnableMCP()
48
+ @CanAccessIfCanReadOn("incident")
49
+ @TenantColumn("projectId")
50
+ @TableAccessControl({
51
+ create: [
52
+ Permission.ProjectOwner,
53
+ Permission.ProjectAdmin,
54
+ Permission.ProjectMember,
55
+ Permission.IncidentAdmin,
56
+ Permission.IncidentMember,
57
+ Permission.AlertAdmin,
58
+ Permission.AlertMember,
59
+ Permission.CreateIncidentAlert,
60
+ ],
61
+ read: [
62
+ Permission.ProjectOwner,
63
+ Permission.ProjectAdmin,
64
+ Permission.ProjectMember,
65
+ Permission.Viewer,
66
+ Permission.IncidentAdmin,
67
+ Permission.IncidentMember,
68
+ Permission.IncidentViewer,
69
+ Permission.AlertAdmin,
70
+ Permission.AlertMember,
71
+ Permission.AlertViewer,
72
+ Permission.ReadIncidentAlert,
73
+ ],
74
+ delete: [
75
+ Permission.ProjectOwner,
76
+ Permission.ProjectAdmin,
77
+ Permission.ProjectMember,
78
+ Permission.IncidentAdmin,
79
+ Permission.IncidentMember,
80
+ Permission.AlertAdmin,
81
+ Permission.AlertMember,
82
+ Permission.DeleteIncidentAlert,
83
+ ],
84
+ update: [
85
+ Permission.ProjectOwner,
86
+ Permission.ProjectAdmin,
87
+ Permission.ProjectMember,
88
+ Permission.IncidentAdmin,
89
+ Permission.IncidentMember,
90
+ Permission.AlertAdmin,
91
+ Permission.AlertMember,
92
+ Permission.EditIncidentAlert,
93
+ ],
94
+ })
95
+ @EnableWorkflow({
96
+ create: true,
97
+ delete: true,
98
+ update: true,
99
+ read: true,
100
+ })
101
+ @CrudApiEndpoint(new Route("/incident-alert"))
102
+ @TableMetadata({
103
+ tableName: "IncidentAlert",
104
+ singularName: "Incident Alert",
105
+ pluralName: "Incident Alerts",
106
+ icon: IconProp.Link,
107
+ tableDescription:
108
+ "Alerts linked to an incident. Link alerts to an incident to track them as part of that incident's response.",
109
+ })
110
+ @OwnedThrough("incidentId", Incident)
111
+ @Entity({
112
+ name: "IncidentAlert",
113
+ })
114
+ @Index(["incidentId", "alertId", "projectId"], { unique: true })
115
+ @UniqueColumnsTogether(
116
+ ["incidentId", "alertId", "projectId"],
117
+ INCIDENT_ALERT_ALREADY_LINKED_MESSAGE,
118
+ )
119
+ export default class IncidentAlert extends BaseModel {
120
+ @ColumnAccessControl({
121
+ create: [
122
+ Permission.ProjectOwner,
123
+ Permission.ProjectAdmin,
124
+ Permission.ProjectMember,
125
+ Permission.IncidentAdmin,
126
+ Permission.IncidentMember,
127
+ Permission.AlertAdmin,
128
+ Permission.AlertMember,
129
+ Permission.CreateIncidentAlert,
130
+ ],
131
+ read: [
132
+ Permission.ProjectOwner,
133
+ Permission.ProjectAdmin,
134
+ Permission.ProjectMember,
135
+ Permission.Viewer,
136
+ Permission.IncidentAdmin,
137
+ Permission.IncidentMember,
138
+ Permission.IncidentViewer,
139
+ Permission.AlertAdmin,
140
+ Permission.AlertMember,
141
+ Permission.AlertViewer,
142
+ Permission.ReadIncidentAlert,
143
+ ],
144
+ update: [],
145
+ })
146
+ @TableColumn({
147
+ manyToOneRelationColumn: "projectId",
148
+ type: TableColumnType.Entity,
149
+ modelType: Project,
150
+ title: "Project",
151
+ description: "Relation to Project Resource in which this object belongs",
152
+ })
153
+ @ManyToOne(
154
+ () => {
155
+ return Project;
156
+ },
157
+ {
158
+ eager: false,
159
+ nullable: false,
160
+ onDelete: "CASCADE",
161
+ orphanedRowAction: "nullify",
162
+ },
163
+ )
164
+ @JoinColumn({ name: "projectId" })
165
+ public project?: Project = undefined;
166
+
167
+ @ColumnAccessControl({
168
+ create: [
169
+ Permission.ProjectOwner,
170
+ Permission.ProjectAdmin,
171
+ Permission.ProjectMember,
172
+ Permission.IncidentAdmin,
173
+ Permission.IncidentMember,
174
+ Permission.AlertAdmin,
175
+ Permission.AlertMember,
176
+ Permission.CreateIncidentAlert,
177
+ ],
178
+ read: [
179
+ Permission.ProjectOwner,
180
+ Permission.ProjectAdmin,
181
+ Permission.ProjectMember,
182
+ Permission.Viewer,
183
+ Permission.IncidentAdmin,
184
+ Permission.IncidentMember,
185
+ Permission.IncidentViewer,
186
+ Permission.AlertAdmin,
187
+ Permission.AlertMember,
188
+ Permission.AlertViewer,
189
+ Permission.ReadIncidentAlert,
190
+ ],
191
+ update: [],
192
+ })
193
+ @Index()
194
+ @TableColumn({
195
+ type: TableColumnType.ObjectID,
196
+ required: true,
197
+ canReadOnRelationQuery: true,
198
+ title: "Project ID",
199
+ description: "ID of your OneUptime Project in which this object belongs",
200
+ })
201
+ @Column({
202
+ type: ColumnType.ObjectID,
203
+ nullable: false,
204
+ transformer: ObjectID.getDatabaseTransformer(),
205
+ })
206
+ public projectId?: ObjectID = undefined;
207
+
208
+ @ColumnAccessControl({
209
+ create: [
210
+ Permission.ProjectOwner,
211
+ Permission.ProjectAdmin,
212
+ Permission.ProjectMember,
213
+ Permission.IncidentAdmin,
214
+ Permission.IncidentMember,
215
+ Permission.AlertAdmin,
216
+ Permission.AlertMember,
217
+ Permission.CreateIncidentAlert,
218
+ ],
219
+ read: [
220
+ Permission.ProjectOwner,
221
+ Permission.ProjectAdmin,
222
+ Permission.ProjectMember,
223
+ Permission.Viewer,
224
+ Permission.IncidentAdmin,
225
+ Permission.IncidentMember,
226
+ Permission.IncidentViewer,
227
+ Permission.AlertAdmin,
228
+ Permission.AlertMember,
229
+ Permission.AlertViewer,
230
+ Permission.ReadIncidentAlert,
231
+ ],
232
+ update: [],
233
+ })
234
+ @TableColumn({
235
+ manyToOneRelationColumn: "incidentId",
236
+ type: TableColumnType.Entity,
237
+ modelType: Incident,
238
+ title: "Incident",
239
+ description: "Relation to the Incident this alert is linked to",
240
+ })
241
+ @ManyToOne(
242
+ () => {
243
+ return Incident;
244
+ },
245
+ {
246
+ eager: false,
247
+ nullable: false,
248
+ onDelete: "CASCADE",
249
+ orphanedRowAction: "nullify",
250
+ },
251
+ )
252
+ @JoinColumn({ name: "incidentId" })
253
+ public incident?: Incident = undefined;
254
+
255
+ @ColumnAccessControl({
256
+ create: [
257
+ Permission.ProjectOwner,
258
+ Permission.ProjectAdmin,
259
+ Permission.ProjectMember,
260
+ Permission.IncidentAdmin,
261
+ Permission.IncidentMember,
262
+ Permission.AlertAdmin,
263
+ Permission.AlertMember,
264
+ Permission.CreateIncidentAlert,
265
+ ],
266
+ read: [
267
+ Permission.ProjectOwner,
268
+ Permission.ProjectAdmin,
269
+ Permission.ProjectMember,
270
+ Permission.Viewer,
271
+ Permission.IncidentAdmin,
272
+ Permission.IncidentMember,
273
+ Permission.IncidentViewer,
274
+ Permission.AlertAdmin,
275
+ Permission.AlertMember,
276
+ Permission.AlertViewer,
277
+ Permission.ReadIncidentAlert,
278
+ ],
279
+ update: [],
280
+ })
281
+ @Index()
282
+ @TableColumn({
283
+ type: TableColumnType.ObjectID,
284
+ required: true,
285
+ canReadOnRelationQuery: true,
286
+ title: "Incident ID",
287
+ description: "ID of the Incident this alert is linked to",
288
+ })
289
+ @Column({
290
+ type: ColumnType.ObjectID,
291
+ nullable: false,
292
+ transformer: ObjectID.getDatabaseTransformer(),
293
+ })
294
+ public incidentId?: ObjectID = undefined;
295
+
296
+ @ColumnAccessControl({
297
+ create: [
298
+ Permission.ProjectOwner,
299
+ Permission.ProjectAdmin,
300
+ Permission.ProjectMember,
301
+ Permission.IncidentAdmin,
302
+ Permission.IncidentMember,
303
+ Permission.AlertAdmin,
304
+ Permission.AlertMember,
305
+ Permission.CreateIncidentAlert,
306
+ ],
307
+ read: [
308
+ Permission.ProjectOwner,
309
+ Permission.ProjectAdmin,
310
+ Permission.ProjectMember,
311
+ Permission.Viewer,
312
+ Permission.IncidentAdmin,
313
+ Permission.IncidentMember,
314
+ Permission.IncidentViewer,
315
+ Permission.AlertAdmin,
316
+ Permission.AlertMember,
317
+ Permission.AlertViewer,
318
+ Permission.ReadIncidentAlert,
319
+ ],
320
+ update: [],
321
+ })
322
+ @TableColumn({
323
+ manyToOneRelationColumn: "alertId",
324
+ type: TableColumnType.Entity,
325
+ modelType: Alert,
326
+ title: "Alert",
327
+ description: "Relation to the Alert that is linked to the incident",
328
+ })
329
+ @ManyToOne(
330
+ () => {
331
+ return Alert;
332
+ },
333
+ {
334
+ eager: false,
335
+ nullable: false,
336
+ onDelete: "CASCADE",
337
+ orphanedRowAction: "nullify",
338
+ },
339
+ )
340
+ @JoinColumn({ name: "alertId" })
341
+ public alert?: Alert = undefined;
342
+
343
+ @ColumnAccessControl({
344
+ create: [
345
+ Permission.ProjectOwner,
346
+ Permission.ProjectAdmin,
347
+ Permission.ProjectMember,
348
+ Permission.IncidentAdmin,
349
+ Permission.IncidentMember,
350
+ Permission.AlertAdmin,
351
+ Permission.AlertMember,
352
+ Permission.CreateIncidentAlert,
353
+ ],
354
+ read: [
355
+ Permission.ProjectOwner,
356
+ Permission.ProjectAdmin,
357
+ Permission.ProjectMember,
358
+ Permission.Viewer,
359
+ Permission.IncidentAdmin,
360
+ Permission.IncidentMember,
361
+ Permission.IncidentViewer,
362
+ Permission.AlertAdmin,
363
+ Permission.AlertMember,
364
+ Permission.AlertViewer,
365
+ Permission.ReadIncidentAlert,
366
+ ],
367
+ update: [],
368
+ })
369
+ @Index()
370
+ @TableColumn({
371
+ type: TableColumnType.ObjectID,
372
+ required: true,
373
+ canReadOnRelationQuery: true,
374
+ title: "Alert ID",
375
+ description: "ID of the Alert that is linked to the incident",
376
+ })
377
+ @Column({
378
+ type: ColumnType.ObjectID,
379
+ nullable: false,
380
+ transformer: ObjectID.getDatabaseTransformer(),
381
+ })
382
+ public alertId?: ObjectID = undefined;
383
+
384
+ @ColumnAccessControl({
385
+ create: [
386
+ Permission.ProjectOwner,
387
+ Permission.ProjectAdmin,
388
+ Permission.ProjectMember,
389
+ Permission.IncidentAdmin,
390
+ Permission.IncidentMember,
391
+ Permission.AlertAdmin,
392
+ Permission.AlertMember,
393
+ Permission.CreateIncidentAlert,
394
+ ],
395
+ read: [
396
+ Permission.ProjectOwner,
397
+ Permission.ProjectAdmin,
398
+ Permission.ProjectMember,
399
+ Permission.Viewer,
400
+ Permission.IncidentAdmin,
401
+ Permission.IncidentMember,
402
+ Permission.IncidentViewer,
403
+ Permission.AlertAdmin,
404
+ Permission.AlertMember,
405
+ Permission.AlertViewer,
406
+ Permission.ReadIncidentAlert,
407
+ ],
408
+ update: [],
409
+ })
410
+ @TableColumn({
411
+ manyToOneRelationColumn: "createdByUserId",
412
+ type: TableColumnType.Entity,
413
+ modelType: User,
414
+ title: "Linked by User",
415
+ description:
416
+ "Relation to User who linked the alert to the incident (if it was linked by a User)",
417
+ })
418
+ @ManyToOne(
419
+ () => {
420
+ return User;
421
+ },
422
+ {
423
+ eager: false,
424
+ nullable: true,
425
+ onDelete: "SET NULL",
426
+ orphanedRowAction: "nullify",
427
+ },
428
+ )
429
+ @JoinColumn({ name: "createdByUserId" })
430
+ public createdByUser?: User = undefined;
431
+
432
+ @ColumnAccessControl({
433
+ create: [
434
+ Permission.ProjectOwner,
435
+ Permission.ProjectAdmin,
436
+ Permission.ProjectMember,
437
+ Permission.IncidentAdmin,
438
+ Permission.IncidentMember,
439
+ Permission.AlertAdmin,
440
+ Permission.AlertMember,
441
+ Permission.CreateIncidentAlert,
442
+ ],
443
+ read: [
444
+ Permission.ProjectOwner,
445
+ Permission.ProjectAdmin,
446
+ Permission.ProjectMember,
447
+ Permission.Viewer,
448
+ Permission.IncidentAdmin,
449
+ Permission.IncidentMember,
450
+ Permission.IncidentViewer,
451
+ Permission.AlertAdmin,
452
+ Permission.AlertMember,
453
+ Permission.AlertViewer,
454
+ Permission.ReadIncidentAlert,
455
+ ],
456
+ update: [],
457
+ })
458
+ @TableColumn({
459
+ type: TableColumnType.ObjectID,
460
+ title: "Linked by User ID",
461
+ description:
462
+ "ID of the User who linked the alert to the incident (if it was linked by a User)",
463
+ })
464
+ @Column({
465
+ type: ColumnType.ObjectID,
466
+ nullable: true,
467
+ transformer: ObjectID.getDatabaseTransformer(),
468
+ })
469
+ public createdByUserId?: ObjectID = undefined;
470
+
471
+ @ColumnAccessControl({
472
+ create: [],
473
+ read: [
474
+ Permission.ProjectOwner,
475
+ Permission.ProjectAdmin,
476
+ Permission.ProjectMember,
477
+ Permission.Viewer,
478
+ Permission.IncidentAdmin,
479
+ Permission.IncidentMember,
480
+ Permission.IncidentViewer,
481
+ Permission.AlertAdmin,
482
+ Permission.AlertMember,
483
+ Permission.AlertViewer,
484
+ Permission.ReadIncidentAlert,
485
+ ],
486
+ update: [],
487
+ })
488
+ @TableColumn({
489
+ manyToOneRelationColumn: "deletedByUserId",
490
+ type: TableColumnType.Entity,
491
+ modelType: User,
492
+ title: "Deleted by User",
493
+ description:
494
+ "Relation to User who deleted this object (if this object was deleted by a User)",
495
+ })
496
+ @ManyToOne(
497
+ () => {
498
+ return User;
499
+ },
500
+ {
501
+ cascade: false,
502
+ eager: false,
503
+ nullable: true,
504
+ onDelete: "SET NULL",
505
+ orphanedRowAction: "nullify",
506
+ },
507
+ )
508
+ @JoinColumn({ name: "deletedByUserId" })
509
+ public deletedByUser?: User = undefined;
510
+
511
+ @ColumnAccessControl({
512
+ create: [],
513
+ read: [
514
+ Permission.ProjectOwner,
515
+ Permission.ProjectAdmin,
516
+ Permission.ProjectMember,
517
+ Permission.Viewer,
518
+ Permission.IncidentAdmin,
519
+ Permission.IncidentMember,
520
+ Permission.IncidentViewer,
521
+ Permission.AlertAdmin,
522
+ Permission.AlertMember,
523
+ Permission.AlertViewer,
524
+ Permission.ReadIncidentAlert,
525
+ ],
526
+ update: [],
527
+ })
528
+ @TableColumn({
529
+ type: TableColumnType.ObjectID,
530
+ title: "Deleted by User ID",
531
+ description:
532
+ "User ID who deleted this object (if this object was deleted by a User)",
533
+ })
534
+ @Column({
535
+ type: ColumnType.ObjectID,
536
+ nullable: true,
537
+ transformer: ObjectID.getDatabaseTransformer(),
538
+ })
539
+ public deletedByUserId?: ObjectID = undefined;
540
+ }
@@ -41,6 +41,8 @@ export enum IncidentFeedEventType {
41
41
  OnCallNotification = "OnCallNotification",
42
42
  IncidentMemberAdded = "IncidentMemberAdded",
43
43
  IncidentMemberRemoved = "IncidentMemberRemoved",
44
+ AlertLinked = "AlertLinked",
45
+ AlertUnlinked = "AlertUnlinked",
44
46
  LabelRuleExecuted = "LabelRuleExecuted",
45
47
  OwnerRuleExecuted = "OwnerRuleExecuted",
46
48
  PrivacyRuleExecuted = "PrivacyRuleExecuted",
@@ -376,6 +376,7 @@ import AlertEpisodeLabelRule from "./AlertEpisodeLabelRule";
376
376
 
377
377
  import IncidentEpisode from "./IncidentEpisode";
378
378
  import IncidentEpisodeMember from "./IncidentEpisodeMember";
379
+ import IncidentAlert from "./IncidentAlert";
379
380
  import IncidentEpisodeRoleMember from "./IncidentEpisodeRoleMember";
380
381
  import IncidentEpisodeStateTimeline from "./IncidentEpisodeStateTimeline";
381
382
  import IncidentEpisodeOwnerUser from "./IncidentEpisodeOwnerUser";
@@ -592,6 +593,7 @@ const AllModelTypes: Array<{
592
593
 
593
594
  IncidentEpisode,
594
595
  IncidentEpisodeMember,
596
+ IncidentAlert,
595
597
  IncidentEpisodeRoleMember,
596
598
  IncidentEpisodeStateTimeline,
597
599
  IncidentEpisodeOwnerUser,
@@ -1653,6 +1653,66 @@ export default class Project extends TenantModel {
1653
1653
  })
1654
1654
  public enableAutomaticAlertInvestigation?: boolean = undefined;
1655
1655
 
1656
+ @ColumnAccessControl({
1657
+ create: [],
1658
+ read: [
1659
+ Permission.ProjectOwner,
1660
+ Permission.ProjectAdmin,
1661
+ Permission.ProjectMember,
1662
+ Permission.Viewer,
1663
+ Permission.ReadProject,
1664
+ Permission.UnAuthorizedSsoUser,
1665
+ Permission.ProjectUser,
1666
+ ],
1667
+ update: [Permission.ProjectOwner, Permission.ProjectAdmin],
1668
+ })
1669
+ @TableColumn({
1670
+ required: true,
1671
+ isDefaultValueColumn: true,
1672
+ type: TableColumnType.Boolean,
1673
+ title: "Acknowledge Linked Alerts When Incident Is Acknowledged",
1674
+ description:
1675
+ "When enabled, acknowledging an incident also acknowledges every alert linked to it. This stops those alerts' on-call escalations, and their reminders only when the alert reminder rule is set to stop on Acknowledged. Alerts linked to an incident that is already acknowledged are acknowledged as they are linked.",
1676
+ defaultValue: false,
1677
+ example: true,
1678
+ })
1679
+ @Column({
1680
+ nullable: false,
1681
+ default: false,
1682
+ type: ColumnType.Boolean,
1683
+ })
1684
+ public acknowledgeLinkedAlertsWhenIncidentAcknowledged?: boolean = undefined;
1685
+
1686
+ @ColumnAccessControl({
1687
+ create: [],
1688
+ read: [
1689
+ Permission.ProjectOwner,
1690
+ Permission.ProjectAdmin,
1691
+ Permission.ProjectMember,
1692
+ Permission.Viewer,
1693
+ Permission.ReadProject,
1694
+ Permission.UnAuthorizedSsoUser,
1695
+ Permission.ProjectUser,
1696
+ ],
1697
+ update: [Permission.ProjectOwner, Permission.ProjectAdmin],
1698
+ })
1699
+ @TableColumn({
1700
+ required: true,
1701
+ isDefaultValueColumn: true,
1702
+ type: TableColumnType.Boolean,
1703
+ title: "Resolve Linked Alerts When Incident Is Resolved",
1704
+ description:
1705
+ "When enabled, resolving an incident also resolves every alert linked to it, except alerts that are still linked to another incident that is not resolved yet. Alerts linked to an incident that is already resolved are resolved as they are linked.",
1706
+ defaultValue: false,
1707
+ example: true,
1708
+ })
1709
+ @Column({
1710
+ nullable: false,
1711
+ default: false,
1712
+ type: ColumnType.Boolean,
1713
+ })
1714
+ public resolveLinkedAlertsWhenIncidentResolved?: boolean = undefined;
1715
+
1656
1716
  @ColumnAccessControl({
1657
1717
  create: [],
1658
1718
  read: [
@@ -915,7 +915,7 @@ export default class RumApplication extends BaseModel {
915
915
  type: TableColumnType.JSON,
916
916
  title: "Session Replay Trace Propagation Origins",
917
917
  description:
918
- "Origins the recorder may inject a W3C traceparent header into, linking recordings to the backend traces of their requests without any OpenTelemetry browser setup. Empty means never inject: adding a header makes cross-origin requests preflighted, so each listed origin is an explicit statement that its API allows the traceparent header.",
918
+ "APIs on OTHER origins than the page (for example https://api.example.com) that the recorder may inject a W3C traceparent header into, linking recordings to the backend traces of their requests without any OpenTelemetry browser setup. Requests to the page's own origin need no entry here: Same-origin trace propagation covers them. Empty (the default) injects nothing cross-origin: adding a header makes a cross-origin request preflighted, so each listed origin is an explicit statement that its API allows traceparent in Access-Control-Allow-Headers. Listed origins get traceparent only, never the session id.",
919
919
  })
920
920
  @Column({
921
921
  type: ColumnType.JSON,
@@ -926,6 +926,57 @@ export default class RumApplication extends BaseModel {
926
926
  })
927
927
  public sessionReplayTracePropagationOrigins?: Array<string> = undefined;
928
928
 
929
+ /*
930
+ * On for existing applications as well as new ones: the column is added
931
+ * with DEFAULT true, and the recorder and its config are served no-store,
932
+ * so every installed recorder starts linking on its next page load. This
933
+ * switch is the way back that needs no redeploy on the customer's side.
934
+ *
935
+ * Same narrower create/update ACL as sessionReplayCaptureUserIdentity:
936
+ * linking a recording to backend telemetry that names the user identifies
937
+ * it, and the tracestate member carries the session id past the
938
+ * customer's backend to every service it calls.
939
+ */
940
+ @ColumnAccessControl({
941
+ create: [
942
+ Permission.ProjectOwner,
943
+ Permission.ProjectAdmin,
944
+ Permission.SettingsAdmin,
945
+ Permission.CreateRumApplication,
946
+ ],
947
+ read: [
948
+ Permission.ProjectOwner,
949
+ Permission.ProjectAdmin,
950
+ Permission.ProjectMember,
951
+ Permission.Viewer,
952
+ Permission.SettingsAdmin,
953
+ Permission.SettingsMember,
954
+ Permission.SettingsViewer,
955
+ Permission.ReadRumApplication,
956
+ ],
957
+ update: [
958
+ Permission.ProjectOwner,
959
+ Permission.ProjectAdmin,
960
+ Permission.SettingsAdmin,
961
+ Permission.EditRumApplication,
962
+ ],
963
+ })
964
+ @TableColumn({
965
+ isDefaultValueColumn: true,
966
+ required: true,
967
+ type: TableColumnType.Boolean,
968
+ title: "Same-origin trace propagation",
969
+ description:
970
+ "When enabled, the recorder adds a W3C traceparent and a tracestate member carrying the replay session id (oneuptime=sid:<session id>) to the fetch and XHR requests the page makes to its own origin while a session is uploading, so the backend spans, logs and exceptions those requests cause link to the recording automatically, with no code in your frontend or backend. Nothing is added before consent, after consent is revoked, or before an on-error trigger fires, and a request that already carries a traceparent or tracestate keeps its own. A traceparent the recorder generates is marked sampled, so ParentBased samplers in your backend keep every browser-originated trace (to keep ratio sampling, set a remoteParentSampled ratio delegate only on the service(s) your pages call directly, never on the services they call: ratio decisions differ between language SDKs; for one rate across services, use tail sampling in an OpenTelemetry Collector). Your backend's OpenTelemetry forwards the tracestate, and with it the session id, to every service it calls, third parties included; the visitor id is never sent. On by default. Narrower create/update ACL than the other replay settings: it links recordings to backend telemetry that may name the user.",
971
+ defaultValue: true,
972
+ })
973
+ @Column({
974
+ type: ColumnType.Boolean,
975
+ nullable: false,
976
+ default: true,
977
+ })
978
+ public sessionReplaySameOriginTracePropagation?: boolean = undefined;
979
+
929
980
  @ColumnAccessControl({
930
981
  create: [
931
982
  Permission.ProjectOwner,