@oneuptime/common 10.0.39 → 10.0.41

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/Index.ts +4 -0
  2. package/Models/AnalyticsModels/Profile.ts +687 -0
  3. package/Models/AnalyticsModels/ProfileSample.ts +547 -0
  4. package/Models/DatabaseModels/Dashboard.ts +357 -0
  5. package/Models/DatabaseModels/DashboardDomain.ts +658 -0
  6. package/Models/DatabaseModels/Index.ts +2 -0
  7. package/Models/DatabaseModels/StatusPage.ts +41 -0
  8. package/Server/API/DashboardAPI.ts +408 -0
  9. package/Server/API/DashboardDomainAPI.ts +235 -0
  10. package/Server/API/StatusPageAPI.ts +36 -2
  11. package/Server/API/TelemetryAPI.ts +393 -0
  12. package/Server/EnvironmentConfig.ts +12 -0
  13. package/Server/Infrastructure/Postgres/SchemaMigrations/1774524742177-MigrationName.ts +97 -0
  14. package/Server/Infrastructure/Postgres/SchemaMigrations/1774524742178-MigrationName.ts +17 -0
  15. package/Server/Infrastructure/Postgres/SchemaMigrations/1774524742179-MigrationName.ts +50 -0
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/1774559064919-MigrationName.ts +59 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
  18. package/Server/Middleware/UserAuthorization.ts +96 -1
  19. package/Server/Services/DashboardDomainService.ts +647 -0
  20. package/Server/Services/DashboardService.ts +174 -3
  21. package/Server/Services/IncidentService.ts +295 -50
  22. package/Server/Services/IncidentStateTimelineService.ts +1 -0
  23. package/Server/Services/Index.ts +6 -0
  24. package/Server/Services/MonitorService.ts +5 -0
  25. package/Server/Services/ProfileAggregationService.ts +559 -0
  26. package/Server/Services/ProfileSampleService.ts +11 -0
  27. package/Server/Services/ProfileService.ts +11 -0
  28. package/Server/Services/TelemetryUsageBillingService.ts +77 -3
  29. package/Server/Services/WorkspaceNotificationSummaryService.ts +15 -1
  30. package/Server/Types/Billing/MeteredPlan/AllMeteredPlans.ts +9 -0
  31. package/Server/Utils/Cookie.ts +48 -0
  32. package/Server/Utils/Monitor/Criteria/ProfileMonitorCriteria.ts +34 -0
  33. package/Server/Utils/Monitor/DataToProcess.ts +3 -1
  34. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +299 -0
  35. package/Server/Utils/Profile/PprofEncoder.ts +225 -0
  36. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +53 -16
  37. package/Server/Utils/Workspace/Slack/Slack.ts +26 -6
  38. package/ServiceRoute.ts +2 -0
  39. package/Tests/UI/Components/ComponentsModal.test.tsx +19 -15
  40. package/Types/AnalyticsDatabase/AnalyticsTableName.ts +2 -0
  41. package/Types/CookieName.ts +1 -0
  42. package/Types/Dashboard/Chart/ChartType.ts +5 -0
  43. package/Types/Dashboard/DashboardComponentType.ts +4 -0
  44. package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +10 -0
  45. package/Types/Dashboard/DashboardComponents/DashboardChartComponent.ts +1 -2
  46. package/Types/Dashboard/DashboardComponents/DashboardGaugeComponent.ts +17 -0
  47. package/Types/Dashboard/DashboardComponents/DashboardLogStreamComponent.ts +15 -0
  48. package/Types/Dashboard/DashboardComponents/DashboardTableComponent.ts +14 -0
  49. package/Types/Dashboard/DashboardComponents/DashboardTextComponent.ts +1 -0
  50. package/Types/Dashboard/DashboardComponents/DashboardTraceListComponent.ts +13 -0
  51. package/Types/Dashboard/DashboardComponents/DashboardValueComponent.ts +2 -0
  52. package/Types/Dashboard/DashboardTemplates.ts +964 -0
  53. package/Types/Dashboard/DashboardVariable.ts +23 -0
  54. package/Types/Dashboard/DashboardViewConfig.ts +59 -0
  55. package/Types/Dashboard/MasterPassword.ts +10 -0
  56. package/Types/Icon/IconProp.ts +1 -0
  57. package/Types/Incident/IncidentMetricType.ts +3 -0
  58. package/Types/MeteredPlan/ProductType.ts +1 -0
  59. package/Types/Metrics/MetricQueryConfigData.ts +3 -0
  60. package/Types/Monitor/CriteriaFilter.ts +3 -0
  61. package/Types/Monitor/KubernetesAlertTemplates.ts +78 -7
  62. package/Types/Monitor/MetricMonitor/MetricMonitorResponse.ts +20 -0
  63. package/Types/Monitor/MonitorStep.ts +25 -0
  64. package/Types/Monitor/MonitorStepProfileMonitor.ts +96 -0
  65. package/Types/Monitor/MonitorType.ts +11 -0
  66. package/Types/Monitor/ProfileMonitor/ProfileMonitorResponse.ts +12 -0
  67. package/Types/Permission.ts +87 -0
  68. package/Types/Telemetry/TelemetryType.ts +1 -0
  69. package/Types/Workspace/NotificationSummary/WorkspaceNotificationSummaryItem.ts +1 -0
  70. package/UI/Components/Button/Button.tsx +1 -1
  71. package/UI/Components/Card/Card.tsx +8 -4
  72. package/UI/Components/Charts/Area/AreaChart.tsx +4 -0
  73. package/UI/Components/Charts/Bar/BarChart.tsx +4 -0
  74. package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +26 -0
  75. package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +26 -0
  76. package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +26 -0
  77. package/UI/Components/Charts/Line/LineChart.tsx +4 -0
  78. package/UI/Components/Charts/Types/ReferenceLineProps.ts +6 -0
  79. package/UI/Components/Icon/Icon.tsx +33 -0
  80. package/UI/Components/ModelTable/BaseModelTable.tsx +13 -10
  81. package/UI/Components/MoreMenu/MoreMenu.tsx +15 -2
  82. package/UI/Components/MoreMenu/MoreMenuItem.tsx +4 -4
  83. package/UI/Components/Workflow/Component.tsx +450 -209
  84. package/UI/Components/Workflow/ComponentPortViewer.tsx +57 -20
  85. package/UI/Components/Workflow/ComponentReturnValueViewer.tsx +65 -25
  86. package/UI/Components/Workflow/ComponentSettingsModal.tsx +202 -37
  87. package/UI/Components/Workflow/ComponentsModal.tsx +180 -93
  88. package/UI/Components/Workflow/Workflow.tsx +105 -9
  89. package/UI/Config.ts +9 -0
  90. package/Utils/Dashboard/Components/DashboardChartComponent.ts +53 -22
  91. package/Utils/Dashboard/Components/DashboardGaugeComponent.ts +124 -0
  92. package/Utils/Dashboard/Components/DashboardLogStreamComponent.ts +110 -0
  93. package/Utils/Dashboard/Components/DashboardTableComponent.ts +86 -0
  94. package/Utils/Dashboard/Components/DashboardTextComponent.ts +32 -7
  95. package/Utils/Dashboard/Components/DashboardTraceListComponent.ts +86 -0
  96. package/Utils/Dashboard/Components/DashboardValueComponent.ts +39 -3
  97. package/Utils/Dashboard/Components/Index.ts +28 -0
  98. package/Utils/ValueFormatter.ts +170 -0
  99. package/build/dist/Models/AnalyticsModels/Index.js +4 -0
  100. package/build/dist/Models/AnalyticsModels/Index.js.map +1 -1
  101. package/build/dist/Models/AnalyticsModels/Profile.js +621 -0
  102. package/build/dist/Models/AnalyticsModels/Profile.js.map +1 -0
  103. package/build/dist/Models/AnalyticsModels/ProfileSample.js +497 -0
  104. package/build/dist/Models/AnalyticsModels/ProfileSample.js.map +1 -0
  105. package/build/dist/Models/DatabaseModels/Dashboard.js +365 -0
  106. package/build/dist/Models/DatabaseModels/Dashboard.js.map +1 -1
  107. package/build/dist/Models/DatabaseModels/DashboardDomain.js +691 -0
  108. package/build/dist/Models/DatabaseModels/DashboardDomain.js.map +1 -0
  109. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  110. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  111. package/build/dist/Models/DatabaseModels/StatusPage.js +42 -0
  112. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  113. package/build/dist/Server/API/DashboardAPI.js +293 -0
  114. package/build/dist/Server/API/DashboardAPI.js.map +1 -0
  115. package/build/dist/Server/API/DashboardDomainAPI.js +124 -0
  116. package/build/dist/Server/API/DashboardDomainAPI.js.map +1 -0
  117. package/build/dist/Server/API/StatusPageAPI.js +26 -2
  118. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  119. package/build/dist/Server/API/TelemetryAPI.js +222 -0
  120. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  121. package/build/dist/Server/EnvironmentConfig.js +4 -0
  122. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  123. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1774524742177-MigrationName.js +40 -0
  124. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1774524742177-MigrationName.js.map +1 -0
  125. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1774524742178-MigrationName.js +12 -0
  126. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1774524742178-MigrationName.js.map +1 -0
  127. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1774524742179-MigrationName.js +23 -0
  128. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1774524742179-MigrationName.js.map +1 -0
  129. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1774559064919-MigrationName.js +26 -0
  130. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1774559064919-MigrationName.js.map +1 -0
  131. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
  132. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  133. package/build/dist/Server/Middleware/UserAuthorization.js +41 -0
  134. package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
  135. package/build/dist/Server/Services/DashboardDomainService.js +595 -0
  136. package/build/dist/Server/Services/DashboardDomainService.js.map +1 -0
  137. package/build/dist/Server/Services/DashboardService.js +117 -3
  138. package/build/dist/Server/Services/DashboardService.js.map +1 -1
  139. package/build/dist/Server/Services/IncidentService.js +231 -55
  140. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  141. package/build/dist/Server/Services/IncidentStateTimelineService.js +1 -1
  142. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  143. package/build/dist/Server/Services/Index.js +6 -0
  144. package/build/dist/Server/Services/Index.js.map +1 -1
  145. package/build/dist/Server/Services/MonitorService.js +5 -2
  146. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  147. package/build/dist/Server/Services/ProfileAggregationService.js +356 -0
  148. package/build/dist/Server/Services/ProfileAggregationService.js.map +1 -0
  149. package/build/dist/Server/Services/ProfileSampleService.js +9 -0
  150. package/build/dist/Server/Services/ProfileSampleService.js.map +1 -0
  151. package/build/dist/Server/Services/ProfileService.js +9 -0
  152. package/build/dist/Server/Services/ProfileService.js.map +1 -0
  153. package/build/dist/Server/Services/TelemetryUsageBillingService.js +61 -4
  154. package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
  155. package/build/dist/Server/Services/WorkspaceNotificationSummaryService.js +13 -1
  156. package/build/dist/Server/Services/WorkspaceNotificationSummaryService.js.map +1 -1
  157. package/build/dist/Server/Types/Billing/MeteredPlan/AllMeteredPlans.js +8 -0
  158. package/build/dist/Server/Types/Billing/MeteredPlan/AllMeteredPlans.js.map +1 -1
  159. package/build/dist/Server/Utils/Cookie.js +36 -0
  160. package/build/dist/Server/Utils/Cookie.js.map +1 -1
  161. package/build/dist/Server/Utils/Monitor/Criteria/ProfileMonitorCriteria.js +34 -0
  162. package/build/dist/Server/Utils/Monitor/Criteria/ProfileMonitorCriteria.js.map +1 -0
  163. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +173 -0
  164. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  165. package/build/dist/Server/Utils/Profile/PprofEncoder.js +129 -0
  166. package/build/dist/Server/Utils/Profile/PprofEncoder.js.map +1 -0
  167. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +36 -14
  168. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  169. package/build/dist/Server/Utils/Workspace/Slack/Slack.js +23 -6
  170. package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
  171. package/build/dist/ServiceRoute.js +1 -0
  172. package/build/dist/ServiceRoute.js.map +1 -1
  173. package/build/dist/Tests/UI/Components/ComponentsModal.test.js +15 -15
  174. package/build/dist/Tests/UI/Components/ComponentsModal.test.js.map +1 -1
  175. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js +2 -0
  176. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js.map +1 -1
  177. package/build/dist/Types/CookieName.js +1 -0
  178. package/build/dist/Types/CookieName.js.map +1 -1
  179. package/build/dist/Types/Dashboard/Chart/ChartType.js +5 -0
  180. package/build/dist/Types/Dashboard/Chart/ChartType.js.map +1 -1
  181. package/build/dist/Types/Dashboard/DashboardComponentType.js +4 -0
  182. package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
  183. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +1 -0
  184. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
  185. package/build/dist/Types/Dashboard/DashboardComponents/DashboardGaugeComponent.js +2 -0
  186. package/build/dist/Types/Dashboard/DashboardComponents/DashboardGaugeComponent.js.map +1 -0
  187. package/build/dist/Types/Dashboard/DashboardComponents/DashboardLogStreamComponent.js +2 -0
  188. package/build/dist/Types/Dashboard/DashboardComponents/DashboardLogStreamComponent.js.map +1 -0
  189. package/build/dist/Types/Dashboard/DashboardComponents/DashboardTableComponent.js +2 -0
  190. package/build/dist/Types/Dashboard/DashboardComponents/DashboardTableComponent.js.map +1 -0
  191. package/build/dist/Types/Dashboard/DashboardComponents/DashboardTraceListComponent.js +2 -0
  192. package/build/dist/Types/Dashboard/DashboardComponents/DashboardTraceListComponent.js.map +1 -0
  193. package/build/dist/Types/Dashboard/DashboardTemplates.js +853 -0
  194. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -0
  195. package/build/dist/Types/Dashboard/DashboardVariable.js +7 -0
  196. package/build/dist/Types/Dashboard/DashboardVariable.js.map +1 -0
  197. package/build/dist/Types/Dashboard/DashboardViewConfig.js +50 -1
  198. package/build/dist/Types/Dashboard/DashboardViewConfig.js.map +1 -1
  199. package/build/dist/Types/Dashboard/MasterPassword.js +5 -0
  200. package/build/dist/Types/Dashboard/MasterPassword.js.map +1 -0
  201. package/build/dist/Types/Icon/IconProp.js +1 -0
  202. package/build/dist/Types/Icon/IconProp.js.map +1 -1
  203. package/build/dist/Types/Incident/IncidentMetricType.js +3 -0
  204. package/build/dist/Types/Incident/IncidentMetricType.js.map +1 -1
  205. package/build/dist/Types/MeteredPlan/ProductType.js +1 -0
  206. package/build/dist/Types/MeteredPlan/ProductType.js.map +1 -1
  207. package/build/dist/Types/Metrics/MetricQueryConfigData.js +1 -0
  208. package/build/dist/Types/Metrics/MetricQueryConfigData.js.map +1 -1
  209. package/build/dist/Types/Monitor/CriteriaFilter.js +2 -0
  210. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  211. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +58 -7
  212. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
  213. package/build/dist/Types/Monitor/MonitorStep.js +15 -0
  214. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  215. package/build/dist/Types/Monitor/MonitorStepProfileMonitor.js +59 -0
  216. package/build/dist/Types/Monitor/MonitorStepProfileMonitor.js.map +1 -0
  217. package/build/dist/Types/Monitor/MonitorType.js +10 -0
  218. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  219. package/build/dist/Types/Monitor/ProfileMonitor/ProfileMonitorResponse.js +2 -0
  220. package/build/dist/Types/Monitor/ProfileMonitor/ProfileMonitorResponse.js.map +1 -0
  221. package/build/dist/Types/Permission.js +75 -0
  222. package/build/dist/Types/Permission.js.map +1 -1
  223. package/build/dist/Types/Telemetry/TelemetryType.js +1 -0
  224. package/build/dist/Types/Telemetry/TelemetryType.js.map +1 -1
  225. package/build/dist/Types/Workspace/NotificationSummary/WorkspaceNotificationSummaryItem.js +1 -0
  226. package/build/dist/Types/Workspace/NotificationSummary/WorkspaceNotificationSummaryItem.js.map +1 -1
  227. package/build/dist/UI/Components/Button/Button.js +1 -1
  228. package/build/dist/UI/Components/Button/Button.js.map +1 -1
  229. package/build/dist/UI/Components/Card/Card.js +4 -4
  230. package/build/dist/UI/Components/Card/Card.js.map +1 -1
  231. package/build/dist/UI/Components/Charts/Area/AreaChart.js +1 -1
  232. package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
  233. package/build/dist/UI/Components/Charts/Bar/BarChart.js +1 -1
  234. package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
  235. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +5 -2
  236. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
  237. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +5 -2
  238. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
  239. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +6 -3
  240. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
  241. package/build/dist/UI/Components/Charts/Line/LineChart.js +1 -1
  242. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  243. package/build/dist/UI/Components/Charts/Types/ReferenceLineProps.js +2 -0
  244. package/build/dist/UI/Components/Charts/Types/ReferenceLineProps.js.map +1 -0
  245. package/build/dist/UI/Components/Icon/Icon.js +11 -0
  246. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  247. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +12 -9
  248. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  249. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +8 -2
  250. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  251. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +4 -4
  252. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
  253. package/build/dist/UI/Components/Workflow/Component.js +311 -143
  254. package/build/dist/UI/Components/Workflow/Component.js.map +1 -1
  255. package/build/dist/UI/Components/Workflow/ComponentPortViewer.js +44 -18
  256. package/build/dist/UI/Components/Workflow/ComponentPortViewer.js.map +1 -1
  257. package/build/dist/UI/Components/Workflow/ComponentReturnValueViewer.js +48 -22
  258. package/build/dist/UI/Components/Workflow/ComponentReturnValueViewer.js.map +1 -1
  259. package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js +127 -21
  260. package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js.map +1 -1
  261. package/build/dist/UI/Components/Workflow/ComponentsModal.js +107 -52
  262. package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
  263. package/build/dist/UI/Components/Workflow/Workflow.js +87 -12
  264. package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
  265. package/build/dist/UI/Config.js +3 -1
  266. package/build/dist/UI/Config.js.map +1 -1
  267. package/build/dist/Utils/Dashboard/Components/DashboardChartComponent.js +50 -21
  268. package/build/dist/Utils/Dashboard/Components/DashboardChartComponent.js.map +1 -1
  269. package/build/dist/Utils/Dashboard/Components/DashboardGaugeComponent.js +104 -0
  270. package/build/dist/Utils/Dashboard/Components/DashboardGaugeComponent.js.map +1 -0
  271. package/build/dist/Utils/Dashboard/Components/DashboardLogStreamComponent.js +91 -0
  272. package/build/dist/Utils/Dashboard/Components/DashboardLogStreamComponent.js.map +1 -0
  273. package/build/dist/Utils/Dashboard/Components/DashboardTableComponent.js +70 -0
  274. package/build/dist/Utils/Dashboard/Components/DashboardTableComponent.js.map +1 -0
  275. package/build/dist/Utils/Dashboard/Components/DashboardTextComponent.js +28 -7
  276. package/build/dist/Utils/Dashboard/Components/DashboardTextComponent.js.map +1 -1
  277. package/build/dist/Utils/Dashboard/Components/DashboardTraceListComponent.js +70 -0
  278. package/build/dist/Utils/Dashboard/Components/DashboardTraceListComponent.js.map +1 -0
  279. package/build/dist/Utils/Dashboard/Components/DashboardValueComponent.js +34 -3
  280. package/build/dist/Utils/Dashboard/Components/DashboardValueComponent.js.map +1 -1
  281. package/build/dist/Utils/Dashboard/Components/Index.js +16 -0
  282. package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
  283. package/build/dist/Utils/ValueFormatter.js +132 -0
  284. package/build/dist/Utils/ValueFormatter.js.map +1 -0
  285. package/package.json +1 -1
