@oneuptime/common 11.7.3 → 11.7.4

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 (365) hide show
  1. package/Models/DatabaseModels/AlertEpisodeStateTimeline.ts +1 -0
  2. package/Models/DatabaseModels/AlertStateTimeline.ts +1 -0
  3. package/Models/DatabaseModels/IncidentEpisodeStateTimeline.ts +1 -0
  4. package/Models/DatabaseModels/IncidentStateTimeline.ts +1 -0
  5. package/Models/DatabaseModels/Index.ts +5 -0
  6. package/Models/DatabaseModels/LogDropFilter.ts +89 -0
  7. package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +13 -3
  8. package/Models/DatabaseModels/RecommendationDismissal.ts +463 -0
  9. package/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.ts +1 -0
  10. package/Models/DatabaseModels/StatusPageGroup.ts +95 -0
  11. package/Models/DatabaseModels/TraceDropFilter.ts +89 -0
  12. package/Models/DatabaseModels/WorkflowVariable.ts +5 -1
  13. package/Server/API/AlertAPI.ts +32 -17
  14. package/Server/API/BaseAPI.ts +31 -2
  15. package/Server/API/BaseAnalyticsAPI.ts +36 -2
  16. package/Server/API/CommonAPI.ts +57 -0
  17. package/Server/API/IncidentAPI.ts +60 -33
  18. package/Server/API/IncidentEpisodeAPI.ts +31 -16
  19. package/Server/API/MonitorAPI.ts +30 -0
  20. package/Server/API/MonitorTemplateAPI.ts +8 -0
  21. package/Server/API/ProbeAPI.ts +196 -15
  22. package/Server/API/ProjectAPI.ts +79 -1
  23. package/Server/API/ScheduledMaintenanceAPI.ts +33 -18
  24. package/Server/API/StatusPageAPI.ts +74 -37
  25. package/Server/API/WorkspaceNotificationRuleAPI.ts +34 -4
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/1785320000000-RepairCrossProjectIncidentReferences.ts +527 -0
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/1785329453269-AddParentGroupToStatusPageGroup.ts +31 -0
  28. package/Server/Infrastructure/Postgres/SchemaMigrations/1785397674289-AddRecommendationDismissalTable.ts +55 -0
  29. package/Server/Infrastructure/Postgres/SchemaMigrations/1785405581596-AddDroppedCountersToDropFilters.ts +53 -0
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
  31. package/Server/Services/AlertEpisodeService.ts +47 -0
  32. package/Server/Services/AlertService.ts +125 -0
  33. package/Server/Services/BillingService.ts +98 -0
  34. package/Server/Services/DatabaseService.ts +184 -20
  35. package/Server/Services/IncidentEpisodeService.ts +47 -0
  36. package/Server/Services/IncidentService.ts +123 -0
  37. package/Server/Services/IncidentTemplateService.ts +123 -1
  38. package/Server/Services/Index.ts +2 -0
  39. package/Server/Services/LogDropFilterService.ts +133 -0
  40. package/Server/Services/MonitorProbeService.ts +94 -4
  41. package/Server/Services/MonitorService.ts +48 -43
  42. package/Server/Services/NetworkDeviceDiscoveryScanService.ts +70 -0
  43. package/Server/Services/ProbeService.ts +66 -0
  44. package/Server/Services/ProjectService.ts +131 -7
  45. package/Server/Services/RecommendationDismissalService.ts +52 -0
  46. package/Server/Services/RunbookAgentJobService.ts +68 -7
  47. package/Server/Services/ScheduledMaintenanceService.ts +103 -0
  48. package/Server/Services/ScheduledMaintenanceTemplateService.ts +90 -0
  49. package/Server/Services/StatusPageGroupService.ts +186 -0
  50. package/Server/Services/TraceDropFilterService.ts +133 -0
  51. package/Server/Types/Workflow/Components/API/Delete.ts +12 -0
  52. package/Server/Types/Workflow/Components/API/Get.ts +12 -0
  53. package/Server/Types/Workflow/Components/API/Patch.ts +12 -0
  54. package/Server/Types/Workflow/Components/API/Post.ts +12 -0
  55. package/Server/Types/Workflow/Components/API/Put.ts +13 -0
  56. package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +212 -0
  57. package/Server/Utils/DropFilterValidation.ts +127 -0
  58. package/Server/Utils/Errors.ts +5 -0
  59. package/Server/Utils/Monitor/MonitorAlert.ts +28 -1
  60. package/Server/Utils/Monitor/MonitorIncident.ts +31 -2
  61. package/Server/Utils/Telemetry/AppMetrics.ts +31 -0
  62. package/Tests/Models/DatabaseModels/MonitorProbeColumnAccessControl.test.ts +196 -0
  63. package/Tests/Models/RecommendationDismissalModel.test.ts +269 -0
  64. package/Tests/Server/API/BaseAPIUpdatePayloadValidation.test.ts +320 -0
  65. package/Tests/Server/API/BaseAnalyticsAPIUpdatePayloadValidation.test.ts +293 -0
  66. package/Tests/Server/API/CommonAPIAuthGuard.test.ts +164 -0
  67. package/Tests/Server/API/ProbeAPI.test.ts +422 -53
  68. package/Tests/Server/API/ProjectAPI.test.ts +180 -0
  69. package/Tests/Server/API/ProjectAPIExtendTrialBillingDisabled.test.ts +138 -0
  70. package/Tests/Server/API/ProjectScopedCustomRouteAuth.test.ts +458 -0
  71. package/Tests/Server/Infrastructure/ContainerBootConfiguration.test.ts +359 -0
  72. package/Tests/Server/Infrastructure/ProcessSignalDelivery.test.ts +427 -0
  73. package/Tests/Server/Services/BillingServiceExtendTrial.test.ts +439 -0
  74. package/Tests/Server/Services/CrossProjectReferenceWriteGuard.test.ts +810 -0
  75. package/Tests/Server/Services/DatabaseServiceAtomicAddToColumns.test.ts +269 -0
  76. package/Tests/Server/Services/DatabaseServiceEmptyUpdate.test.ts +277 -0
  77. package/Tests/Server/Services/DatabaseServiceSortColumnSelect.test.ts +201 -0
  78. package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +81 -23
  79. package/Tests/Server/Services/DropFilterSaveValidation.test.ts +398 -0
  80. package/Tests/Server/Services/MonitorProbeDeleteHooks.test.ts +280 -0
  81. package/Tests/Server/Services/MonitorProbeServiceProbeTenancy.test.ts +304 -0
  82. package/Tests/Server/Services/NetworkDeviceDiscoveryScanService.test.ts +262 -0
  83. package/Tests/Server/Services/ProjectServiceExtendTrial.test.ts +614 -0
  84. package/Tests/Server/Services/RecommendationDismissalService.test.ts +306 -0
  85. package/Tests/Server/Services/RepairCrossProjectIncidentReferencesMigration.test.ts +528 -0
  86. package/Tests/Server/Services/StatusPageGroupNesting.test.ts +395 -0
  87. package/Tests/Server/TestingUtils/Services/BillingServiceHelper.ts +26 -21
  88. package/Tests/Server/Types/Database/Permissions/WorkflowVariableColumnPermission.test.ts +227 -0
  89. package/Tests/Server/Types/Workflow/Components/ApiComponentErrorPort.test.ts +285 -0
  90. package/Tests/Server/Utils/Database/ProjectScopedReferenceValidator.test.ts +463 -0
  91. package/Tests/Server/Utils/DropFilterValidation.test.ts +269 -0
  92. package/Tests/Server/Utils/Telemetry/SpanUtil.test.ts +94 -0
  93. package/Tests/Types/DateUserTimezone.test.ts +52 -0
  94. package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +177 -9
  95. package/Tests/Types/Monitor/MonitorStepDnsMonitor.test.ts +105 -0
  96. package/Tests/Types/Monitor/MonitorStepDnssecMonitor.test.ts +131 -0
  97. package/Tests/Types/Monitor/MonitorStepDomainMonitor.test.ts +60 -0
  98. package/Tests/Types/Monitor/MonitorStepExternalStatusPageMonitor.test.ts +82 -0
  99. package/Tests/Types/Monitor/MonitorStepInfrastructureMonitors.test.ts +268 -0
  100. package/Tests/Types/Monitor/MonitorStepMetricMonitor.test.ts +386 -0
  101. package/Tests/Types/Monitor/MonitorStepProfileMonitor.test.ts +185 -0
  102. package/Tests/Types/Monitor/MonitorStepSnmpMonitor.test.ts +156 -0
  103. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +371 -0
  104. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +901 -0
  105. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +607 -0
  106. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.test.ts +754 -0
  107. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +960 -0
  108. package/Tests/Types/RollingTime/RollingTimeUtil.test.ts +186 -0
  109. package/Tests/Types/Runbook/RunbookStepTimeout.test.ts +410 -0
  110. package/Tests/Types/Telemetry/DropFilterSampling.test.ts +241 -0
  111. package/Tests/Types/Workspace/NotificationRuleConditionUtil.test.ts +353 -0
  112. package/Tests/Types/Workspace/NotificationRuleUtil.test.ts +566 -0
  113. package/Tests/UI/Components/CodeEditor.test.tsx +174 -0
  114. package/Tests/UI/Components/ErrorBoundary.test.tsx +555 -24
  115. package/Tests/UI/Components/InfoCard.test.tsx +358 -0
  116. package/Tests/UI/Components/LogTimeRangePicker.test.tsx +138 -0
  117. package/Tests/UI/Components/Modal.test.tsx +43 -5
  118. package/Tests/UI/Components/ModelTable/BaseModelTableSearchLabels.test.tsx +397 -0
  119. package/Tests/UI/Components/ModelTable/ColumnCustomizationModal.test.tsx +427 -0
  120. package/Tests/UI/Components/Runbook/StepTimeoutInput.test.tsx +386 -0
  121. package/Tests/UI/Components/StatusPage/ResourceGroupSection.test.tsx +671 -0
  122. package/Tests/UI/Components/TelemetryTimeRangePicker.test.tsx +404 -0
  123. package/Tests/UI/Utils/DropdownAlignment.test.ts +306 -0
  124. package/Tests/UI/Utils/TableFilterUrlState.test.ts +292 -0
  125. package/Tests/Utils/Monitor/MonitorSummaryProbeUtil.test.ts +263 -0
  126. package/Tests/Utils/NetworkDiscovery/ScanTargetUtil.test.ts +583 -0
  127. package/Tests/Utils/StatusPage/GroupNestingLayout.test.ts +1072 -0
  128. package/Tests/Utils/StatusPage/GroupTree.test.ts +583 -0
  129. package/Tests/Utils/StatusPage/ResourceUptime.test.ts +411 -0
  130. package/Types/Date.ts +15 -6
  131. package/Types/Monitor/KubernetesAlertTemplates.ts +205 -0
  132. package/Types/Monitor/MonitorStep.ts +10 -1
  133. package/Types/Monitor/MonitorStepMetricMonitor.ts +46 -1
  134. package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +413 -0
  135. package/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.ts +168 -0
  136. package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +175 -0
  137. package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +743 -0
  138. package/Types/Permission.ts +45 -0
  139. package/Types/Recommendation/RecommendationType.ts +20 -0
  140. package/Types/Runbook/RunbookExecutionDeadline.ts +129 -0
  141. package/Types/Runbook/RunbookStepTimeout.ts +202 -0
  142. package/Types/Telemetry/DropFilterSampling.ts +92 -0
  143. package/UI/Components/AI/GenerateFromAIModal.tsx +0 -2
  144. package/UI/Components/Accordion/Accordion.tsx +10 -2
  145. package/UI/Components/BulkUpdate/BulkLabelActions.tsx +0 -1
  146. package/UI/Components/CodeEditor/CodeEditor.tsx +34 -20
  147. package/UI/Components/Date/RangeStartAndEndDateView.tsx +0 -1
  148. package/UI/Components/EditionLabel/EditionLabel.tsx +1 -27
  149. package/UI/Components/Error/PageError.tsx +0 -4
  150. package/UI/Components/ErrorBoundary.tsx +252 -15
  151. package/UI/Components/InfoCard/InfoCard.tsx +58 -1
  152. package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +34 -1
  153. package/UI/Components/Modal/Modal.tsx +16 -60
  154. package/UI/Components/ModelFormModal/ModelFormModal.tsx +0 -8
  155. package/UI/Components/ModelTable/BaseModelTable.tsx +116 -67
  156. package/UI/Components/ModelTable/ColumnCustomizationModal.tsx +150 -47
  157. package/UI/Components/Runbook/StepTimeoutInput.tsx +173 -0
  158. package/UI/Components/StatusPage/ResourceGroupSection.tsx +231 -0
  159. package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +34 -1
  160. package/UI/Utils/DropdownAlignment.ts +162 -0
  161. package/UI/Utils/TableFilterUrlState.ts +59 -20
  162. package/Utils/API.ts +106 -2
  163. package/Utils/Monitor/MonitorSummaryProbeUtil.ts +130 -0
  164. package/Utils/NetworkDiscovery/ScanTargetUtil.ts +434 -0
  165. package/Utils/StatusPage/GroupNestingLayout.ts +343 -0
  166. package/Utils/StatusPage/GroupTree.ts +307 -0
  167. package/Utils/StatusPage/ResourceUptime.ts +90 -17
  168. package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js +1 -0
  169. package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js.map +1 -1
  170. package/build/dist/Models/DatabaseModels/AlertStateTimeline.js +1 -0
  171. package/build/dist/Models/DatabaseModels/AlertStateTimeline.js.map +1 -1
  172. package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js +1 -0
  173. package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js.map +1 -1
  174. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js +1 -0
  175. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js.map +1 -1
  176. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  177. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  178. package/build/dist/Models/DatabaseModels/LogDropFilter.js +91 -0
  179. package/build/dist/Models/DatabaseModels/LogDropFilter.js.map +1 -1
  180. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +14 -4
  181. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
  182. package/build/dist/Models/DatabaseModels/RecommendationDismissal.js +484 -0
  183. package/build/dist/Models/DatabaseModels/RecommendationDismissal.js.map +1 -0
  184. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js +1 -0
  185. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js.map +1 -1
  186. package/build/dist/Models/DatabaseModels/StatusPageGroup.js +94 -0
  187. package/build/dist/Models/DatabaseModels/StatusPageGroup.js.map +1 -1
  188. package/build/dist/Models/DatabaseModels/TraceDropFilter.js +91 -0
  189. package/build/dist/Models/DatabaseModels/TraceDropFilter.js.map +1 -1
  190. package/build/dist/Models/DatabaseModels/WorkflowVariable.js +5 -1
  191. package/build/dist/Models/DatabaseModels/WorkflowVariable.js.map +1 -1
  192. package/build/dist/Server/API/AlertAPI.js +22 -13
  193. package/build/dist/Server/API/AlertAPI.js.map +1 -1
  194. package/build/dist/Server/API/BaseAPI.js +22 -1
  195. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  196. package/build/dist/Server/API/BaseAnalyticsAPI.js +24 -1
  197. package/build/dist/Server/API/BaseAnalyticsAPI.js.map +1 -1
  198. package/build/dist/Server/API/CommonAPI.js +42 -0
  199. package/build/dist/Server/API/CommonAPI.js.map +1 -1
  200. package/build/dist/Server/API/IncidentAPI.js +43 -26
  201. package/build/dist/Server/API/IncidentAPI.js.map +1 -1
  202. package/build/dist/Server/API/IncidentEpisodeAPI.js +21 -12
  203. package/build/dist/Server/API/IncidentEpisodeAPI.js.map +1 -1
  204. package/build/dist/Server/API/MonitorAPI.js +23 -0
  205. package/build/dist/Server/API/MonitorAPI.js.map +1 -1
  206. package/build/dist/Server/API/MonitorTemplateAPI.js +4 -0
  207. package/build/dist/Server/API/MonitorTemplateAPI.js.map +1 -1
  208. package/build/dist/Server/API/ProbeAPI.js +131 -15
  209. package/build/dist/Server/API/ProbeAPI.js.map +1 -1
  210. package/build/dist/Server/API/ProjectAPI.js +62 -3
  211. package/build/dist/Server/API/ProjectAPI.js.map +1 -1
  212. package/build/dist/Server/API/ScheduledMaintenanceAPI.js +23 -14
  213. package/build/dist/Server/API/ScheduledMaintenanceAPI.js.map +1 -1
  214. package/build/dist/Server/API/StatusPageAPI.js +61 -33
  215. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  216. package/build/dist/Server/API/WorkspaceNotificationRuleAPI.js +26 -2
  217. package/build/dist/Server/API/WorkspaceNotificationRuleAPI.js.map +1 -1
  218. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785320000000-RepairCrossProjectIncidentReferences.js +397 -0
  219. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785320000000-RepairCrossProjectIncidentReferences.js.map +1 -0
  220. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785329453269-AddParentGroupToStatusPageGroup.js +16 -0
  221. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785329453269-AddParentGroupToStatusPageGroup.js.map +1 -0
  222. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785397674289-AddRecommendationDismissalTable.js +30 -0
  223. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785397674289-AddRecommendationDismissalTable.js.map +1 -0
  224. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785405581596-AddDroppedCountersToDropFilters.js +34 -0
  225. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785405581596-AddDroppedCountersToDropFilters.js.map +1 -0
  226. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
  227. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  228. package/build/dist/Server/Services/AlertEpisodeService.js +39 -0
  229. package/build/dist/Server/Services/AlertEpisodeService.js.map +1 -1
  230. package/build/dist/Server/Services/AlertService.js +95 -0
  231. package/build/dist/Server/Services/AlertService.js.map +1 -1
  232. package/build/dist/Server/Services/BillingService.js +71 -0
  233. package/build/dist/Server/Services/BillingService.js.map +1 -1
  234. package/build/dist/Server/Services/DatabaseService.js +140 -17
  235. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  236. package/build/dist/Server/Services/IncidentEpisodeService.js +39 -0
  237. package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
  238. package/build/dist/Server/Services/IncidentService.js +100 -0
  239. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  240. package/build/dist/Server/Services/IncidentTemplateService.js +97 -0
  241. package/build/dist/Server/Services/IncidentTemplateService.js.map +1 -1
  242. package/build/dist/Server/Services/Index.js +2 -0
  243. package/build/dist/Server/Services/Index.js.map +1 -1
  244. package/build/dist/Server/Services/LogDropFilterService.js +93 -0
  245. package/build/dist/Server/Services/LogDropFilterService.js.map +1 -1
  246. package/build/dist/Server/Services/MonitorProbeService.js +73 -5
  247. package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
  248. package/build/dist/Server/Services/MonitorService.js +34 -39
  249. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  250. package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js +71 -0
  251. package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js.map +1 -1
  252. package/build/dist/Server/Services/ProbeService.js +64 -0
  253. package/build/dist/Server/Services/ProbeService.js.map +1 -1
  254. package/build/dist/Server/Services/ProjectService.js +103 -7
  255. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  256. package/build/dist/Server/Services/RecommendationDismissalService.js +50 -0
  257. package/build/dist/Server/Services/RecommendationDismissalService.js.map +1 -0
  258. package/build/dist/Server/Services/RunbookAgentJobService.js +63 -5
  259. package/build/dist/Server/Services/RunbookAgentJobService.js.map +1 -1
  260. package/build/dist/Server/Services/ScheduledMaintenanceService.js +83 -0
  261. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  262. package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js +65 -0
  263. package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js.map +1 -1
  264. package/build/dist/Server/Services/StatusPageGroupService.js +136 -0
  265. package/build/dist/Server/Services/StatusPageGroupService.js.map +1 -1
  266. package/build/dist/Server/Services/TraceDropFilterService.js +93 -0
  267. package/build/dist/Server/Services/TraceDropFilterService.js.map +1 -1
  268. package/build/dist/Server/Types/Workflow/Components/API/Delete.js +11 -0
  269. package/build/dist/Server/Types/Workflow/Components/API/Delete.js.map +1 -1
  270. package/build/dist/Server/Types/Workflow/Components/API/Get.js +11 -0
  271. package/build/dist/Server/Types/Workflow/Components/API/Get.js.map +1 -1
  272. package/build/dist/Server/Types/Workflow/Components/API/Patch.js +11 -0
  273. package/build/dist/Server/Types/Workflow/Components/API/Patch.js.map +1 -1
  274. package/build/dist/Server/Types/Workflow/Components/API/Post.js +11 -0
  275. package/build/dist/Server/Types/Workflow/Components/API/Post.js.map +1 -1
  276. package/build/dist/Server/Types/Workflow/Components/API/Put.js +12 -0
  277. package/build/dist/Server/Types/Workflow/Components/API/Put.js.map +1 -1
  278. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +132 -0
  279. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -0
  280. package/build/dist/Server/Utils/DropFilterValidation.js +80 -0
  281. package/build/dist/Server/Utils/DropFilterValidation.js.map +1 -0
  282. package/build/dist/Server/Utils/Errors.js +3 -0
  283. package/build/dist/Server/Utils/Errors.js.map +1 -1
  284. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +30 -12
  285. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  286. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +38 -18
  287. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  288. package/build/dist/Server/Utils/Telemetry/AppMetrics.js +26 -0
  289. package/build/dist/Server/Utils/Telemetry/AppMetrics.js.map +1 -1
  290. package/build/dist/Types/Date.js +14 -4
  291. package/build/dist/Types/Date.js.map +1 -1
  292. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +192 -0
  293. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
  294. package/build/dist/Types/Monitor/MonitorStep.js +6 -1
  295. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  296. package/build/dist/Types/Monitor/MonitorStepMetricMonitor.js +32 -1
  297. package/build/dist/Types/Monitor/MonitorStepMetricMonitor.js.map +1 -1
  298. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +294 -0
  299. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -0
  300. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js +110 -0
  301. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js.map +1 -0
  302. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +58 -0
  303. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -0
  304. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +451 -0
  305. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -0
  306. package/build/dist/Types/Permission.js +40 -0
  307. package/build/dist/Types/Permission.js.map +1 -1
  308. package/build/dist/Types/Recommendation/RecommendationType.js +21 -0
  309. package/build/dist/Types/Recommendation/RecommendationType.js.map +1 -0
  310. package/build/dist/Types/Runbook/RunbookExecutionDeadline.js +93 -0
  311. package/build/dist/Types/Runbook/RunbookExecutionDeadline.js.map +1 -0
  312. package/build/dist/Types/Runbook/RunbookStepTimeout.js +142 -0
  313. package/build/dist/Types/Runbook/RunbookStepTimeout.js.map +1 -0
  314. package/build/dist/Types/Telemetry/DropFilterSampling.js +75 -0
  315. package/build/dist/Types/Telemetry/DropFilterSampling.js.map +1 -0
  316. package/build/dist/UI/Components/AI/GenerateFromAIModal.js +1 -2
  317. package/build/dist/UI/Components/AI/GenerateFromAIModal.js.map +1 -1
  318. package/build/dist/UI/Components/Accordion/Accordion.js +9 -2
  319. package/build/dist/UI/Components/Accordion/Accordion.js.map +1 -1
  320. package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js +1 -1
  321. package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js.map +1 -1
  322. package/build/dist/UI/Components/CodeEditor/CodeEditor.js +27 -14
  323. package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
  324. package/build/dist/UI/Components/Date/RangeStartAndEndDateView.js +1 -1
  325. package/build/dist/UI/Components/Date/RangeStartAndEndDateView.js.map +1 -1
  326. package/build/dist/UI/Components/EditionLabel/EditionLabel.js +2 -20
  327. package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
  328. package/build/dist/UI/Components/Error/PageError.js +1 -3
  329. package/build/dist/UI/Components/Error/PageError.js.map +1 -1
  330. package/build/dist/UI/Components/ErrorBoundary.js +145 -11
  331. package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
  332. package/build/dist/UI/Components/InfoCard/InfoCard.js +28 -1
  333. package/build/dist/UI/Components/InfoCard/InfoCard.js.map +1 -1
  334. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +13 -2
  335. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
  336. package/build/dist/UI/Components/Modal/Modal.js +4 -32
  337. package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
  338. package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
  339. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +69 -33
  340. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  341. package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js +73 -32
  342. package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js.map +1 -1
  343. package/build/dist/UI/Components/Runbook/StepTimeoutInput.js +101 -0
  344. package/build/dist/UI/Components/Runbook/StepTimeoutInput.js.map +1 -0
  345. package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js +73 -0
  346. package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js.map +1 -0
  347. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +13 -2
  348. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
  349. package/build/dist/UI/Utils/DropdownAlignment.js +98 -0
  350. package/build/dist/UI/Utils/DropdownAlignment.js.map +1 -0
  351. package/build/dist/UI/Utils/TableFilterUrlState.js +48 -15
  352. package/build/dist/UI/Utils/TableFilterUrlState.js.map +1 -1
  353. package/build/dist/Utils/API.js +39 -2
  354. package/build/dist/Utils/API.js.map +1 -1
  355. package/build/dist/Utils/Monitor/MonitorSummaryProbeUtil.js +97 -0
  356. package/build/dist/Utils/Monitor/MonitorSummaryProbeUtil.js.map +1 -0
  357. package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js +330 -0
  358. package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js.map +1 -0
  359. package/build/dist/Utils/StatusPage/GroupNestingLayout.js +280 -0
  360. package/build/dist/Utils/StatusPage/GroupNestingLayout.js.map +1 -0
  361. package/build/dist/Utils/StatusPage/GroupTree.js +214 -0
  362. package/build/dist/Utils/StatusPage/GroupTree.js.map +1 -0
  363. package/build/dist/Utils/StatusPage/ResourceUptime.js +60 -16
  364. package/build/dist/Utils/StatusPage/ResourceUptime.js.map +1 -1
  365. package/package.json +1 -1
