@oneuptime/common 11.7.1 → 11.7.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 (285) hide show
  1. package/Models/AnalyticsModels/KubernetesCostAllocation.ts +103 -0
  2. package/Models/DatabaseModels/DashboardDomain.ts +1 -0
  3. package/Models/DatabaseModels/Incident.ts +2 -0
  4. package/Models/DatabaseModels/IncidentEpisode.ts +1 -0
  5. package/Models/DatabaseModels/IncidentEpisodePublicNote.ts +1 -0
  6. package/Models/DatabaseModels/IncidentEpisodeStateTimeline.ts +1 -0
  7. package/Models/DatabaseModels/IncidentPublicNote.ts +1 -0
  8. package/Models/DatabaseModels/IncidentStateTimeline.ts +1 -0
  9. package/Models/DatabaseModels/Monitor.ts +1 -0
  10. package/Models/DatabaseModels/MonitorStatusTimeline.ts +1 -0
  11. package/Models/DatabaseModels/NetworkSite.ts +1 -0
  12. package/Models/DatabaseModels/NetworkSiteStatusTimeline.ts +1 -0
  13. package/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.ts +1 -0
  14. package/Models/DatabaseModels/OnCallDutyPolicySchedule.ts +2 -0
  15. package/Models/DatabaseModels/Probe.ts +13 -13
  16. package/Models/DatabaseModels/ScheduledMaintenance.ts +1 -0
  17. package/Models/DatabaseModels/ScheduledMaintenancePublicNote.ts +1 -0
  18. package/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.ts +1 -0
  19. package/Models/DatabaseModels/ScheduledMaintenanceTemplate.ts +1 -0
  20. package/Models/DatabaseModels/StatusPage.ts +1 -0
  21. package/Models/DatabaseModels/StatusPageAnnouncement.ts +1 -0
  22. package/Models/DatabaseModels/StatusPageDomain.ts +1 -0
  23. package/Models/DatabaseModels/TableView.ts +40 -0
  24. package/Models/DatabaseModels/WorkspaceNotificationSummary.ts +1 -0
  25. package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +11 -0
  26. package/Server/API/BaseAPI.ts +17 -1
  27. package/Server/API/CommonAPI.ts +32 -0
  28. package/Server/API/MicrosoftTeamsAPI.ts +99 -2
  29. package/Server/API/ProbeAPI.ts +2 -0
  30. package/Server/API/SlackAPI.ts +62 -0
  31. package/Server/API/StatusPageAPI.ts +157 -192
  32. package/Server/Infrastructure/Postgres/SchemaMigrations/1785140242697-AddHotQueryIndexes.ts +89 -0
  33. package/Server/Infrastructure/Postgres/SchemaMigrations/1785148065137-AddHotQueryIndexesSecondPass.ts +61 -0
  34. package/Server/Infrastructure/Postgres/SchemaMigrations/1785240000000-RepairCrossProjectMonitorStatusReferences.ts +280 -0
  35. package/Server/Infrastructure/Postgres/SchemaMigrations/1785241000000-AddColumnsToTableView.ts +13 -0
  36. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
  37. package/Server/Services/DatabaseService.ts +11 -3
  38. package/Server/Services/MonitorGroupService.ts +145 -0
  39. package/Server/Services/MonitorService.ts +231 -30
  40. package/Server/Services/ProbeService.ts +319 -16
  41. package/Server/Services/StatusPageService.ts +72 -42
  42. package/Server/Services/WorkspaceNotificationRuleService.ts +232 -2
  43. package/Server/Utils/Database/PostgresErrorTranslator.ts +131 -0
  44. package/Server/Utils/Monitor/MonitorResource.ts +88 -35
  45. package/Server/Utils/Monitor/MonitorStatusTimeline.ts +21 -1
  46. package/Server/Utils/Monitor/MonitorStepsProjectValidator.ts +158 -0
  47. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +706 -6
  48. package/Tests/Models/AnalyticsModels/KubernetesCostAllocation.test.ts +16 -0
  49. package/Tests/Models/DatabaseModels/ProbeColumnAccessControl.test.ts +103 -0
  50. package/Tests/Server/API/BaseAPIUpdateNoOp.test.ts +135 -0
  51. package/Tests/Server/API/CommonAPIAuthGuard.test.ts +317 -0
  52. package/Tests/Server/API/MicrosoftTeamsManifest.test.ts +228 -0
  53. package/Tests/Server/API/ProbeAPI.test.ts +6 -0
  54. package/Tests/Server/API/ZZVerifyChatsAuth.test.ts +167 -0
  55. package/Tests/Server/Services/AddHotQueryIndexesMigration.test.ts +255 -0
  56. package/Tests/Server/Services/AddHotQueryIndexesSecondPassMigration.test.ts +258 -0
  57. package/Tests/Server/Services/DatabaseServiceSanitizeUpdateData.test.ts +1 -1
  58. package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +121 -0
  59. package/Tests/Server/Services/HeartbeatWriteFastPathSafety.test.ts +200 -0
  60. package/Tests/Server/Services/HookFreeWriteSafetySecondPass.test.ts +181 -0
  61. package/Tests/Server/Services/MonitorGroupServiceBatchedStatuses.test.ts +513 -0
  62. package/Tests/Server/Services/MonitorResourceProbeAgreementReuse.test.ts +492 -0
  63. package/Tests/Server/Services/MonitorServiceProbeSelection.test.ts +401 -0
  64. package/Tests/Server/Services/MonitorStatusTimelineFastPath.test.ts +453 -0
  65. package/Tests/Server/Services/ProbeAuthKeyCacheAndHeartbeat.test.ts +679 -0
  66. package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +3 -3
  67. package/Tests/Server/Services/StatusPageDomainResolutionCache.test.ts +245 -0
  68. package/Tests/Server/Services/StatusPageOverviewTimelineWindow.test.ts +283 -0
  69. package/Tests/Server/Services/StatusPageServiceMcp.test.ts +17 -1
  70. package/Tests/Server/Services/StatusPageServiceMonitorGroupBatching.test.ts +331 -0
  71. package/Tests/Server/Services/UserOnCallLogClaimNotificationRule.test.ts +12 -12
  72. package/Tests/Server/Services/WorkspaceNotificationRuleChats.test.ts +1390 -0
  73. package/Tests/Server/Utils/AI/Insights/InsightFixRouting.test.ts +4 -4
  74. package/Tests/Server/Utils/AI/Insights/InsightScanner.test.ts +2 -2
  75. package/Tests/Server/Utils/AI/Insights/InsightStore.test.ts +1 -3
  76. package/Tests/Server/Utils/AI/Insights/InsightStoreHardening.test.ts +1 -3
  77. package/Tests/Server/Utils/AI/Insights/InsightTriage.test.ts +1 -1
  78. package/Tests/Server/Utils/AI/Insights/InsightTriageRunner.test.ts +5 -5
  79. package/Tests/Server/Utils/Alert/AlertPrivacyFilter.test.ts +187 -0
  80. package/Tests/Server/Utils/AlertEpisode/AlertEpisodePrivacyFilter.test.ts +170 -0
  81. package/Tests/Server/Utils/Database/PostgresErrorTranslator.test.ts +125 -0
  82. package/Tests/Server/Utils/Incident/IncidentPrivacyFilter.test.ts +264 -0
  83. package/Tests/Server/Utils/IncidentEpisode/IncidentEpisodePrivacyFilter.test.ts +175 -0
  84. package/Tests/Server/Utils/Monitor/MonitorStepsProjectValidator.test.ts +181 -0
  85. package/Tests/Server/Utils/Monitor/NetworkDeviceWalkUtil.test.ts +1 -1
  86. package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +2 -2
  87. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelsList.test.ts +341 -0
  88. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChats.test.ts +2175 -0
  89. package/Tests/Server/Utils/Workspace/SlackChannelsList.test.ts +585 -0
  90. package/Tests/Types/Billing/MeteredPlan.test.ts +46 -0
  91. package/Tests/Types/JSONFunctions.test.ts +103 -1
  92. package/Tests/Types/Workspace/NotificationRules/NotificationRuleCondition.test.ts +219 -1
  93. package/Tests/UI/Components/BulkUpdateForm.test.tsx +174 -0
  94. package/Tests/UI/Components/CardModelDetailEdit.test.tsx +315 -0
  95. package/Tests/UI/Components/ModelDetailSelect.test.tsx +229 -0
  96. package/Tests/UI/Components/ModelTable/BaseModelTableBulkSelectAll.test.tsx +1258 -0
  97. package/Tests/UI/Components/ModelTable/BaseModelTableColumnCustomization.test.tsx +679 -0
  98. package/Tests/UI/Components/ModelTable/ColumnCustomizationModal.test.tsx +572 -0
  99. package/Tests/UI/Components/ModelTable/ColumnPreference.test.ts +1678 -0
  100. package/Tests/UI/Components/ModelTable/CustomFieldColumns.test.tsx +1094 -0
  101. package/Tests/UI/Components/ModelTableExportFromColumns.test.ts +153 -0
  102. package/Tests/UI/Components/MonacoLoader.test.ts +67 -0
  103. package/Tests/UI/Components/MonacoRuntime.test.ts +121 -0
  104. package/Tests/UI/Components/TableBulkCsvExport.test.tsx +212 -3
  105. package/Tests/UI/Utils/Project.test.ts +809 -0
  106. package/Tests/UI/Utils/TableColumnsToCsv.test.ts +360 -0
  107. package/Tests/Utils/Alerts/AlertMetricType.test.ts +143 -0
  108. package/Tests/Utils/Dashboard/VariableUrlState.test.ts +219 -0
  109. package/Tests/Utils/Incident/IncidentMetricType.test.ts +174 -0
  110. package/Tests/Utils/Monitor/MonitorProbeSelectionUtil.test.ts +145 -0
  111. package/Tests/Utils/StatusPage/ResourceUptime.test.ts +263 -0
  112. package/Tests/Utils/UserPreferences.test.ts +563 -0
  113. package/Types/JSONFunctions.ts +7 -2
  114. package/Types/Kubernetes/KubernetesCostIngest.ts +37 -1
  115. package/Types/Workspace/NotificationRules/BaseNotificationRule.ts +4 -0
  116. package/Types/Workspace/NotificationRules/NotificationRuleCondition.ts +25 -10
  117. package/Types/Workspace/WorkspaceMessagePayload.ts +1 -0
  118. package/UI/Components/BulkUpdate/BulkUpdateForm.tsx +63 -8
  119. package/UI/Components/CodeEditor/CodeEditor.tsx +3 -0
  120. package/UI/Components/CodeEditor/MonacoLoader.ts +36 -0
  121. package/UI/Components/Forms/ModelForm.tsx +41 -18
  122. package/UI/Components/MasterPage/MasterPage.tsx +65 -0
  123. package/UI/Components/ModelDetail/CardModelDetail.tsx +23 -1
  124. package/UI/Components/ModelDetail/ModelDetail.tsx +46 -1
  125. package/UI/Components/ModelTable/BaseModelTable.tsx +687 -34
  126. package/UI/Components/ModelTable/Column.ts +29 -0
  127. package/UI/Components/ModelTable/ColumnCustomizationModal.tsx +420 -0
  128. package/UI/Components/ModelTable/ColumnPreference.ts +482 -0
  129. package/UI/Components/ModelTable/CustomFieldColumns.tsx +326 -0
  130. package/UI/Components/ModelTable/ExportFromColumns.ts +57 -0
  131. package/UI/Components/ModelTable/TableView.tsx +24 -2
  132. package/UI/Components/ModelTable/useCustomFieldColumns.ts +150 -0
  133. package/UI/Components/Navbar/NavBar.tsx +66 -1
  134. package/UI/Components/SideMenu/SideMenu.tsx +24 -4
  135. package/UI/Components/Table/Table.tsx +66 -14
  136. package/UI/Components/Table/TableRow.tsx +180 -175
  137. package/UI/Components/Table/Types/Column.ts +20 -0
  138. package/UI/Utils/Project.ts +214 -18
  139. package/UI/Utils/TableColumnsToCsv.ts +86 -6
  140. package/UI/esbuild-config.js +34 -0
  141. package/Utils/Monitor/MonitorProbeSelectionUtil.ts +72 -0
  142. package/Utils/UserPreferences.ts +53 -0
  143. package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js +86 -0
  144. package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js.map +1 -1
  145. package/build/dist/Models/DatabaseModels/DashboardDomain.js +1 -0
  146. package/build/dist/Models/DatabaseModels/DashboardDomain.js.map +1 -1
  147. package/build/dist/Models/DatabaseModels/Incident.js +2 -0
  148. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  149. package/build/dist/Models/DatabaseModels/IncidentEpisode.js +1 -0
  150. package/build/dist/Models/DatabaseModels/IncidentEpisode.js.map +1 -1
  151. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js +1 -0
  152. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js.map +1 -1
  153. package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js +1 -0
  154. package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js.map +1 -1
  155. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js +1 -0
  156. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js.map +1 -1
  157. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js +1 -0
  158. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js.map +1 -1
  159. package/build/dist/Models/DatabaseModels/Monitor.js +1 -0
  160. package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
  161. package/build/dist/Models/DatabaseModels/MonitorStatusTimeline.js +1 -0
  162. package/build/dist/Models/DatabaseModels/MonitorStatusTimeline.js.map +1 -1
  163. package/build/dist/Models/DatabaseModels/NetworkSite.js +1 -0
  164. package/build/dist/Models/DatabaseModels/NetworkSite.js.map +1 -1
  165. package/build/dist/Models/DatabaseModels/NetworkSiteStatusTimeline.js +1 -0
  166. package/build/dist/Models/DatabaseModels/NetworkSiteStatusTimeline.js.map +1 -1
  167. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js +1 -0
  168. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js.map +1 -1
  169. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +2 -0
  170. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js.map +1 -1
  171. package/build/dist/Models/DatabaseModels/Probe.js +13 -13
  172. package/build/dist/Models/DatabaseModels/Probe.js.map +1 -1
  173. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +1 -0
  174. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
  175. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js +1 -0
  176. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js.map +1 -1
  177. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js +1 -0
  178. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js.map +1 -1
  179. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplate.js +1 -0
  180. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplate.js.map +1 -1
  181. package/build/dist/Models/DatabaseModels/StatusPage.js +1 -0
  182. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  183. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js +1 -0
  184. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js.map +1 -1
  185. package/build/dist/Models/DatabaseModels/StatusPageDomain.js +1 -0
  186. package/build/dist/Models/DatabaseModels/StatusPageDomain.js.map +1 -1
  187. package/build/dist/Models/DatabaseModels/TableView.js +40 -0
  188. package/build/dist/Models/DatabaseModels/TableView.js.map +1 -1
  189. package/build/dist/Models/DatabaseModels/WorkspaceNotificationSummary.js +1 -0
  190. package/build/dist/Models/DatabaseModels/WorkspaceNotificationSummary.js.map +1 -1
  191. package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
  192. package/build/dist/Server/API/BaseAPI.js +12 -1
  193. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  194. package/build/dist/Server/API/CommonAPI.js +21 -0
  195. package/build/dist/Server/API/CommonAPI.js.map +1 -1
  196. package/build/dist/Server/API/MicrosoftTeamsAPI.js +72 -2
  197. package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
  198. package/build/dist/Server/API/ProbeAPI.js +2 -0
  199. package/build/dist/Server/API/ProbeAPI.js.map +1 -1
  200. package/build/dist/Server/API/SlackAPI.js +44 -0
  201. package/build/dist/Server/API/SlackAPI.js.map +1 -1
  202. package/build/dist/Server/API/StatusPageAPI.js +98 -152
  203. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  204. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785140242697-AddHotQueryIndexes.js +36 -0
  205. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785140242697-AddHotQueryIndexes.js.map +1 -0
  206. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785148065137-AddHotQueryIndexesSecondPass.js +26 -0
  207. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785148065137-AddHotQueryIndexesSecondPass.js.map +1 -0
  208. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785240000000-RepairCrossProjectMonitorStatusReferences.js +254 -0
  209. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785240000000-RepairCrossProjectMonitorStatusReferences.js.map +1 -0
  210. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785241000000-AddColumnsToTableView.js +12 -0
  211. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785241000000-AddColumnsToTableView.js.map +1 -0
  212. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
  213. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  214. package/build/dist/Server/Services/DatabaseService.js +10 -2
  215. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  216. package/build/dist/Server/Services/MonitorGroupService.js +118 -0
  217. package/build/dist/Server/Services/MonitorGroupService.js.map +1 -1
  218. package/build/dist/Server/Services/MonitorService.js +198 -24
  219. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  220. package/build/dist/Server/Services/ProbeService.js +238 -9
  221. package/build/dist/Server/Services/ProbeService.js.map +1 -1
  222. package/build/dist/Server/Services/StatusPageService.js +46 -39
  223. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  224. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +178 -3
  225. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
  226. package/build/dist/Server/Utils/Database/PostgresErrorTranslator.js +80 -0
  227. package/build/dist/Server/Utils/Database/PostgresErrorTranslator.js.map +1 -0
  228. package/build/dist/Server/Utils/Monitor/MonitorResource.js +67 -29
  229. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  230. package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js +31 -14
  231. package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js.map +1 -1
  232. package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js +117 -0
  233. package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js.map +1 -0
  234. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +549 -7
  235. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  236. package/build/dist/Types/JSONFunctions.js +8 -3
  237. package/build/dist/Types/JSONFunctions.js.map +1 -1
  238. package/build/dist/Types/Kubernetes/KubernetesCostIngest.js.map +1 -1
  239. package/build/dist/Types/Workspace/NotificationRules/NotificationRuleCondition.js +17 -7
  240. package/build/dist/Types/Workspace/NotificationRules/NotificationRuleCondition.js.map +1 -1
  241. package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js +37 -11
  242. package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js.map +1 -1
  243. package/build/dist/UI/Components/CodeEditor/CodeEditor.js +2 -0
  244. package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
  245. package/build/dist/UI/Components/CodeEditor/MonacoLoader.js +34 -0
  246. package/build/dist/UI/Components/CodeEditor/MonacoLoader.js.map +1 -0
  247. package/build/dist/UI/Components/Forms/ModelForm.js +37 -17
  248. package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
  249. package/build/dist/UI/Components/MasterPage/MasterPage.js +50 -1
  250. package/build/dist/UI/Components/MasterPage/MasterPage.js.map +1 -1
  251. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +22 -1
  252. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
  253. package/build/dist/UI/Components/ModelDetail/ModelDetail.js +31 -1
  254. package/build/dist/UI/Components/ModelDetail/ModelDetail.js.map +1 -1
  255. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +472 -27
  256. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  257. package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js +189 -0
  258. package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js.map +1 -0
  259. package/build/dist/UI/Components/ModelTable/ColumnPreference.js +258 -0
  260. package/build/dist/UI/Components/ModelTable/ColumnPreference.js.map +1 -0
  261. package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js +168 -0
  262. package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js.map +1 -0
  263. package/build/dist/UI/Components/ModelTable/ExportFromColumns.js +30 -0
  264. package/build/dist/UI/Components/ModelTable/ExportFromColumns.js.map +1 -0
  265. package/build/dist/UI/Components/ModelTable/TableView.js +13 -2
  266. package/build/dist/UI/Components/ModelTable/TableView.js.map +1 -1
  267. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +84 -0
  268. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -0
  269. package/build/dist/UI/Components/Navbar/NavBar.js +39 -1
  270. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  271. package/build/dist/UI/Components/SideMenu/SideMenu.js +15 -5
  272. package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
  273. package/build/dist/UI/Components/Table/Table.js +46 -13
  274. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  275. package/build/dist/UI/Components/Table/TableRow.js +11 -6
  276. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  277. package/build/dist/UI/Utils/Project.js +161 -15
  278. package/build/dist/UI/Utils/Project.js.map +1 -1
  279. package/build/dist/UI/Utils/TableColumnsToCsv.js +67 -6
  280. package/build/dist/UI/Utils/TableColumnsToCsv.js.map +1 -1
  281. package/build/dist/Utils/Monitor/MonitorProbeSelectionUtil.js +52 -0
  282. package/build/dist/Utils/Monitor/MonitorProbeSelectionUtil.js.map +1 -0
  283. package/build/dist/Utils/UserPreferences.js +33 -0
  284. package/build/dist/Utils/UserPreferences.js.map +1 -1
  285. package/package.json +4 -3