@@ -1,12 +1,27 @@
1
1
  import CreateBy from "../Types/Database/CreateBy";
2
2
  import { OnCreate } from "../Types/Database/Hooks";
3
+ import CookieUtil from "../Utils/Cookie";
4
+ import { ExpressRequest } from "../Utils/Express";
5
+ import JSONWebToken from "../Utils/JsonWebToken";
6
+ import logger from "../Utils/Logger";
3
7
  import DatabaseService from "./DatabaseService";
4
8
  import BadDataException from "../../Types/Exception/BadDataException";
9
+ import NotAuthenticatedException from "../../Types/Exception/NotAuthenticatedException";
10
+ import ForbiddenException from "../../Types/Exception/ForbiddenException";
11
+ import MasterPasswordRequiredException from "../../Types/Exception/MasterPasswordRequiredException";
5
12
  import Model from "../../Models/DatabaseModels/Dashboard";
6
13
  import { IsBillingEnabled } from "../EnvironmentConfig";
7
14
  import { PlanType } from "../../Types/Billing/SubscriptionPlan";
8
15
  import DashboardViewConfigUtil from "../../Utils/Dashboard/DashboardViewConfig";
9
16
  import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
17
+ import ObjectID from "../../Types/ObjectID";
18
+ import { JSONObject } from "../../Types/JSON";
19
+ import IP from "../../Types/IP/IP";
20
+ import {
21
+ DASHBOARD_MASTER_PASSWORD_COOKIE_IDENTIFIER,
22
+ DASHBOARD_MASTER_PASSWORD_REQUIRED_MESSAGE,
23
+ } from "../../Types/Dashboard/MasterPassword";
24
+
10
25
  export class Service extends DatabaseService<Model> {
11
26
  public constructor() {
12
27
  super(Model);
@@ -40,12 +55,168 @@ export class Service extends DatabaseService<Model> {
40
55
  }
41
56
  }
42
57
 
43
- // make sure dashboard config is empty.
44
- createBy.data.dashboardViewConfig =
45
- DashboardViewConfigUtil.createDefaultDashboardViewConfig();
58
+ // use default empty config only if no template config was provided.
59
+ if (
60
+ !createBy.data.dashboardViewConfig ||
61
+ !createBy.data.dashboardViewConfig.components ||
62
+ createBy.data.dashboardViewConfig.components.length === 0
63
+ ) {
64
+ createBy.data.dashboardViewConfig =
65
+ DashboardViewConfigUtil.createDefaultDashboardViewConfig();
66
+ }
46
67
 
47
68
  return Promise.resolve({ createBy, carryForward: null });
48
69
  }