@@ -0,0 +1,463 @@
1
+ import ProjectScopedReferenceValidator from "../../../../Server/Utils/Database/ProjectScopedReferenceValidator";
2
+ import IncidentSeverityService from "../../../../Server/Services/IncidentSeverityService";
3
+ import IncidentStateService from "../../../../Server/Services/IncidentStateService";
4
+ import MonitorStatusService from "../../../../Server/Services/MonitorStatusService";
5
+ import IncidentSeverity from "../../../../Models/DatabaseModels/IncidentSeverity";
6
+ import IncidentState from "../../../../Models/DatabaseModels/IncidentState";
7
+ import MonitorStatus from "../../../../Models/DatabaseModels/MonitorStatus";
8
+ import BadDataException from "../../../../Types/Exception/BadDataException";
9
+ import ObjectID from "../../../../Types/ObjectID";
10
+ import { afterEach, describe, expect, it, jest } from "@jest/globals";
11
+
12
+ /*
13
+ * Contract under test: an incident (or alert, or scheduled maintenance event)
14
+ * stores the id of its state, its severity and the monitor status it switches
15
+ * monitors to. Saving one that belongs to a *different* project is what leaves
16
+ * the referenced project undeletable — deleting that project cascades into the
17
+ * record, the row here still points at it, and the ON DELETE NO ACTION foreign
18
+ * key refuses the delete with 23503.
19
+ *
20
+ * The check has to stay narrow in the same way MonitorStepsProjectValidator
21
+ * is: an id that matches no row at all must keep saving, otherwise a record
22
+ * that already points at something deleted can never be saved back into shape.
23
+ */
24
+
25
+ const PROJECT_ID: ObjectID = new ObjectID(
26
+ "4af3a31b-58b0-4746-8025-f9cd4db1945e",
27
+ );
28
+ const OTHER_PROJECT_ID: ObjectID = new ObjectID(
29
+ "3376855b-361c-427c-8982-bad7ada30414",
30
+ );
31
+
32
+ const OWN_SEVERITY_ID: string = "59b5ab80-63f6-4ffd-b3df-31c6ad127695";
33
+ const FOREIGN_SEVERITY_ID: string = "cfc2f04f-79cb-4344-8c54-dafe5e3a290c";
34
+ const FOREIGN_STATE_ID: string = "a2eb67d4-bd2e-4186-9187-dad799c9316c";
35
+ const FOREIGN_STATUS_ID: string = "1a1cf3f2-0e35-4a1e-98a1-3f0f8b5f7f9e";
36
+ const UNKNOWN_ID: string = "9c0ba0b3-2f8e-4c02-a8d5-6a4d2f5b9c11";
37
+
38
+ const incidentSeverity: (
39
+ id: string,
40
+ projectId: ObjectID,
41
+ ) => IncidentSeverity = (id: string, projectId: ObjectID): IncidentSeverity => {
42
+ const severity: IncidentSeverity = new IncidentSeverity();
43
+ severity._id = id;
44
+ severity.name = "Critical";
45
+ severity.projectId = projectId;
46
+ return severity;
47
+ };
48
+
49
+ const incidentState: (id: string, projectId: ObjectID) => IncidentState = (
50
+ id: string,
51
+ projectId: ObjectID,
52
+ ): IncidentState => {
53
+ const state: IncidentState = new IncidentState();
54
+ state._id = id;
55
+ state.name = "Created";
56
+ state.projectId = projectId;
57
+ return state;
58
+ };
59
+
60
+ const monitorStatus: (id: string, projectId: ObjectID) => MonitorStatus = (
61
+ id: string,
62
+ projectId: ObjectID,
63
+ ): MonitorStatus => {
64
+ const status: MonitorStatus = new MonitorStatus();
65
+ status._id = id;
66
+ status.name = "Operational";
67
+ status.projectId = projectId;
68
+ return status;
69
+ };
70
+
71
+ type FoundRecords = {
72
+ incidentSeverities?: Array<IncidentSeverity>;
73
+ incidentStates?: Array<IncidentState>;
74
+ monitorStatuses?: Array<MonitorStatus>;
75
+ };
76
+
77
+ const mockLookups: (found: FoundRecords) => {
78
+ severityFindBy: jest.Mock;
79
+ stateFindBy: jest.Mock;
80
+ statusFindBy: jest.Mock;
81
+ } = (found: FoundRecords) => {
82
+ const severityFindBy: jest.Mock = jest.fn(async () => {
83
+ return found.incidentSeverities || [];
84
+ }) as unknown as jest.Mock;
85
+ const stateFindBy: jest.Mock = jest.fn(async () => {
86
+ return found.incidentStates || [];
87
+ }) as unknown as jest.Mock;
88
+ const statusFindBy: jest.Mock = jest.fn(async () => {
89
+ return found.monitorStatuses || [];
90
+ }) as unknown as jest.Mock;
91
+
92
+ jest
93
+ .spyOn(IncidentSeverityService, "findBy")
94
+ .mockImplementation(severityFindBy as never);
95
+ jest
96
+ .spyOn(IncidentStateService, "findBy")
97
+ .mockImplementation(stateFindBy as never);
98
+ jest
99
+ .spyOn(MonitorStatusService, "findBy")
100
+ .mockImplementation(statusFindBy as never);
101
+
102
+ return { severityFindBy, stateFindBy, statusFindBy };
103
+ };
104
+
105
+ describe("ProjectScopedReferenceValidator", () => {
106
+ afterEach(() => {
107
+ jest.restoreAllMocks();
108
+ });
109
+
110
+ it("rejects a reference that belongs to another project", async () => {
111
+ mockLookups({
112
+ incidentSeverities: [
113
+ incidentSeverity(FOREIGN_SEVERITY_ID, OTHER_PROJECT_ID),
114
+ ],
115
+ });
116
+
117
+ await expect(
118
+ ProjectScopedReferenceValidator.validateReferencesBelongToProject({
119
+ projectId: PROJECT_ID,
120
+ subject: "incident",
121
+ references: [
122
+ {
123
+ modelName: "Incident Severity",
124
+ id: FOREIGN_SEVERITY_ID,
125
+ service: IncidentSeverityService,
126
+ },
127
+ ],
128
+ }),
129
+ ).rejects.toThrow(BadDataException);
130
+ });
131
+
132
+ it("names the model and the record in the rejection so the user can fix it", async () => {
133
+ mockLookups({
134
+ incidentSeverities: [
135
+ incidentSeverity(FOREIGN_SEVERITY_ID, OTHER_PROJECT_ID),
136
+ ],
137
+ });
138
+
139
+ await expect(
140
+ ProjectScopedReferenceValidator.validateReferencesBelongToProject({
141
+ projectId: PROJECT_ID,
142
+ subject: "incident",
143
+ references: [
144
+ {
145
+ modelName: "Incident Severity",
146
+ id: FOREIGN_SEVERITY_ID,
147
+ service: IncidentSeverityService,
148
+ },
149
+ ],
150
+ }),
151
+ ).rejects.toThrow(
152
+ 'This incident references records that belong to a different project: Incident Severity "Critical". Please pick values from this project and try again.',
153
+ );
154
+ });
155
+
156
+ it("accepts a reference that belongs to the same project", async () => {
157
+ mockLookups({
158
+ incidentSeverities: [incidentSeverity(OWN_SEVERITY_ID, PROJECT_ID)],
159
+ });
160
+
161
+ await expect(
162
+ ProjectScopedReferenceValidator.validateReferencesBelongToProject({
163
+ projectId: PROJECT_ID,
164
+ references: [
165
+ {
166
+ modelName: "Incident Severity",
167
+ id: OWN_SEVERITY_ID,
168
+ service: IncidentSeverityService,
169
+ },
170
+ ],
171
+ }),
172
+ ).resolves.toBeUndefined();
173
+ });
174
+
175
+ it("leaves an id that matches no record alone", async () => {
176
+ /*
177
+ * A record that already points at something deleted must stay saveable —
178
+ * refusing unknown ids would trap the user. The not-null and foreign key
179
+ * checks report that case on their own.
180
+ */
181
+ mockLookups({ incidentSeverities: [] });
182
+
183
+ await expect(
184
+ ProjectScopedReferenceValidator.validateReferencesBelongToProject({
185
+ projectId: PROJECT_ID,
186
+ references: [
187
+ {
188
+ modelName: "Incident Severity",
189
+ id: UNKNOWN_ID,
190
+ service: IncidentSeverityService,
191
+ },
192
+ ],
193
+ }),
194
+ ).resolves.toBeUndefined();
195
+ });
196
+
197
+ it("reports every foreign reference in a single message", async () => {
198
+ mockLookups({
199
+ incidentSeverities: [
200
+ incidentSeverity(FOREIGN_SEVERITY_ID, OTHER_PROJECT_ID),
201
+ ],
202
+ incidentStates: [incidentState(FOREIGN_STATE_ID, OTHER_PROJECT_ID)],
203
+ monitorStatuses: [monitorStatus(FOREIGN_STATUS_ID, OTHER_PROJECT_ID)],
204
+ });
205
+
206
+ let message: string = "";
207
+
208
+ try {
209
+ await ProjectScopedReferenceValidator.validateReferencesBelongToProject({
210
+ projectId: PROJECT_ID,
211
+ subject: "incident",
212
+ references: [
213
+ {
214
+ modelName: "Incident State",
215
+ id: FOREIGN_STATE_ID,
216
+ service: IncidentStateService,
217
+ },
218
+ {
219
+ modelName: "Incident Severity",
220
+ id: FOREIGN_SEVERITY_ID,
221
+ service: IncidentSeverityService,
222
+ },
223
+ {
224
+ modelName: "Monitor Status",
225
+ id: FOREIGN_STATUS_ID,
226
+ service: MonitorStatusService,
227
+ },
228
+ ],
229
+ });
230
+ } catch (error) {
231
+ message = (error as BadDataException).message;
232
+ }
233
+
234
+ expect(message).toContain('Incident State "Created"');
235
+ expect(message).toContain('Incident Severity "Critical"');
236
+ expect(message).toContain('Monitor Status "Operational"');
237
+ });
238
+
239
+ it("mixes accepted and rejected references without letting the good one mask the bad one", async () => {
240
+ mockLookups({
241
+ incidentSeverities: [
242
+ incidentSeverity(OWN_SEVERITY_ID, PROJECT_ID),
243
+ incidentSeverity(FOREIGN_SEVERITY_ID, OTHER_PROJECT_ID),
244
+ ],
245
+ });
246
+
247
+ let message: string = "";
248
+
249
+ try {
250
+ await ProjectScopedReferenceValidator.validateReferencesBelongToProject({
251
+ projectId: PROJECT_ID,
252
+ references: [
253
+ {
254
+ modelName: "Incident Severity",
255
+ id: OWN_SEVERITY_ID,
256
+ service: IncidentSeverityService,
257
+ },
258
+ {
259
+ modelName: "Incident Severity",
260
+ id: FOREIGN_SEVERITY_ID,
261
+ service: IncidentSeverityService,
262
+ },
263
+ ],
264
+ });
265
+ } catch (error) {
266
+ message = (error as BadDataException).message;
267
+ }
268
+
269
+ expect(message).toContain("belong to a different project");
270
+ });
271
+
272
+ it("looks each model up once, with every id it was asked about", async () => {
273
+ /*
274
+ * These run on the incident create path, so three references must not mean
275
+ * three round trips per model.
276
+ */
277
+ const { severityFindBy } = mockLookups({ incidentSeverities: [] });
278
+
279
+ await ProjectScopedReferenceValidator.validateReferencesBelongToProject({
280
+ projectId: PROJECT_ID,
281
+ references: [
282
+ {
283
+ modelName: "Incident Severity",
284
+ id: OWN_SEVERITY_ID,
285
+ service: IncidentSeverityService,
286
+ },
287
+ {
288
+ modelName: "Incident Severity",
289
+ id: FOREIGN_SEVERITY_ID,
290
+ service: IncidentSeverityService,
291
+ },
292
+ ],
293
+ });
294
+
295
+ expect(severityFindBy).toHaveBeenCalledTimes(1);
296
+
297
+ /*
298
+ * QueryHelper.any() builds a Raw() operator that carries the ids as bound
299
+ * parameters under a generated key, so assert on the serialized query
300
+ * rather than on that key.
301
+ */
302
+ const query: string = JSON.stringify(
303
+ (
304
+ severityFindBy.mock.calls[0] as unknown as Array<{
305
+ query: unknown;
306
+ }>
307
+ )[0]!.query,
308
+ );
309
+
310
+ expect(query).toContain(OWN_SEVERITY_ID);
311
+ expect(query).toContain(FOREIGN_SEVERITY_ID);
312
+ });
313
+
314
+ it("issues no query at all when nothing is being referenced", async () => {
315
+ const { severityFindBy, stateFindBy, statusFindBy } = mockLookups({});
316
+
317
+ await ProjectScopedReferenceValidator.validateReferencesBelongToProject({
318
+ projectId: PROJECT_ID,
319
+ references: [
320
+ {
321
+ modelName: "Incident Severity",
322
+ id: undefined,
323
+ service: IncidentSeverityService,
324
+ },
325
+ {
326
+ modelName: "Incident State",
327
+ id: null,
328
+ service: IncidentStateService,
329
+ },
330
+ {
331
+ modelName: "Monitor Status",
332
+ id: "",
333
+ service: MonitorStatusService,
334
+ },
335
+ ],
336
+ });
337
+
338
+ expect(severityFindBy).not.toHaveBeenCalled();
339
+ expect(stateFindBy).not.toHaveBeenCalled();
340
+ expect(statusFindBy).not.toHaveBeenCalled();
341
+ });
342
+
343
+ it("does nothing when the project is unknown", async () => {
344
+ /*
345
+ * Root and internal writes do not always carry a project. There is nothing
346
+ * to compare against, so the check has to stay out of the way rather than
347
+ * guess.
348
+ */
349
+ const { severityFindBy } = mockLookups({
350
+ incidentSeverities: [
351
+ incidentSeverity(FOREIGN_SEVERITY_ID, OTHER_PROJECT_ID),
352
+ ],
353
+ });
354
+
355
+ await expect(
356
+ ProjectScopedReferenceValidator.validateReferencesBelongToProject({
357
+ projectId: undefined,
358
+ references: [
359
+ {
360
+ modelName: "Incident Severity",
361
+ id: FOREIGN_SEVERITY_ID,
362
+ service: IncidentSeverityService,
363
+ },
364
+ ],
365
+ }),
366
+ ).resolves.toBeUndefined();
367
+
368
+ expect(severityFindBy).not.toHaveBeenCalled();
369
+ });
370
+
371
+ it("treats an ObjectID and its string form as the same reference", async () => {
372
+ mockLookups({
373
+ incidentSeverities: [
374
+ incidentSeverity(FOREIGN_SEVERITY_ID, OTHER_PROJECT_ID),
375
+ ],
376
+ });
377
+
378
+ await expect(
379
+ ProjectScopedReferenceValidator.validateReferencesBelongToProject({
380
+ projectId: PROJECT_ID,
381
+ references: [
382
+ {
383
+ modelName: "Incident Severity",
384
+ id: new ObjectID(FOREIGN_SEVERITY_ID),
385
+ service: IncidentSeverityService,
386
+ },
387
+ ],
388
+ }),
389
+ ).rejects.toThrow("belong to a different project");
390
+ });
391
+
392
+ it("falls back to the id when the foreign record has no name", async () => {
393
+ const severity: IncidentSeverity = incidentSeverity(
394
+ FOREIGN_SEVERITY_ID,
395
+ OTHER_PROJECT_ID,
396
+ );
397
+ delete severity.name;
398
+
399
+ mockLookups({ incidentSeverities: [severity] });
400
+
401
+ await expect(
402
+ ProjectScopedReferenceValidator.validateReferencesBelongToProject({
403
+ projectId: PROJECT_ID,
404
+ references: [
405
+ {
406
+ modelName: "Incident Severity",
407
+ id: FOREIGN_SEVERITY_ID,
408
+ service: IncidentSeverityService,
409
+ },
410
+ ],
411
+ }),
412
+ ).rejects.toThrow(`Incident Severity "${FOREIGN_SEVERITY_ID}"`);
413
+ });
414
+
415
+ it("rejects a record with no project of its own", async () => {
416
+ /*
417
+ * A project-scoped record without a projectId is not this project's, and
418
+ * treating "no project" as "same project" would let exactly the rows this
419
+ * check exists for slip through.
420
+ */
421
+ const severity: IncidentSeverity = incidentSeverity(
422
+ FOREIGN_SEVERITY_ID,
423
+ OTHER_PROJECT_ID,
424
+ );
425
+ delete severity.projectId;
426
+
427
+ mockLookups({ incidentSeverities: [severity] });
428
+
429
+ await expect(
430
+ ProjectScopedReferenceValidator.validateReferencesBelongToProject({
431
+ projectId: PROJECT_ID,
432
+ references: [
433
+ {
434
+ modelName: "Incident Severity",
435
+ id: FOREIGN_SEVERITY_ID,
436
+ service: IncidentSeverityService,
437
+ },
438
+ ],
439
+ }),
440
+ ).rejects.toThrow("belong to a different project");
441
+ });
442
+
443
+ it("says 'request' when the caller does not name the subject", async () => {
444
+ mockLookups({
445
+ incidentSeverities: [
446
+ incidentSeverity(FOREIGN_SEVERITY_ID, OTHER_PROJECT_ID),
447
+ ],
448
+ });
449
+
450
+ await expect(
451
+ ProjectScopedReferenceValidator.validateReferencesBelongToProject({
452
+ projectId: PROJECT_ID,
453
+ references: [
454
+ {
455
+ modelName: "Incident Severity",
456
+ id: FOREIGN_SEVERITY_ID,
457
+ service: IncidentSeverityService,
458
+ },
459
+ ],
460
+ }),
461
+ ).rejects.toThrow("This request references records");
462
+ });
463
+ });