@@ -0,0 +1,492 @@
1
+ /*
2
+ * The probe-result hot path in MonitorResource.ts now pre-fetches every
3
+ * MonitorProbe row for the monitor ONCE (with the heavy lastMonitoringLog
4
+ * jsonb) and threads the rows into checkProbeAgreement via the new optional
5
+ * `monitorProbes` input. Before this optimization checkProbeAgreement
6
+ * re-queried MonitorProbeService.findBy on every single probe result — the
7
+ * second-largest read on the hottest Postgres path.
8
+ *
9
+ * This suite pins the contract of that reuse:
10
+ * - when `monitorProbes` is PROVIDED, findBy must never run and the
11
+ * agreement result must be computed purely from the provided rows
12
+ * (including the provided-but-empty-array case: [] is truthy, so it
13
+ * must NOT fall back to querying);
14
+ * - when `monitorProbes` is ABSENT, the original single findBy with the
15
+ * original query/select must still run (the fallback for callers that
16
+ * did not pre-fetch, e.g. the incoming-request path);
17
+ * - the agreement semantics themselves (active-probe filtering, the
18
+ * minimumProbeAgreement threshold, missing-step-log skipping, and the
19
+ * no-active-probes pass-through) are unchanged by the reuse.
20
+ *
21
+ * If any assertion here starts failing, either the fallback query drifted
22
+ * from the pre-fetch select (the pre-fetch is the union both consumers
23
+ * need) or the reuse regressed into re-querying per result.
24
+ *
25
+ * Everything heavy is mocked BEFORE importing MonitorResource: the criteria
26
+ * evaluator (pulls native isolated-vm via VMAPI/VMRunner), the probe
27
+ * service (Postgres) and the logger. Pure in-memory model instances — no
28
+ * Postgres, no Redis, no isolated-vm.
29
+ */
30
+
31
+ jest.mock("../../../Server/Utils/Monitor/MonitorCriteriaEvaluator", () => {
32
+ return {
33
+ __esModule: true,
34
+ default: {
35
+ processMonitorStep: jest.fn(),
36
+ },
37
+ };
38
+ });
39
+
40
+ jest.mock("../../../Server/Services/MonitorProbeService", () => {
41
+ return {
42
+ __esModule: true,
43
+ default: {
44
+ findBy: jest.fn(),
45
+ },
46
+ };
47
+ });
48
+
49
+ jest.mock("../../../Server/Utils/Logger", () => {
50
+ return {
51
+ __esModule: true,
52
+ default: {
53
+ debug: jest.fn(),
54
+ info: jest.fn(),
55
+ warn: jest.fn(),
56
+ error: jest.fn(),
57
+ trace: jest.fn(),
58
+ },
59
+ };
60
+ });
61
+
62
+ import MonitorResourceUtil from "../../../Server/Utils/Monitor/MonitorResource";
63
+ import MonitorCriteriaEvaluator from "../../../Server/Utils/Monitor/MonitorCriteriaEvaluator";
64
+ import MonitorProbeService from "../../../Server/Services/MonitorProbeService";
65
+ import Monitor from "../../../Models/DatabaseModels/Monitor";
66
+ import MonitorProbe, {
67
+ MonitorStepProbeResponse,
68
+ } from "../../../Models/DatabaseModels/MonitorProbe";
69
+ import Probe, {
70
+ ProbeConnectionStatus,
71
+ } from "../../../Models/DatabaseModels/Probe";
72
+ import MonitorStep from "../../../Types/Monitor/MonitorStep";
73
+ import ObjectID from "../../../Types/ObjectID";
74
+ import ProbeApiIngestResponse from "../../../Types/Probe/ProbeApiIngestResponse";
75
+ import ProbeMonitorResponse from "../../../Types/Probe/ProbeMonitorResponse";
76
+ import DataToProcess from "../../../Server/Utils/Monitor/DataToProcess";
77
+ import { LIMIT_PER_PROJECT } from "../../../Types/Database/LimitMax";
78
+ import { describe, expect, test, beforeEach } from "@jest/globals";
79
+
80
+ interface ProbeAgreementResult {
81
+ hasAgreement: boolean;
82
+ agreementCount: number;
83
+ requiredCount: number;
84
+ totalActiveProbes: number;
85
+ agreedCriteriaId: string | null;
86
+ agreedRootCause: string | null;
87
+ agreedProbeNames: Array<string>;
88
+ }
89
+
90
+ const processMonitorStepMock: jest.Mock =
91
+ MonitorCriteriaEvaluator.processMonitorStep as unknown as jest.Mock;
92
+
93
+ const findByMock: jest.Mock =
94
+ MonitorProbeService.findBy as unknown as jest.Mock;
95
+
96
+ type CheckProbeAgreementFunction = (input: {
97
+ monitor: Monitor;
98
+ monitorStep: MonitorStep;
99
+ currentCriteriaMetId: string | null;
100
+ currentRootCause: string | null;
101
+ monitorProbes?: Array<MonitorProbe> | undefined;
102
+ }) => Promise<ProbeAgreementResult>;
103
+
104
+ const checkProbeAgreement: CheckProbeAgreementFunction = (
105
+ MonitorResourceUtil as any
106
+ )["checkProbeAgreement"].bind(MonitorResourceUtil);
107
+
108
+ type MakeMonitor = (minimumProbeAgreement?: number) => Monitor;
109
+
110
+ const makeMonitor: MakeMonitor = (minimumProbeAgreement?: number): Monitor => {
111
+ const monitor: Monitor = new Monitor();
112
+ monitor.id = ObjectID.generate();
113
+ if (minimumProbeAgreement !== undefined) {
114
+ monitor.minimumProbeAgreement = minimumProbeAgreement;
115
+ }
116
+ return monitor;
117
+ };
118
+
119
+ /*
120
+ * The mocked evaluator returns whatever criteria id the probe response
121
+ * carries in its `testCriteriaId` marker — so each probe row fully
122
+ * determines its own evaluation outcome.
123
+ */
124
+ type MakeProbeResponse = (
125
+ testCriteriaId: string | undefined,
126
+ testRootCause?: string,
127
+ ) => ProbeMonitorResponse;
128
+
129
+ const makeProbeResponse: MakeProbeResponse = (
130
+ testCriteriaId: string | undefined,
131
+ testRootCause?: string,
132
+ ): ProbeMonitorResponse => {
133
+ return {
134
+ testCriteriaId: testCriteriaId,
135
+ testRootCause: testRootCause || null,
136
+ } as unknown as ProbeMonitorResponse;
137
+ };
138
+
139
+ type MakeMonitorProbe = (input: {
140
+ probeName: string;
141
+ isEnabled: boolean;
142
+ connectionStatus: ProbeConnectionStatus | undefined;
143
+ lastMonitoringLog?: MonitorStepProbeResponse | undefined;
144
+ }) => MonitorProbe;
145
+
146
+ const makeMonitorProbe: MakeMonitorProbe = (input: {
147
+ probeName: string;
148
+ isEnabled: boolean;
149
+ connectionStatus: ProbeConnectionStatus | undefined;
150
+ lastMonitoringLog?: MonitorStepProbeResponse | undefined;
151
+ }): MonitorProbe => {
152
+ const probe: Probe = new Probe();
153
+ probe.name = input.probeName;
154
+ if (input.connectionStatus !== undefined) {
155
+ probe.connectionStatus = input.connectionStatus;
156
+ }
157
+
158
+ const monitorProbe: MonitorProbe = new MonitorProbe();
159
+ monitorProbe.id = ObjectID.generate();
160
+ monitorProbe.probeId = ObjectID.generate();
161
+ monitorProbe.isEnabled = input.isEnabled;
162
+ monitorProbe.probe = probe;
163
+ if (input.lastMonitoringLog !== undefined) {
164
+ monitorProbe.lastMonitoringLog = input.lastMonitoringLog;
165
+ }
166
+ return monitorProbe;
167
+ };
168
+
169
+ describe("MonitorResourceUtil.checkProbeAgreement pre-fetched row reuse", () => {
170
+ let monitorStep: MonitorStep;
171
+ let stepId: string;
172
+
173
+ beforeEach(() => {
174
+ jest.clearAllMocks();
175
+
176
+ monitorStep = new MonitorStep();
177
+ stepId = monitorStep.id.toString();
178
+
179
+ processMonitorStepMock.mockImplementation(
180
+ (input: {
181
+ dataToProcess: DataToProcess;
182
+ monitor: Monitor;
183
+ }): Promise<ProbeApiIngestResponse> => {
184
+ return Promise.resolve({
185
+ monitorId: input.monitor.id!,
186
+ criteriaMetId: (input.dataToProcess as any).testCriteriaId,
187
+ rootCause: (input.dataToProcess as any).testRootCause || null,
188
+ });
189
+ },
190
+ );
191
+ });
192
+
193
+ describe("monitorProbes provided (hot path)", () => {
194
+ test("never queries MonitorProbeService.findBy and computes agreement from the provided rows", async () => {
195
+ const monitor: Monitor = makeMonitor();
196
+
197
+ const probeA: MonitorProbe = makeMonitorProbe({
198
+ probeName: "Probe A",
199
+ isEnabled: true,
200
+ connectionStatus: ProbeConnectionStatus.Connected,
201
+ lastMonitoringLog: {
202
+ [stepId]: makeProbeResponse("criteria-c", "root cause C"),
203
+ },
204
+ });
205
+ const probeB: MonitorProbe = makeMonitorProbe({
206
+ probeName: "Probe B",
207
+ isEnabled: true,
208
+ connectionStatus: ProbeConnectionStatus.Connected,
209
+ lastMonitoringLog: {
210
+ [stepId]: makeProbeResponse("criteria-c", "root cause C"),
211
+ },
212
+ });
213
+
214
+ const result: ProbeAgreementResult = await checkProbeAgreement({
215
+ monitor: monitor,
216
+ monitorStep: monitorStep,
217
+ currentCriteriaMetId: "criteria-c",
218
+ currentRootCause: "root cause C",
219
+ monitorProbes: [probeA, probeB],
220
+ });
221
+
222
+ expect(findByMock).not.toHaveBeenCalled();
223
+ // Both provided rows were evaluated — result came from them.
224
+ expect(processMonitorStepMock).toHaveBeenCalledTimes(2);
225
+ expect(result.hasAgreement).toBe(true);
226
+ expect(result.agreementCount).toBe(2);
227
+ expect(result.totalActiveProbes).toBe(2);
228
+ });
229
+
230
+ test("a provided EMPTY array still short-circuits the query ([] is truthy)", async () => {
231
+ const monitor: Monitor = makeMonitor();
232
+
233
+ const result: ProbeAgreementResult = await checkProbeAgreement({
234
+ monitor: monitor,
235
+ monitorStep: monitorStep,
236
+ currentCriteriaMetId: "current-criteria",
237
+ currentRootCause: "current root cause",
238
+ monitorProbes: [],
239
+ });
240
+
241
+ expect(findByMock).not.toHaveBeenCalled();
242
+ expect(result.hasAgreement).toBe(true);
243
+ expect(result.agreementCount).toBe(0);
244
+ });
245
+
246
+ test("both probes agreeing on the same criteria wins with both probe names", async () => {
247
+ const monitor: Monitor = makeMonitor();
248
+
249
+ const probeA: MonitorProbe = makeMonitorProbe({
250
+ probeName: "Probe A",
251
+ isEnabled: true,
252
+ connectionStatus: ProbeConnectionStatus.Connected,
253
+ lastMonitoringLog: {
254
+ [stepId]: makeProbeResponse("criteria-c", "root cause C"),
255
+ },
256
+ });
257
+ const probeB: MonitorProbe = makeMonitorProbe({
258
+ probeName: "Probe B",
259
+ isEnabled: true,
260
+ connectionStatus: ProbeConnectionStatus.Connected,
261
+ lastMonitoringLog: {
262
+ [stepId]: makeProbeResponse("criteria-c", "root cause C"),
263
+ },
264
+ });
265
+
266
+ const result: ProbeAgreementResult = await checkProbeAgreement({
267
+ monitor: monitor,
268
+ monitorStep: monitorStep,
269
+ currentCriteriaMetId: null,
270
+ currentRootCause: null,
271
+ monitorProbes: [probeA, probeB],
272
+ });
273
+
274
+ expect(result.hasAgreement).toBe(true);
275
+ expect(result.agreementCount).toBe(2);
276
+ expect(result.requiredCount).toBe(2);
277
+ expect(result.totalActiveProbes).toBe(2);
278
+ expect(result.agreedCriteriaId).toBe("criteria-c");
279
+ expect(result.agreedRootCause).toBe("root cause C");
280
+ expect([...result.agreedProbeNames].sort()).toEqual([
281
+ "Probe A",
282
+ "Probe B",
283
+ ]);
284
+ });
285
+
286
+ test("minimumProbeAgreement not reached: split criteria yields no agreement and empty names", async () => {
287
+ // 3 active probes, threshold 2, each evaluating to a DIFFERENT criteria.
288
+ const monitor: Monitor = makeMonitor(2);
289
+
290
+ const probes: Array<MonitorProbe> = ["c-1", "c-2", "c-3"].map(
291
+ (criteriaId: string, index: number): MonitorProbe => {
292
+ return makeMonitorProbe({
293
+ probeName: `Probe ${index + 1}`,
294
+ isEnabled: true,
295
+ connectionStatus: ProbeConnectionStatus.Connected,
296
+ lastMonitoringLog: {
297
+ [stepId]: makeProbeResponse(criteriaId),
298
+ },
299
+ });
300
+ },
301
+ );
302
+
303
+ const result: ProbeAgreementResult = await checkProbeAgreement({
304
+ monitor: monitor,
305
+ monitorStep: monitorStep,
306
+ currentCriteriaMetId: "c-1",
307
+ currentRootCause: "root cause 1",
308
+ monitorProbes: probes,
309
+ });
310
+
311
+ expect(findByMock).not.toHaveBeenCalled();
312
+ expect(result.hasAgreement).toBe(false);
313
+ expect(result.agreementCount).toBe(1);
314
+ expect(result.requiredCount).toBe(2);
315
+ expect(result.totalActiveProbes).toBe(3);
316
+ expect(result.agreedCriteriaId).toBeNull();
317
+ expect(result.agreedRootCause).toBeNull();
318
+ expect(result.agreedProbeNames).toEqual([]);
319
+ });
320
+
321
+ test("disabled and disconnected probes are excluded from active probes", async () => {
322
+ const monitor: Monitor = makeMonitor();
323
+
324
+ const activeProbe: MonitorProbe = makeMonitorProbe({
325
+ probeName: "Active Probe",
326
+ isEnabled: true,
327
+ connectionStatus: ProbeConnectionStatus.Connected,
328
+ lastMonitoringLog: {
329
+ [stepId]: makeProbeResponse("criteria-c", "root cause C"),
330
+ },
331
+ });
332
+ const disabledProbe: MonitorProbe = makeMonitorProbe({
333
+ probeName: "Disabled Probe",
334
+ isEnabled: false,
335
+ connectionStatus: ProbeConnectionStatus.Connected,
336
+ lastMonitoringLog: {
337
+ [stepId]: makeProbeResponse("other-criteria"),
338
+ },
339
+ });
340
+ const disconnectedProbe: MonitorProbe = makeMonitorProbe({
341
+ probeName: "Disconnected Probe",
342
+ isEnabled: true,
343
+ connectionStatus: ProbeConnectionStatus.Disconnected,
344
+ lastMonitoringLog: {
345
+ [stepId]: makeProbeResponse("other-criteria"),
346
+ },
347
+ });
348
+
349
+ const result: ProbeAgreementResult = await checkProbeAgreement({
350
+ monitor: monitor,
351
+ monitorStep: monitorStep,
352
+ currentCriteriaMetId: null,
353
+ currentRootCause: null,
354
+ monitorProbes: [activeProbe, disabledProbe, disconnectedProbe],
355
+ });
356
+
357
+ // Only the enabled+connected probe counts — and only it is evaluated.
358
+ expect(result.totalActiveProbes).toBe(1);
359
+ expect(processMonitorStepMock).toHaveBeenCalledTimes(1);
360
+ expect(result.hasAgreement).toBe(true);
361
+ expect(result.agreementCount).toBe(1);
362
+ expect(result.agreedProbeNames).toEqual(["Active Probe"]);
363
+ });
364
+
365
+ test("no active probes passes the CURRENT criteria and root cause through as agreement", async () => {
366
+ const monitor: Monitor = makeMonitor();
367
+
368
+ const disabledProbe: MonitorProbe = makeMonitorProbe({
369
+ probeName: "Disabled Probe",
370
+ isEnabled: false,
371
+ connectionStatus: ProbeConnectionStatus.Connected,
372
+ lastMonitoringLog: {
373
+ [stepId]: makeProbeResponse("other-criteria"),
374
+ },
375
+ });
376
+
377
+ const result: ProbeAgreementResult = await checkProbeAgreement({
378
+ monitor: monitor,
379
+ monitorStep: monitorStep,
380
+ currentCriteriaMetId: "current-criteria",
381
+ currentRootCause: "current root cause",
382
+ monitorProbes: [disabledProbe],
383
+ });
384
+
385
+ expect(findByMock).not.toHaveBeenCalled();
386
+ expect(processMonitorStepMock).not.toHaveBeenCalled();
387
+ expect(result).toEqual({
388
+ hasAgreement: true,
389
+ agreementCount: 0,
390
+ requiredCount: 0,
391
+ totalActiveProbes: 0,
392
+ agreedCriteriaId: "current-criteria",
393
+ agreedRootCause: "current root cause",
394
+ agreedProbeNames: [],
395
+ });
396
+ });
397
+
398
+ test("an active probe with no lastMonitoringLog entry for the step is skipped", async () => {
399
+ // No minimumProbeAgreement → required = number of ACTIVE probes (2).
400
+ const monitor: Monitor = makeMonitor();
401
+
402
+ const respondedProbe: MonitorProbe = makeMonitorProbe({
403
+ probeName: "Responded Probe",
404
+ isEnabled: true,
405
+ connectionStatus: ProbeConnectionStatus.Connected,
406
+ lastMonitoringLog: {
407
+ [stepId]: makeProbeResponse("criteria-c"),
408
+ },
409
+ });
410
+ const silentProbe: MonitorProbe = makeMonitorProbe({
411
+ probeName: "Silent Probe",
412
+ isEnabled: true,
413
+ connectionStatus: ProbeConnectionStatus.Connected,
414
+ // Log exists but for a DIFFERENT step id — must not count.
415
+ lastMonitoringLog: {
416
+ [ObjectID.generate().toString()]: makeProbeResponse("criteria-c"),
417
+ },
418
+ });
419
+
420
+ const result: ProbeAgreementResult = await checkProbeAgreement({
421
+ monitor: monitor,
422
+ monitorStep: monitorStep,
423
+ currentCriteriaMetId: null,
424
+ currentRootCause: null,
425
+ monitorProbes: [respondedProbe, silentProbe],
426
+ });
427
+
428
+ /*
429
+ * The silent probe is still ACTIVE (it raises the bar) but is never
430
+ * evaluated and never counts toward agreement.
431
+ */
432
+ expect(result.totalActiveProbes).toBe(2);
433
+ expect(processMonitorStepMock).toHaveBeenCalledTimes(1);
434
+ expect(result.agreementCount).toBe(1);
435
+ expect(result.requiredCount).toBe(2);
436
+ expect(result.hasAgreement).toBe(false);
437
+ expect(result.agreedProbeNames).toEqual([]);
438
+ });
439
+ });
440
+
441
+ describe("monitorProbes absent (fallback path)", () => {
442
+ test("falls back to exactly one findBy with the original query and select", async () => {
443
+ const monitor: Monitor = makeMonitor();
444
+
445
+ const probeA: MonitorProbe = makeMonitorProbe({
446
+ probeName: "Probe A",
447
+ isEnabled: true,
448
+ connectionStatus: ProbeConnectionStatus.Connected,
449
+ lastMonitoringLog: {
450
+ [stepId]: makeProbeResponse("criteria-c", "root cause C"),
451
+ },
452
+ });
453
+
454
+ findByMock.mockResolvedValue([probeA]);
455
+
456
+ const result: ProbeAgreementResult = await checkProbeAgreement({
457
+ monitor: monitor,
458
+ monitorStep: monitorStep,
459
+ currentCriteriaMetId: null,
460
+ currentRootCause: null,
461
+ });
462
+
463
+ expect(findByMock).toHaveBeenCalledTimes(1);
464
+ expect(findByMock).toHaveBeenCalledWith({
465
+ query: {
466
+ monitorId: monitor.id!,
467
+ },
468
+ select: {
469
+ probeId: true,
470
+ isEnabled: true,
471
+ lastMonitoringLog: true,
472
+ probe: {
473
+ connectionStatus: true,
474
+ name: true,
475
+ },
476
+ },
477
+ limit: LIMIT_PER_PROJECT,
478
+ skip: 0,
479
+ props: {
480
+ isRoot: true,
481
+ },
482
+ });
483
+
484
+ // And the queried rows drive the result.
485
+ expect(result.hasAgreement).toBe(true);
486
+ expect(result.agreementCount).toBe(1);
487
+ expect(result.agreedCriteriaId).toBe("criteria-c");
488
+ expect(result.agreedRootCause).toBe("root cause C");
489
+ expect(result.agreedProbeNames).toEqual(["Probe A"]);
490
+ });
491
+ });
492
+ });