70
+
71
+ public async hasReadAccess(data: {
72
+ dashboardId: ObjectID;
73
+ req: ExpressRequest;
74
+ }): Promise<{
75
+ hasReadAccess: boolean;
76
+ error?: NotAuthenticatedException | ForbiddenException;
77
+ }> {
78
+ const dashboardId: ObjectID = data.dashboardId;
79
+ const req: ExpressRequest = data.req;
80
+
81
+ try {
82
+ const dashboard: Model | null = await this.findOneById({
83
+ id: dashboardId,
84
+ props: {
85
+ isRoot: true,
86
+ },
87
+ select: {
88
+ _id: true,
89
+ isPublicDashboard: true,
90
+ ipWhitelist: true,
91
+ enableMasterPassword: true,
92
+ masterPassword: true,
93
+ },
94
+ });
95
+
96
+ // If dashboard is not public, deny access
97
+ if (dashboard && !dashboard.isPublicDashboard) {
98
+ return {
99
+ hasReadAccess: false,
100
+ error: new NotAuthenticatedException(
101
+ "This dashboard is not available.",
102
+ ),
103
+ };
104
+ }
105
+
106
+ if (dashboard?.ipWhitelist && dashboard.ipWhitelist.length > 0) {
107
+ const ipWhitelist: Array<string> = dashboard.ipWhitelist?.split("\n");
108
+
109
+ const ipAccessedFrom: string | undefined =
110
+ req.headers["x-forwarded-for"]?.toString() ||
111
+ req.headers["x-real-ip"]?.toString() ||
112
+ req.socket.remoteAddress ||
113
+ req.ip ||
114
+ req.ips[0];
115
+
116
+ if (!ipAccessedFrom) {
117
+ logger.error("IP address not found in request.");
118
+ return {
119
+ hasReadAccess: false,
120
+ error: new ForbiddenException(
121
+ "Unable to verify IP address for dashboard access.",
122
+ ),
123
+ };
124
+ }
125
+
126
+ const isIPWhitelisted: boolean = IP.isInWhitelist({
127
+ ips:
128
+ ipAccessedFrom?.split(",").map((i: string) => {
129
+ return i.trim();
130
+ }) || [],
131
+ whitelist: ipWhitelist,
132
+ });
133
+
134
+ if (!isIPWhitelisted) {
135
+ logger.error(
136
+ `IP address ${ipAccessedFrom} is not whitelisted for dashboard ${dashboardId.toString()}.`,
137
+ );
138
+
139
+ return {
140
+ hasReadAccess: false,
141
+ error: new ForbiddenException(
142
+ `Your IP address ${ipAccessedFrom} is blocked from accessing this dashboard.`,
143
+ ),
144
+ };
145
+ }
146
+ }
147
+
148
+ const shouldEnforceMasterPassword: boolean = Boolean(
149
+ dashboard &&
150
+ dashboard.isPublicDashboard &&
151
+ dashboard.enableMasterPassword &&
152
+ dashboard.masterPassword,
153
+ );
154
+
155
+ if (shouldEnforceMasterPassword) {
156
+ const hasValidMasterPassword: boolean =
157
+ this.hasValidMasterPasswordCookie({
158
+ req,
159
+ dashboardId,
160
+ });
161
+
162
+ if (hasValidMasterPassword) {
163
+ return {
164
+ hasReadAccess: true,
165
+ };
166
+ }
167
+
168
+ return {
169
+ hasReadAccess: false,
170
+ error: new MasterPasswordRequiredException(
171
+ DASHBOARD_MASTER_PASSWORD_REQUIRED_MESSAGE,
172
+ ),
173
+ };
174
+ }
175
+
176
+ // Public dashboard without master password - grant access
177
+ if (dashboard && dashboard.isPublicDashboard) {
178
+ return {
179
+ hasReadAccess: true,
180
+ };
181
+ }
182
+ } catch (err) {
183
+ logger.error(err);
184
+ }
185
+
186
+ return {
187
+ hasReadAccess: false,
188
+ error: new NotAuthenticatedException(
189
+ "You do not have access to this dashboard.",
190
+ ),
191
+ };
192
+ }
193
+
194
+ private hasValidMasterPasswordCookie(data: {
195
+ req: ExpressRequest;
196
+ dashboardId: ObjectID;
197
+ }): boolean {
198
+ const token: string | undefined = CookieUtil.getCookieFromExpressRequest(
199
+ data.req,
200
+ CookieUtil.getDashboardMasterPasswordKey(data.dashboardId),
201
+ );
202
+
203
+ if (!token) {
204
+ return false;
205
+ }
206
+
207
+ try {
208
+ const payload: JSONObject = JSONWebToken.decodeJsonPayload(token);
209
+
210
+ return (
211
+ payload["dashboardId"] === data.dashboardId.toString() &&
212
+ payload["type"] === DASHBOARD_MASTER_PASSWORD_COOKIE_IDENTIFIER
213
+ );
214
+ } catch (err) {
215
+ logger.error(err);
216
+ }
217
+
218
+ return false;
219
+ }
49
220
  }
50
221
 
51
222
  export default new Service();
@@ -1039,6 +1039,7 @@ ${incident.remediationNotes || "No remediation notes provided."}
1039
1039
  " was created.",
1040
1040
  createdItem.createdStateLog,
1041
1041
  onCreate.createBy.props,
1042
+ createdItem.declaredAt || undefined,
1042
1043
  );
1043
1044
  }
1044
1045
  } catch (error) {
@@ -1335,6 +1336,97 @@ ${incident.remediationNotes || "No remediation notes provided."}
1335
1336
  });
1336
1337
  }
1337
1338
 
1339
+ // emit postmortem completion time metric when postmortemPostedAt is set
1340
+ if (
1341
+ Object.prototype.hasOwnProperty.call(
1342
+ updatedIncidentData,
1343
+ "postmortemPostedAt",
1344
+ ) &&
1345
+ updatedIncidentData["postmortemPostedAt"]
1346
+ ) {
1347
+ try {
1348
+ const postmortemPostedAt: Date = updatedIncidentData[
1349
+ "postmortemPostedAt"
1350
+ ] as Date;
1351
+
1352
+ // find the resolved state timeline to calculate time from resolution to postmortem
1353
+ const resolvedStateId: ObjectID =
1354
+ await IncidentStateTimelineService.getResolvedStateIdForProject(
1355
+ projectId,
1356
+ );
1357
+
1358
+ const resolvedTimeline: IncidentStateTimeline | null =
1359
+ await IncidentStateTimelineService.findOneBy({
1360
+ query: {
1361
+ incidentId: incidentId,
1362
+ incidentStateId: resolvedStateId,
1363
+ },
1364
+ select: {
1365
+ startsAt: true,
1366
+ },
1367
+ sort: {
1368
+ startsAt: SortOrder.Descending,
1369
+ },
1370
+ props: {
1371
+ isRoot: true,
1372
+ },
1373
+ });
1374
+
1375
+ // only emit if the incident has been resolved
1376
+ if (resolvedTimeline && resolvedTimeline.startsAt) {
1377
+ const postmortemMetric: Metric = new Metric();
1378
+ postmortemMetric.projectId = projectId;
1379
+ postmortemMetric.serviceId = incidentId;
1380
+ postmortemMetric.serviceType = ServiceType.Incident;
1381
+ postmortemMetric.name =
1382
+ IncidentMetricType.PostmortemCompletionTime;
1383
+ postmortemMetric.value = OneUptimeDate.getDifferenceInSeconds(
1384
+ postmortemPostedAt,
1385
+ resolvedTimeline.startsAt,
1386
+ );
1387
+ postmortemMetric.attributes = {
1388
+ incidentId: incidentId.toString(),
1389
+ projectId: projectId.toString(),
1390
+ };
1391
+ postmortemMetric.attributeKeys = TelemetryUtil.getAttributeKeys(
1392
+ postmortemMetric.attributes,
1393
+ );
1394
+ postmortemMetric.time = postmortemPostedAt;
1395
+ postmortemMetric.timeUnixNano = OneUptimeDate.toUnixNano(
1396
+ postmortemMetric.time,
1397
+ );
1398
+ postmortemMetric.metricPointType = MetricPointType.Sum;
1399
+
1400
+ await MetricService.create({
1401
+ data: postmortemMetric,
1402
+ props: {
1403
+ isRoot: true,
1404
+ },
1405
+ });
1406
+
1407
+ const postmortemMetricType: MetricType = new MetricType();
1408
+ postmortemMetricType.name =
1409
+ IncidentMetricType.PostmortemCompletionTime;
1410
+ postmortemMetricType.description =
1411
+ "Time from incident resolution to postmortem publication";
1412
+ postmortemMetricType.unit = "seconds";
1413
+
1414
+ TelemetryUtil.indexMetricNameServiceNameMap({
1415
+ metricNameServiceNameMap: {
1416
+ [postmortemMetricType.name]: postmortemMetricType,
1417
+ },
1418
+ projectId: projectId,
1419
+ }).catch((err: Error) => {
1420
+ logger.error(err);
1421
+ });
1422
+ }
1423
+ } catch (metricError) {
1424
+ logger.error(
1425
+ `Failed to emit postmortem completion time metric: ${metricError}`,
1426
+ );
1427
+ }
1428
+ }
1429
+
1338
1430
  let shouldAddIncidentFeed: boolean = false;
1339
1431
  let feedInfoInMarkdown: string = `**[${incidentLabel}](${incidentLink.toString()}) was updated.**`;
1340
1432
 
@@ -1468,6 +1560,56 @@ ${incidentSeverity.name}
1468
1560
  `SLA recalculation failed in IncidentService.onUpdateSuccess: ${slaError}`,
1469
1561
  );
1470
1562
  }
1563
+
1564
+ // emit severity change metric
1565
+ try {
1566
+ const severityChangeMetric: Metric = new Metric();
1567
+ severityChangeMetric.projectId = projectId;
1568
+ severityChangeMetric.serviceId = incidentId;
1569
+ severityChangeMetric.serviceType = ServiceType.Incident;
1570
+ severityChangeMetric.name = IncidentMetricType.SeverityChange;
1571
+ severityChangeMetric.value = 1;
1572
+ severityChangeMetric.attributes = {
1573
+ incidentId: incidentId.toString(),
1574
+ projectId: projectId.toString(),
1575
+ newIncidentSeverityId: incidentSeverity._id?.toString() || "",
1576
+ newIncidentSeverityName:
1577
+ incidentSeverity.name?.toString() || "",
1578
+ };
1579
+ severityChangeMetric.attributeKeys =
1580
+ TelemetryUtil.getAttributeKeys(severityChangeMetric.attributes);
1581
+ severityChangeMetric.time = OneUptimeDate.getCurrentDate();
1582
+ severityChangeMetric.timeUnixNano = OneUptimeDate.toUnixNano(
1583
+ severityChangeMetric.time,
1584
+ );
1585
+ severityChangeMetric.metricPointType = MetricPointType.Sum;
1586
+
1587
+ await MetricService.create({
1588
+ data: severityChangeMetric,
1589
+ props: {
1590
+ isRoot: true,
1591
+ },
1592
+ });
1593
+
1594
+ const severityChangeMetricType: MetricType = new MetricType();
1595
+ severityChangeMetricType.name = IncidentMetricType.SeverityChange;
1596
+ severityChangeMetricType.description =
1597
+ "Count of incident severity changes";
1598
+ severityChangeMetricType.unit = "";
1599
+
1600
+ TelemetryUtil.indexMetricNameServiceNameMap({
1601
+ metricNameServiceNameMap: {
1602
+ [severityChangeMetricType.name]: severityChangeMetricType,
1603
+ },
1604
+ projectId: projectId,
1605
+ }).catch((err: Error) => {
1606
+ logger.error(err);
1607
+ });
1608
+ } catch (metricError) {
1609
+ logger.error(
1610
+ `Failed to emit severity change metric: ${metricError}`,
1611
+ );
1612
+ }
1471
1613
  }
1472
1614
  }
1473
1615
 
@@ -1693,6 +1835,7 @@ ${incidentSeverity.name}
1693
1835
  public async markMonitorsActiveForMonitoring(
1694
1836
  projectId: ObjectID,
1695
1837
  monitors: Array<Monitor>,
1838
+ startsAt?: Date | undefined,
1696
1839
  ): Promise<void> {
1697
1840
  // resolve all the monitors.
1698
1841
 
@@ -1769,6 +1912,10 @@ ${incidentSeverity.name}
1769
1912
  monitorStatusTimeline.projectId = projectId!;
1770
1913
  monitorStatusTimeline.monitorStatusId = resolvedMonitorState.id!;
1771
1914
 
1915
+ if (startsAt) {
1916
+ monitorStatusTimeline.startsAt = startsAt;
1917
+ }
1918
+
1772
1919
  await MonitorStatusTimelineService.create({
1773
1920
  data: monitorStatusTimeline,
1774
1921
  props: {
@@ -1959,6 +2106,77 @@ ${incidentSeverity.name}
1959
2106
  throw new BadDataException("Incident Project ID not found");
1960
2107
  }
1961
2108
 
2109
+ // fetch owner users and teams for metric attributes
2110
+ const ownerUsers: Array<IncidentOwnerUser> =
2111
+ await IncidentOwnerUserService.findBy({
2112
+ query: {
2113
+ incidentId: data.incidentId,
2114
+ },
2115
+ select: {
2116
+ _id: true,
2117
+ user: {
2118
+ _id: true,
2119
+ name: true,
2120
+ },
2121
+ },
2122
+ props: {
2123
+ isRoot: true,
2124
+ },
2125
+ limit: LIMIT_PER_PROJECT,
2126
+ skip: 0,
2127
+ });
2128
+
2129
+ const ownerTeams: Array<IncidentOwnerTeam> =
2130
+ await IncidentOwnerTeamService.findBy({
2131
+ query: {
2132
+ incidentId: data.incidentId,
2133
+ },
2134
+ select: {
2135
+ _id: true,
2136
+ team: {
2137
+ _id: true,
2138
+ name: true,
2139
+ },
2140
+ },
2141
+ props: {
2142
+ isRoot: true,
2143
+ },
2144
+ limit: LIMIT_PER_PROJECT,
2145
+ skip: 0,
2146
+ });
2147
+
2148
+ const ownerUserIds: Array<string> = ownerUsers
2149
+ .map((ownerUser: IncidentOwnerUser) => {
2150
+ return ownerUser.user?._id?.toString();
2151
+ })
2152
+ .filter((id: string | undefined) => {
2153
+ return Boolean(id);
2154
+ }) as Array<string>;
2155
+
2156
+ const ownerUserNames: Array<string> = ownerUsers
2157
+ .map((ownerUser: IncidentOwnerUser) => {
2158
+ return ownerUser.user?.name?.toString();
2159
+ })
2160
+ .filter((name: string | undefined) => {
2161
+ return Boolean(name);
2162
+ }) as Array<string>;
2163
+
2164
+ const ownerTeamIds: Array<string> = ownerTeams
2165
+ .map((ownerTeam: IncidentOwnerTeam) => {
2166
+ return ownerTeam.team?._id?.toString();
2167
+ })
2168
+ .filter((id: string | undefined) => {
2169
+ return Boolean(id);
2170
+ }) as Array<string>;
2171
+
2172
+ const ownerTeamNames: Array<string> = ownerTeams
2173
+ .map((ownerTeam: IncidentOwnerTeam) => {
2174
+ return ownerTeam.team?.name?.toString();
2175
+ })
2176
+ .filter((name: string | undefined) => {
2177
+ return Boolean(name);
2178
+ }) as Array<string>;
2179
+
1962
2180
  // get incident state timeline
1963
2181
 
1964
2182
  const incidentStateTimelines: Array<IncidentStateTimeline> =
@@ -1970,8 +2188,10 @@ ${incidentSeverity.name}
1970
2188
  projectId: true,
1971
2189
  incidentStateId: true,
1972
2190
  incidentState: {
2191
+ name: true,
1973
2192
  isAcknowledgedState: true,
1974
2193
  isResolvedState: true,
2194
+ isCreatedState: true,
1975
2195
  },
1976
2196
  startsAt: true,
1977
2197
  endsAt: true,
@@ -2013,14 +2233,8 @@ ${incidentSeverity.name}
2013
2233
 
2014
2234
  const metricTypesMap: Dictionary<MetricType> = {};
2015
2235
 
2016
- const incidentCountMetric: Metric = new Metric();
2017
-
2018
- incidentCountMetric.projectId = incident.projectId;
2019
- incidentCountMetric.serviceId = incident.id!;
2020
- incidentCountMetric.serviceType = ServiceType.Incident;
2021
- incidentCountMetric.name = IncidentMetricType.IncidentCount;
2022
- incidentCountMetric.value = 1;
2023
- incidentCountMetric.attributes = {
2236
+ // common attributes shared by all incident metrics
2237
+ const baseMetricAttributes: JSONObject = {
2024
2238
  incidentId: data.incidentId.toString(),
2025
2239
  projectId: incident.projectId.toString(),
2026
2240
  monitorIds:
@@ -2033,7 +2247,20 @@ ${incidentSeverity.name}
2033
2247
  }) || [],
2034
2248
  incidentSeverityId: incident.incidentSeverity?._id?.toString(),
2035
2249
  incidentSeverityName: incident.incidentSeverity?.name?.toString(),
2250
+ ownerUserIds: ownerUserIds,
2251
+ ownerUserNames: ownerUserNames,
2252
+ ownerTeamIds: ownerTeamIds,
2253
+ ownerTeamNames: ownerTeamNames,
2036
2254
  };
2255
+
2256
+ const incidentCountMetric: Metric = new Metric();
2257
+
2258
+ incidentCountMetric.projectId = incident.projectId;
2259
+ incidentCountMetric.serviceId = incident.id!;
2260
+ incidentCountMetric.serviceType = ServiceType.Incident;
2261
+ incidentCountMetric.name = IncidentMetricType.IncidentCount;
2262
+ incidentCountMetric.value = 1;
2263
+ incidentCountMetric.attributes = { ...baseMetricAttributes };
2037
2264
  incidentCountMetric.attributeKeys = TelemetryUtil.getAttributeKeys(
2038
2265
  incidentCountMetric.attributes,
2039
2266
  );
@@ -2080,20 +2307,7 @@ ${incidentSeverity.name}
2080
2307
  ackIncidentStateTimeline?.startsAt || OneUptimeDate.getCurrentDate(),
2081
2308
  incidentStartsAt,
2082
2309
  );
2083
- timeToAcknowledgeMetric.attributes = {
2084
- incidentId: data.incidentId.toString(),
2085
- projectId: incident.projectId.toString(),
2086
- monitorIds:
2087
- incident.monitors?.map((monitor: Monitor) => {
2088
- return monitor._id?.toString();
2089
- }) || [],
2090
- monitorNames:
2091
- incident.monitors?.map((monitor: Monitor) => {
2092
- return monitor.name?.toString();
2093
- }) || [],
2094
- incidentSeverityId: incident.incidentSeverity?._id?.toString(),
2095
- incidentSeverityName: incident.incidentSeverity?.name?.toString(),
2096
- };
2310
+ timeToAcknowledgeMetric.attributes = { ...baseMetricAttributes };
2097
2311
  timeToAcknowledgeMetric.attributeKeys = TelemetryUtil.getAttributeKeys(
2098
2312
  timeToAcknowledgeMetric.attributes,
2099
2313
  );
@@ -2146,20 +2360,7 @@ ${incidentSeverity.name}
2146
2360
  OneUptimeDate.getCurrentDate(),
2147
2361
  incidentStartsAt,
2148
2362
  );
2149
- timeToResolveMetric.attributes = {
2150
- incidentId: data.incidentId.toString(),
2151
- projectId: incident.projectId.toString(),
2152
- monitorIds:
2153
- incident.monitors?.map((monitor: Monitor) => {
2154
- return monitor._id?.toString();
2155
- }) || [],
2156
- monitorNames:
2157
- incident.monitors?.map((monitor: Monitor) => {
2158
- return monitor.name?.toString();
2159
- }) || [],
2160
- incidentSeverityId: incident.incidentSeverity?._id?.toString(),
2161
- incidentSeverityName: incident.incidentSeverity?.name?.toString(),
2162
- };
2363
+ timeToResolveMetric.attributes = { ...baseMetricAttributes };
2163
2364
  timeToResolveMetric.attributeKeys = TelemetryUtil.getAttributeKeys(
2164
2365
  timeToResolveMetric.attributes,
2165
2366
  );
@@ -2207,20 +2408,7 @@ ${incidentSeverity.name}
2207
2408
  incidentEndsAt,
2208
2409
  incidentStartsAt,
2209
2410
  );
2210
- incidentDurationMetric.attributes = {
2211
- incidentId: data.incidentId.toString(),
2212
- projectId: incident.projectId.toString(),
2213
- monitorIds:
2214
- incident.monitors?.map((monitor: Monitor) => {
2215
- return monitor._id?.toString();
2216
- }) || [],
2217
- monitorNames:
2218
- incident.monitors?.map((monitor: Monitor) => {
2219
- return monitor.name?.toString();
2220
- }) || [],
2221
- incidentSeverityId: incident.incidentSeverity?._id?.toString(),
2222
- incidentSeverityName: incident.incidentSeverity?.name?.toString(),
2223
- };
2411
+ incidentDurationMetric.attributes = { ...baseMetricAttributes };
2224
2412
  incidentDurationMetric.attributeKeys = TelemetryUtil.getAttributeKeys(
2225
2413
  incidentDurationMetric.attributes,
2226
2414
  );
@@ -2247,6 +2435,63 @@ ${incidentSeverity.name}
2247
2435
  metricTypesMap[incidentDurationMetric.name] = metricType;
2248
2436
  }
2249
2437
 
2438
+ // time-in-state metrics — emit one metric per state transition that has a completed duration
2439
+ for (const timeline of incidentStateTimelines) {
2440
+ if (!timeline.startsAt || !timeline.endsAt) {
2441
+ continue;
2442
+ }
2443
+
2444
+ const stateName: string =
2445
+ timeline.incidentState?.name?.toString() || "Unknown";
2446
+
2447
+ const timeInStateMetric: Metric = new Metric();
2448
+
2449
+ timeInStateMetric.projectId = incident.projectId;
2450
+ timeInStateMetric.serviceId = incident.id!;
2451
+ timeInStateMetric.serviceType = ServiceType.Incident;
2452
+ timeInStateMetric.name = IncidentMetricType.TimeInState;
2453
+ timeInStateMetric.value = OneUptimeDate.getDifferenceInSeconds(
2454
+ timeline.endsAt,
2455
+ timeline.startsAt,
2456
+ );
2457
+ timeInStateMetric.attributes = {
2458
+ ...baseMetricAttributes,
2459
+ incidentStateName: stateName,
2460
+ incidentStateId: timeline.incidentStateId?.toString(),
2461
+ isCreatedState:
2462
+ timeline.incidentState?.isCreatedState?.toString() || "false",
2463
+ isAcknowledgedState:
2464
+ timeline.incidentState?.isAcknowledgedState?.toString() || "false",
2465
+ isResolvedState:
2466
+ timeline.incidentState?.isResolvedState?.toString() || "false",
2467
+ };
2468
+ timeInStateMetric.attributeKeys = TelemetryUtil.getAttributeKeys(
2469
+ timeInStateMetric.attributes,
2470
+ );
2471
+
2472
+ timeInStateMetric.time = timeline.startsAt;
2473
+ timeInStateMetric.timeUnixNano = OneUptimeDate.toUnixNano(
2474
+ timeInStateMetric.time,
2475
+ );
2476
+ timeInStateMetric.metricPointType = MetricPointType.Sum;
2477
+
2478
+ itemsToSave.push(timeInStateMetric);
2479
+ }
2480
+
2481
+ // add metric type for time-in-state to map (only once)
2482
+ if (
2483
+ incidentStateTimelines.some((t: IncidentStateTimeline) => {
2484
+ return t.startsAt && t.endsAt;
2485
+ })
2486
+ ) {
2487
+ const timeInStateMetricType: MetricType = new MetricType();
2488
+ timeInStateMetricType.name = IncidentMetricType.TimeInState;
2489
+ timeInStateMetricType.description =
2490
+ "Time spent in each incident state (e.g. Created, Investigating, Acknowledged)";
2491
+ timeInStateMetricType.unit = "seconds";
2492
+ metricTypesMap[timeInStateMetricType.name] = timeInStateMetricType;
2493
+ }
2494
+
2250
2495
  await MetricService.createMany({
2251
2496
  items: itemsToSave,
2252
2497
  props: {
@@ -497,6 +497,7 @@ ${createdItem.rootCause}`,
497
497
  await IncidentService.markMonitorsActiveForMonitoring(
498
498
  incident.projectId!,
499
499
  incident.monitors || [],
500
+ createdItem.startsAt || undefined,
500
501
  );
501
502
  }
502
503
  }
@@ -74,6 +74,8 @@ import AIAgentTaskPullRequestService from "./AIAgentTaskPullRequestService";
74
74
  import ProjectCallSMSConfigService from "./ProjectCallSMSConfigService";
75
75
  import ProjectService from "./ProjectService";
76
76
  import ProjectUserProfileService from "./ProjectUserProfileService";
77
+ import ProfileService from "./ProfileService";
78
+ import ProfileSampleService from "./ProfileSampleService";
77
79
  // Project SMTP Config.
78
80
  import ProjectSmtpConfigService from "./ProjectSmtpConfigService";
79
81
  import ProjectSsoService from "./ProjectSsoService";
@@ -105,6 +107,7 @@ import SpanService from "./SpanService";
105
107
  import StatusPageAnnouncementService from "./StatusPageAnnouncementService";
106
108
  import StatusPageAnnouncementTemplateService from "./StatusPageAnnouncementTemplateService";
107
109
  import StatusPageCustomFieldService from "./StatusPageCustomFieldService";
110
+ import DashboardDomainService from "./DashboardDomainService";
108
111
  import StatusPageDomainService from "./StatusPageDomainService";
109
112
  import StatusPageFooterLinkService from "./StatusPageFooterLinkService";
110
113
  import StatusPageGroupService from "./StatusPageGroupService";
@@ -305,6 +308,7 @@ const services: Array<BaseService> = [
305
308
  StatusPageAnnouncementService,
306
309
  StatusPageAnnouncementTemplateService,
307
310
  StatusPageCustomFieldService,
311
+ DashboardDomainService,
308
312
  StatusPageDomainService,
309
313
  StatusPageFooterLinkService,
310
314
  StatusPageGroupService,
@@ -431,6 +435,8 @@ export const AnalyticsServices: Array<
431
435
  MetricService,
432
436
  ExceptionInstanceService,
433
437
  MonitorLogService,
438
+ ProfileService,
439
+ ProfileSampleService,
434
440
  ];
435
441
 
436
442
  export default services;
@@ -1507,6 +1507,7 @@ ${createdItem.description?.trim() || "No description provided."}
1507
1507
  rootCause: string | undefined,
1508
1508
  statusChangeLog: JSONObject | undefined,
1509
1509
  props: DatabaseCommonInteractionProps,
1510
+ startsAt?: Date | undefined,
1510
1511
  ): Promise<void> {
1511
1512
  for (const monitorId of monitorIds) {
1512
1513
  // get last monitor status timeline.
@@ -1552,6 +1553,10 @@ ${createdItem.description?.trim() || "No description provided."}
1552
1553
  statusTimeline.rootCause = rootCause;
1553
1554
  }
1554
1555
 
1556
+ if (startsAt) {
1557
+ statusTimeline.startsAt = startsAt;
1558
+ }
1559
+
1555
1560
  await MonitorStatusTimelineService.create({
1556
1561
  data: statusTimeline,
1557
1562
  props: props,