@oneuptime/common 13.0.1 → 13.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (769) hide show
  1. package/Models/AnalyticsModels/RumSession.ts +34 -0
  2. package/Models/DatabaseModels/AlertEpisodeLabelRule.ts +2 -2
  3. package/Models/DatabaseModels/AlertEpisodeOnCallRule.ts +2 -2
  4. package/Models/DatabaseModels/AlertEpisodeOwnerRule.ts +2 -2
  5. package/Models/DatabaseModels/AlertEpisodePrivacyRule.ts +2 -2
  6. package/Models/DatabaseModels/AlertGroupingRule.ts +2 -2
  7. package/Models/DatabaseModels/AlertLabelRule.ts +2 -2
  8. package/Models/DatabaseModels/AlertOnCallRule.ts +2 -2
  9. package/Models/DatabaseModels/AlertOwnerRule.ts +2 -2
  10. package/Models/DatabaseModels/AlertPrivacyRule.ts +2 -2
  11. package/Models/DatabaseModels/AlertReminderRule.ts +6 -4
  12. package/Models/DatabaseModels/AutoRemediationRule.ts +2 -2
  13. package/Models/DatabaseModels/CephClusterLabelRule.ts +2 -2
  14. package/Models/DatabaseModels/CephClusterOwnerRule.ts +2 -2
  15. package/Models/DatabaseModels/CloudResourceLabelRule.ts +2 -2
  16. package/Models/DatabaseModels/CloudResourceOwnerRule.ts +2 -2
  17. package/Models/DatabaseModels/DashboardLabelRule.ts +2 -2
  18. package/Models/DatabaseModels/DashboardOwnerRule.ts +2 -2
  19. package/Models/DatabaseModels/DatabaseBaseModel/RelationOnlyRuleBaseModel.ts +11 -0
  20. package/Models/DatabaseModels/DatabaseBaseModel/RuleBaseModel.ts +44 -0
  21. package/Models/DatabaseModels/DockerHostLabelRule.ts +2 -2
  22. package/Models/DatabaseModels/DockerHostOwnerRule.ts +2 -2
  23. package/Models/DatabaseModels/DockerSwarmClusterLabelRule.ts +2 -2
  24. package/Models/DatabaseModels/DockerSwarmClusterOwnerRule.ts +2 -2
  25. package/Models/DatabaseModels/HostLabelRule.ts +2 -2
  26. package/Models/DatabaseModels/HostOwnerRule.ts +2 -2
  27. package/Models/DatabaseModels/IncidentEpisodeLabelRule.ts +2 -2
  28. package/Models/DatabaseModels/IncidentEpisodeOnCallRule.ts +2 -2
  29. package/Models/DatabaseModels/IncidentEpisodeOwnerRule.ts +2 -2
  30. package/Models/DatabaseModels/IncidentEpisodePrivacyRule.ts +2 -2
  31. package/Models/DatabaseModels/IncidentGroupingRule.ts +2 -2
  32. package/Models/DatabaseModels/IncidentLabelRule.ts +2 -2
  33. package/Models/DatabaseModels/IncidentOnCallRule.ts +2 -2
  34. package/Models/DatabaseModels/IncidentOwnerRule.ts +2 -2
  35. package/Models/DatabaseModels/IncidentPrivacyRule.ts +2 -2
  36. package/Models/DatabaseModels/IncidentReminderRule.ts +6 -4
  37. package/Models/DatabaseModels/IncidentSlaRule.ts +2 -2
  38. package/Models/DatabaseModels/IncomingCallPolicy.ts +3 -4
  39. package/Models/DatabaseModels/IncomingCallPolicyLabelRule.ts +2 -2
  40. package/Models/DatabaseModels/IncomingCallPolicyOwnerRule.ts +2 -2
  41. package/Models/DatabaseModels/IncomingCallPolicyPhoneNumber.ts +254 -0
  42. package/Models/DatabaseModels/Index.ts +2 -0
  43. package/Models/DatabaseModels/IoTFleetLabelRule.ts +2 -2
  44. package/Models/DatabaseModels/IoTFleetOwnerRule.ts +2 -2
  45. package/Models/DatabaseModels/KubernetesClusterLabelRule.ts +2 -2
  46. package/Models/DatabaseModels/KubernetesClusterOwnerRule.ts +2 -2
  47. package/Models/DatabaseModels/MonitorLabelRule.ts +2 -2
  48. package/Models/DatabaseModels/MonitorOwnerRule.ts +2 -2
  49. package/Models/DatabaseModels/NetworkDeviceAutoImportRule.ts +2 -2
  50. package/Models/DatabaseModels/NetworkDeviceLabelRule.ts +2 -2
  51. package/Models/DatabaseModels/NetworkDeviceOwnerRule.ts +2 -2
  52. package/Models/DatabaseModels/NetworkSiteAssignmentRule.ts +2 -2
  53. package/Models/DatabaseModels/OnCallDutyPolicyLabelRule.ts +2 -2
  54. package/Models/DatabaseModels/OnCallDutyPolicyOwnerRule.ts +2 -2
  55. package/Models/DatabaseModels/OnCallDutyPolicyScheduleLabelRule.ts +2 -2
  56. package/Models/DatabaseModels/OnCallDutyPolicyScheduleOwnerRule.ts +2 -2
  57. package/Models/DatabaseModels/PodmanHostLabelRule.ts +2 -2
  58. package/Models/DatabaseModels/PodmanHostOwnerRule.ts +2 -2
  59. package/Models/DatabaseModels/ProxmoxClusterLabelRule.ts +2 -2
  60. package/Models/DatabaseModels/ProxmoxClusterOwnerRule.ts +2 -2
  61. package/Models/DatabaseModels/RumApplicationLabelRule.ts +2 -2
  62. package/Models/DatabaseModels/RumApplicationOwnerRule.ts +2 -2
  63. package/Models/DatabaseModels/RunbookLabelRule.ts +2 -2
  64. package/Models/DatabaseModels/RunbookOwnerRule.ts +2 -2
  65. package/Models/DatabaseModels/RunbookRule.ts +2 -2
  66. package/Models/DatabaseModels/ScheduledMaintenanceLabelRule.ts +2 -2
  67. package/Models/DatabaseModels/ScheduledMaintenanceOwnerRule.ts +2 -2
  68. package/Models/DatabaseModels/ScheduledMaintenanceReminderRule.ts +6 -4
  69. package/Models/DatabaseModels/ServerlessFunctionLabelRule.ts +2 -2
  70. package/Models/DatabaseModels/ServerlessFunctionOwnerRule.ts +2 -2
  71. package/Models/DatabaseModels/ServiceLabelRule.ts +2 -2
  72. package/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.ts +283 -4
  73. package/Models/DatabaseModels/ServiceOwnerRule.ts +2 -2
  74. package/Models/DatabaseModels/StatusPageLabelRule.ts +2 -2
  75. package/Models/DatabaseModels/StatusPageMonitorRule.ts +2 -2
  76. package/Models/DatabaseModels/StatusPageOwnerRule.ts +2 -2
  77. package/Models/DatabaseModels/VMwareVCenterLabelRule.ts +2 -2
  78. package/Models/DatabaseModels/VMwareVCenterOwnerRule.ts +2 -2
  79. package/Models/DatabaseModels/WorkflowLabelRule.ts +2 -2
  80. package/Models/DatabaseModels/WorkflowOwnerRule.ts +2 -2
  81. package/Server/API/TelemetryAPI.ts +323 -2
  82. package/Server/Infrastructure/Postgres/SchemaMigrations/1792400000000-AddSloBurnRateRuleIncidents.ts +111 -0
  83. package/Server/Infrastructure/Postgres/SchemaMigrations/1792500000000-AddConfigurableRuleCriteria.ts +644 -0
  84. package/Server/Infrastructure/Postgres/SchemaMigrations/1792600000000-AddIncomingCallPolicyPhoneNumbers.ts +72 -0
  85. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  86. package/Server/Middleware/MultipartFormData.ts +46 -21
  87. package/Server/Services/AlertEpisodeLabelRuleEngineService.ts +21 -0
  88. package/Server/Services/AlertEpisodeOnCallRuleEngineService.ts +21 -0
  89. package/Server/Services/AlertEpisodeOwnerRuleEngineService.ts +21 -0
  90. package/Server/Services/AlertEpisodePrivacyRuleEngineService.ts +21 -0
  91. package/Server/Services/AlertGroupingEngineService.ts +27 -0
  92. package/Server/Services/AlertLabelRuleEngineService.ts +27 -0
  93. package/Server/Services/AlertOnCallRuleEngineService.ts +27 -0
  94. package/Server/Services/AlertOwnerRuleEngineService.ts +27 -0
  95. package/Server/Services/AlertPrivacyRuleEngineService.ts +27 -0
  96. package/Server/Services/AlertReminderRuleService.ts +65 -33
  97. package/Server/Services/AutoRemediationRuleEngineService.ts +90 -8
  98. package/Server/Services/CephClusterLabelRuleEngineService.ts +20 -0
  99. package/Server/Services/CephClusterOwnerRuleEngineService.ts +20 -0
  100. package/Server/Services/CloudResourceLabelRuleEngineService.ts +20 -0
  101. package/Server/Services/CloudResourceOwnerRuleEngineService.ts +20 -0
  102. package/Server/Services/DashboardLabelRuleEngineService.ts +20 -0
  103. package/Server/Services/DashboardOwnerRuleEngineService.ts +20 -0
  104. package/Server/Services/DatabaseService.ts +409 -6
  105. package/Server/Services/DockerHostLabelRuleEngineService.ts +20 -0
  106. package/Server/Services/DockerHostOwnerRuleEngineService.ts +20 -0
  107. package/Server/Services/DockerSwarmClusterLabelRuleEngineService.ts +23 -0
  108. package/Server/Services/DockerSwarmClusterOwnerRuleEngineService.ts +23 -0
  109. package/Server/Services/HostLabelRuleEngineService.ts +13 -0
  110. package/Server/Services/HostOwnerRuleEngineService.ts +13 -0
  111. package/Server/Services/IncidentEpisodeLabelRuleEngineService.ts +21 -0
  112. package/Server/Services/IncidentEpisodeOnCallRuleEngineService.ts +21 -0
  113. package/Server/Services/IncidentEpisodeOwnerRuleEngineService.ts +21 -0
  114. package/Server/Services/IncidentEpisodePrivacyRuleEngineService.ts +21 -0
  115. package/Server/Services/IncidentGroupingEngineService.ts +64 -13
  116. package/Server/Services/IncidentLabelRuleEngineService.ts +64 -9
  117. package/Server/Services/IncidentOnCallRuleEngineService.ts +64 -10
  118. package/Server/Services/IncidentOwnerRuleEngineService.ts +64 -10
  119. package/Server/Services/IncidentPrivacyRuleEngineService.ts +64 -10
  120. package/Server/Services/IncidentReminderRuleService.ts +66 -34
  121. package/Server/Services/IncidentSlaRuleService.ts +55 -12
  122. package/Server/Services/IncomingCallPolicyLabelRuleEngineService.ts +20 -0
  123. package/Server/Services/IncomingCallPolicyOwnerRuleEngineService.ts +20 -0
  124. package/Server/Services/IncomingCallPolicyPhoneNumberService.ts +184 -0
  125. package/Server/Services/IncomingCallPolicyService.ts +276 -5
  126. package/Server/Services/Index.ts +2 -0
  127. package/Server/Services/IoTFleetLabelRuleEngineService.ts +20 -0
  128. package/Server/Services/IoTFleetOwnerRuleEngineService.ts +20 -0
  129. package/Server/Services/KubernetesClusterLabelRuleEngineService.ts +23 -0
  130. package/Server/Services/KubernetesClusterOwnerRuleEngineService.ts +23 -0
  131. package/Server/Services/LabelService.ts +50 -7
  132. package/Server/Services/MonitorLabelRuleEngineService.ts +20 -0
  133. package/Server/Services/MonitorOwnerRuleEngineService.ts +20 -0
  134. package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +2 -0
  135. package/Server/Services/NetworkDeviceAutoImportRuleService.ts +93 -1
  136. package/Server/Services/NetworkDeviceLabelRuleEngineService.ts +26 -0
  137. package/Server/Services/NetworkDeviceOwnerRuleEngineService.ts +25 -0
  138. package/Server/Services/NetworkDeviceService.ts +2 -0
  139. package/Server/Services/NetworkSiteAssignmentRuleService.ts +90 -1
  140. package/Server/Services/NetworkSiteService.ts +242 -29
  141. package/Server/Services/NetworkSiteTypeService.ts +177 -77
  142. package/Server/Services/OnCallDutyPolicyLabelRuleEngineService.ts +20 -0
  143. package/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.ts +20 -0
  144. package/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.ts +22 -0
  145. package/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.ts +22 -0
  146. package/Server/Services/PodmanHostLabelRuleEngineService.ts +20 -0
  147. package/Server/Services/PodmanHostOwnerRuleEngineService.ts +20 -0
  148. package/Server/Services/ProjectCallSMSConfigService.ts +156 -7
  149. package/Server/Services/ProxmoxClusterLabelRuleEngineService.ts +25 -0
  150. package/Server/Services/ProxmoxClusterOwnerRuleEngineService.ts +25 -0
  151. package/Server/Services/RumApplicationLabelRuleEngineService.ts +22 -0
  152. package/Server/Services/RumApplicationOwnerRuleEngineService.ts +22 -0
  153. package/Server/Services/RunbookLabelRuleEngineService.ts +20 -0
  154. package/Server/Services/RunbookOwnerRuleEngineService.ts +20 -0
  155. package/Server/Services/RunbookRuleEngineService.ts +18 -1
  156. package/Server/Services/ScheduledMaintenanceLabelRuleEngineService.ts +62 -10
  157. package/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.ts +62 -11
  158. package/Server/Services/ScheduledMaintenanceReminderRuleService.ts +48 -18
  159. package/Server/Services/ServerlessFunctionLabelRuleEngineService.ts +25 -0
  160. package/Server/Services/ServerlessFunctionOwnerRuleEngineService.ts +25 -0
  161. package/Server/Services/ServiceLabelRuleEngineService.ts +20 -0
  162. package/Server/Services/ServiceLevelObjectiveBurnRateRuleService.ts +675 -12
  163. package/Server/Services/ServiceLevelObjectiveService.ts +55 -13
  164. package/Server/Services/ServiceOwnerRuleEngineService.ts +20 -0
  165. package/Server/Services/StatusPageLabelRuleEngineService.ts +20 -0
  166. package/Server/Services/StatusPageMonitorRuleEngineService.ts +31 -2
  167. package/Server/Services/StatusPageMonitorRuleService.ts +34 -1
  168. package/Server/Services/StatusPageOwnerRuleEngineService.ts +20 -0
  169. package/Server/Services/UserService.ts +23 -50
  170. package/Server/Services/VMwareVCenterLabelRuleEngineService.ts +25 -0
  171. package/Server/Services/VMwareVCenterOwnerRuleEngineService.ts +25 -0
  172. package/Server/Services/WorkflowLabelRuleEngineService.ts +20 -0
  173. package/Server/Services/WorkflowOwnerRuleEngineService.ts +20 -0
  174. package/Server/Static/Brand/README.md +10 -5
  175. package/Server/Static/Brand/favicons/oneuptime-up-v1.svg +8 -0
  176. package/Server/Types/Database/QueryHelper.ts +88 -0
  177. package/Server/Utils/AI/Toolbox/SloTools.ts +19 -2
  178. package/Server/Utils/IncomingCallPhoneNumber.ts +29 -16
  179. package/Server/Utils/Profiling.ts +13 -1
  180. package/Server/Utils/Rules/MonitorRuleCriteriaCache.ts +38 -0
  181. package/Server/Utils/SessionReplay/SessionReplayReadService.ts +498 -0
  182. package/Server/Utils/Telemetry.ts +3 -1
  183. package/Server/Utils/VendorAssets.ts +3 -0
  184. package/Tests/App/Dashboard/AIInsightViewTriage.test.tsx +348 -0
  185. package/Tests/App/Dashboard/ArchiveResourceCard.test.tsx +476 -0
  186. package/Tests/App/Dashboard/CloudDocumentationCard.test.tsx +25 -0
  187. package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +449 -24
  188. package/Tests/App/Dashboard/DashboardPersistentSideMenuLayouts.test.tsx +702 -0
  189. package/Tests/App/Dashboard/ExceptionsLandingRedirect.test.tsx +63 -0
  190. package/Tests/App/Dashboard/FeedOrdering.test.ts +150 -0
  191. package/Tests/App/Dashboard/GoogleSecOpsConnectionsErrors.test.tsx +279 -100
  192. package/Tests/App/Dashboard/InventoryItemSideMenu.test.tsx +155 -0
  193. package/Tests/App/Dashboard/InvestigationFeedRefresh.test.tsx +11 -0
  194. package/Tests/App/Dashboard/PasskeySettings.test.tsx +215 -71
  195. package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +347 -0
  196. package/Tests/App/Dashboard/ResourceAuditLogsSideMenus.test.tsx +263 -0
  197. package/Tests/App/Dashboard/ResourceFeed.test.tsx +413 -17
  198. package/Tests/App/Dashboard/RumSessionReplaySideMenu.test.tsx +138 -0
  199. package/Tests/App/Dashboard/SloDashboardTemplateWidgets.test.tsx +940 -0
  200. package/Tests/App/Dashboard/TelemetryIngestionKeyEdit.test.tsx +378 -0
  201. package/Tests/App/Dashboard/TelemetryIngestionKeyForm.test.tsx +735 -0
  202. package/Tests/App/Dashboard/TwoFactorStatus.test.tsx +275 -108
  203. package/Tests/App/StatusPage/BulkAddStatusPageMonitorsModal.test.tsx +13 -3
  204. package/Tests/Models/AnalyticsModels/RumSessionReplayColumns.test.ts +127 -4
  205. package/Tests/Models/DatabaseModels/DomainRoleTierCoverage.test.ts +5 -4
  206. package/Tests/Models/DatabaseModels/IncomingCallPolicyPhoneNumber.test.ts +362 -0
  207. package/Tests/Models/DatabaseModels/RuleBaseModel.test.ts +69 -0
  208. package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +181 -0
  209. package/Tests/Server/API/SessionReplayAPI.test.ts +1303 -145
  210. package/Tests/Server/API/UserTwoFactorSelfService.test.ts +407 -0
  211. package/Tests/Server/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +611 -0
  212. package/Tests/Server/Middleware/MultipartFormData.test.ts +61 -3
  213. package/Tests/Server/Middleware/TelemetryIngestionDisabled.test.ts +211 -0
  214. package/Tests/Server/Services/AlertIncidentRuleCriteriaEngineServices.test.ts +651 -0
  215. package/Tests/Server/Services/AutoRemediationRuleEngineService.test.ts +79 -0
  216. package/Tests/Server/Services/DatabaseServiceRelationOnlyRuleRollout.test.ts +330 -0
  217. package/Tests/Server/Services/DatabaseServiceRuleCriteriaValidation.test.ts +522 -0
  218. package/Tests/Server/Services/IncidentSlaRuleCriteriaCorrelation.test.ts +99 -0
  219. package/Tests/Server/Services/IncomingCallPolicyPhoneNumberService.test.ts +1540 -0
  220. package/Tests/Server/Services/NetworkDeviceRuleEngines.test.ts +179 -2
  221. package/Tests/Server/Services/NetworkSiteAssignmentRuleService.test.ts +170 -0
  222. package/Tests/Server/Services/NetworkSiteService.test.ts +559 -53
  223. package/Tests/Server/Services/NetworkSiteTypeService.test.ts +122 -55
  224. package/Tests/Server/Services/ReminderRuleCriteria.test.ts +173 -0
  225. package/Tests/Server/Services/ResourceRuleCriteriaEngineServices.test.ts +170 -0
  226. package/Tests/Server/Services/ScheduledMaintenanceRuleCriteriaCorrelation.test.ts +154 -0
  227. package/Tests/Server/Services/ServiceLevelObjectiveBurnRateRuleService.test.ts +2450 -470
  228. package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +464 -121
  229. package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +281 -0
  230. package/Tests/Server/Services/StatusPageMonitorRuleEngineService.test.ts +132 -0
  231. package/Tests/Server/Services/StatusPageMonitorRuleHooks.test.ts +159 -14
  232. package/Tests/Server/Services/UserEmailChangePasswordResetExpiry.test.ts +6 -8
  233. package/Tests/Server/Services/UserTwoFactorAuthAdmin.test.ts +203 -34
  234. package/Tests/Server/Types/Database/QueryHelperJsonArrayObjects.test.ts +128 -0
  235. package/Tests/Server/Utils/AI/SloTools.test.ts +190 -1
  236. package/Tests/Server/Utils/AI/Toolbox/AIToolbox.test.ts +461 -0
  237. package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +25 -0
  238. package/Tests/Server/Utils/Billing/BillingFailureNoticeThrottle.test.ts +359 -0
  239. package/Tests/Server/Utils/CodeRepository/GitHub/GitHubWebhookEvents.test.ts +318 -0
  240. package/Tests/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.test.ts +220 -0
  241. package/Tests/Server/Utils/Dashboard/SloTemplatePublicDashboard.test.ts +1043 -0
  242. package/Tests/Server/Utils/Execute.test.ts +302 -0
  243. package/Tests/Server/Utils/GracefulShutdown.test.ts +565 -0
  244. package/Tests/Server/Utils/IncomingCallPhoneNumber.test.ts +36 -20
  245. package/Tests/Server/Utils/Monitor/SloTemplateMetricEmitterContract.test.ts +750 -0
  246. package/Tests/Server/Utils/ProductAnalytics.test.ts +404 -0
  247. package/Tests/Server/Utils/Profiling.test.ts +366 -0
  248. package/Tests/Server/Utils/Rules/MonitorRuleCriteriaCache.test.ts +99 -0
  249. package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +558 -0
  250. package/Tests/Server/Utils/VendorAssets.test.ts +17 -0
  251. package/Tests/Types/Dashboard/DashboardTemplateEditorialInvariants.test.ts +659 -0
  252. package/Tests/Types/Dashboard/DashboardTemplateInvariants.test.ts +97 -0
  253. package/Tests/Types/Dashboard/SloDashboardTemplate.test.ts +1179 -0
  254. package/Tests/Types/Database/AccessControl/OwnedThrough.test.ts +136 -0
  255. package/Tests/Types/Rum/SessionReplayApiContracts.test.ts +180 -1
  256. package/Tests/UI/Components/AiInvestigationSettingsCard.test.tsx +13 -6
  257. package/Tests/UI/Components/Alert.test.tsx +532 -93
  258. package/Tests/UI/Components/Feed.test.tsx +241 -0
  259. package/Tests/UI/Components/Forms/BasicFormStepNavigation.test.tsx +368 -0
  260. package/Tests/UI/Components/Forms/FormSummary.test.tsx +454 -0
  261. package/Tests/UI/Components/Forms/ModelFormJsonColumns.test.tsx +290 -0
  262. package/Tests/UI/Components/Forms/ModelFormRuleCriteria.test.tsx +331 -0
  263. package/Tests/UI/Components/IconOpticalSize.test.tsx +79 -31
  264. package/Tests/UI/Components/ModelTable/ModelTableWrapContent.test.tsx +6 -6
  265. package/Tests/UI/Components/NavBar.test.tsx +91 -2
  266. package/Tests/UI/Components/PencilButton.test.tsx +211 -0
  267. package/Tests/UI/Components/RuleCriteria/RuleCriteriaBuilder.test.tsx +510 -0
  268. package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +350 -0
  269. package/Tests/UI/Components/TableSortAndMobileColumns.test.tsx +50 -0
  270. package/Tests/UI/Components/Telemetry/TelemetryRetentionConfigForm.test.tsx +329 -0
  271. package/Tests/UI/Components/useFeedItems.test.tsx +107 -0
  272. package/Tests/UI/Rum/ChunkLoader.test.ts +401 -0
  273. package/Tests/UI/Rum/RecordingHealthCard.test.tsx +1 -1
  274. package/Tests/UI/Rum/RecordingHealthStrip.test.tsx +7 -1
  275. package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +2 -0
  276. package/Tests/UI/Rum/ReplayEngine.test.ts +1069 -5
  277. package/Tests/UI/Rum/ReplayHeader.test.tsx +579 -2
  278. package/Tests/UI/Rum/ReplayPlayerChrome.test.tsx +23 -5
  279. package/Tests/UI/Rum/ReplayRail.test.tsx +143 -1
  280. package/Tests/UI/Rum/ReplayRenderBudget.test.tsx +338 -0
  281. package/Tests/UI/Rum/ReplaySignals.test.ts +179 -0
  282. package/Tests/UI/Rum/ReplayStage.test.tsx +210 -3
  283. package/Tests/UI/Rum/ReplayTimeline.test.tsx +180 -1
  284. package/Tests/UI/Rum/ReplayUserSessionsMenu.test.tsx +405 -0
  285. package/Tests/UI/Rum/SessionReplayEmptyState.test.tsx +13 -16
  286. package/Tests/UI/Rum/SessionReplayFacets.test.tsx +199 -0
  287. package/Tests/UI/Rum/SessionReplaySearchBar.test.tsx +58 -21
  288. package/Tests/UI/Rum/SessionReplaySetupGuide.test.tsx +2 -0
  289. package/Tests/UI/Rum/SessionReplayTable.test.tsx +717 -4
  290. package/Tests/UI/Rum/SessionReplayUsersPage.test.tsx +435 -0
  291. package/Tests/UI/Rum/SessionReplayUsersTable.test.tsx +577 -0
  292. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +1 -1
  293. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +1 -1
  294. package/Tests/UI/Utils/LabelRuleImportExport.test.ts +192 -0
  295. package/Tests/UI/Utils/Navigation.test.ts +30 -0
  296. package/Tests/Utils/Dashboard/SloTemplateVariableScoping.test.ts +880 -0
  297. package/Tests/Utils/LabelRuleImportExport.test.ts +158 -0
  298. package/Tests/Utils/NetworkDiscovery/AutoImportRuleMatcher.test.ts +93 -0
  299. package/Tests/Utils/NetworkSite/CidrMatchUtil.test.ts +138 -0
  300. package/Tests/Utils/NetworkSite/TypeHierarchyUtil.test.ts +174 -0
  301. package/Tests/Utils/Rules/RuleCriteriaMatcher.test.ts +1424 -0
  302. package/Tests/Utils/Rum/SessionIdentity.test.ts +72 -0
  303. package/Tests/Utils/Slo/SloBurnRateRuleState.test.ts +374 -28
  304. package/Tests/Utils/Telemetry/OriginAllowList.test.ts +118 -0
  305. package/Types/Dashboard/DashboardTemplates.ts +465 -0
  306. package/Types/Rules/RuleCriteria.ts +51 -0
  307. package/Types/Rules/RuleCriteriaFieldRegistry.ts +437 -0
  308. package/Types/Rum/SessionReplay.ts +75 -0
  309. package/Types/Rum/SessionReplayApi.ts +93 -0
  310. package/UI/Components/Alerts/Alert.tsx +102 -72
  311. package/UI/Components/Button/Button.tsx +4 -1
  312. package/UI/Components/Dropdown/Dropdown.tsx +2 -0
  313. package/UI/Components/Feed/Feed.tsx +15 -0
  314. package/UI/Components/Feed/useFeedItems.ts +227 -0
  315. package/UI/Components/Forms/BasicForm.tsx +42 -21
  316. package/UI/Components/Forms/ModelForm.tsx +80 -1
  317. package/UI/Components/Icon/Icon.tsx +3 -35
  318. package/UI/Components/ModelTable/ModelTable.tsx +19 -0
  319. package/UI/Components/Navbar/NavBar.tsx +1 -0
  320. package/UI/Components/RuleCriteria/RuleCriteriaBuilder.tsx +735 -0
  321. package/UI/Components/RuleCriteria/RuleCriteriaModelForm.tsx +209 -0
  322. package/UI/Components/RuleCriteria/RuleCriteriaModelTable.tsx +205 -0
  323. package/UI/Components/RuleCriteria/RuleCriteriaSummary.tsx +123 -0
  324. package/UI/Components/Table/Table.tsx +3 -0
  325. package/UI/Components/Table/TableBody.tsx +3 -0
  326. package/UI/Components/Table/TableRow.tsx +8 -2
  327. package/UI/Components/Telemetry/TelemetryRetentionConfigForm.tsx +14 -2
  328. package/UI/Styles/Theme.css +1 -0
  329. package/UI/Utils/LabelRuleImportExport.ts +114 -6
  330. package/UI/Utils/Navigation.ts +1 -2
  331. package/UI/esbuild-config.js +46 -0
  332. package/Utils/Faker.ts +93 -6
  333. package/Utils/LabelRuleImportExport.ts +295 -2
  334. package/Utils/NetworkDiscovery/AutoImportRuleMatcher.ts +108 -8
  335. package/Utils/NetworkSite/CidrMatchUtil.ts +102 -0
  336. package/Utils/NetworkSite/TypeHierarchyUtil.ts +152 -2
  337. package/Utils/Rules/RuleCriteriaMatcher.ts +931 -0
  338. package/Utils/Rum/SessionIdentity.ts +16 -0
  339. package/Utils/Slo/SloBurnRateRuleState.ts +87 -33
  340. package/Utils/Telemetry/OriginAllowList.ts +74 -0
  341. package/build/dist/Models/AnalyticsModels/RumSession.js +32 -0
  342. package/build/dist/Models/AnalyticsModels/RumSession.js.map +1 -1
  343. package/build/dist/Models/DatabaseModels/AlertEpisodeLabelRule.js +2 -2
  344. package/build/dist/Models/DatabaseModels/AlertEpisodeLabelRule.js.map +1 -1
  345. package/build/dist/Models/DatabaseModels/AlertEpisodeOnCallRule.js +2 -2
  346. package/build/dist/Models/DatabaseModels/AlertEpisodeOnCallRule.js.map +1 -1
  347. package/build/dist/Models/DatabaseModels/AlertEpisodeOwnerRule.js +2 -2
  348. package/build/dist/Models/DatabaseModels/AlertEpisodeOwnerRule.js.map +1 -1
  349. package/build/dist/Models/DatabaseModels/AlertEpisodePrivacyRule.js +2 -2
  350. package/build/dist/Models/DatabaseModels/AlertEpisodePrivacyRule.js.map +1 -1
  351. package/build/dist/Models/DatabaseModels/AlertGroupingRule.js +2 -2
  352. package/build/dist/Models/DatabaseModels/AlertGroupingRule.js.map +1 -1
  353. package/build/dist/Models/DatabaseModels/AlertLabelRule.js +2 -2
  354. package/build/dist/Models/DatabaseModels/AlertLabelRule.js.map +1 -1
  355. package/build/dist/Models/DatabaseModels/AlertOnCallRule.js +2 -2
  356. package/build/dist/Models/DatabaseModels/AlertOnCallRule.js.map +1 -1
  357. package/build/dist/Models/DatabaseModels/AlertOwnerRule.js +2 -2
  358. package/build/dist/Models/DatabaseModels/AlertOwnerRule.js.map +1 -1
  359. package/build/dist/Models/DatabaseModels/AlertPrivacyRule.js +2 -2
  360. package/build/dist/Models/DatabaseModels/AlertPrivacyRule.js.map +1 -1
  361. package/build/dist/Models/DatabaseModels/AlertReminderRule.js +6 -5
  362. package/build/dist/Models/DatabaseModels/AlertReminderRule.js.map +1 -1
  363. package/build/dist/Models/DatabaseModels/AutoRemediationRule.js +2 -2
  364. package/build/dist/Models/DatabaseModels/AutoRemediationRule.js.map +1 -1
  365. package/build/dist/Models/DatabaseModels/CephClusterLabelRule.js +2 -2
  366. package/build/dist/Models/DatabaseModels/CephClusterLabelRule.js.map +1 -1
  367. package/build/dist/Models/DatabaseModels/CephClusterOwnerRule.js +2 -2
  368. package/build/dist/Models/DatabaseModels/CephClusterOwnerRule.js.map +1 -1
  369. package/build/dist/Models/DatabaseModels/CloudResourceLabelRule.js +2 -2
  370. package/build/dist/Models/DatabaseModels/CloudResourceLabelRule.js.map +1 -1
  371. package/build/dist/Models/DatabaseModels/CloudResourceOwnerRule.js +2 -2
  372. package/build/dist/Models/DatabaseModels/CloudResourceOwnerRule.js.map +1 -1
  373. package/build/dist/Models/DatabaseModels/DashboardLabelRule.js +2 -2
  374. package/build/dist/Models/DatabaseModels/DashboardLabelRule.js.map +1 -1
  375. package/build/dist/Models/DatabaseModels/DashboardOwnerRule.js +2 -2
  376. package/build/dist/Models/DatabaseModels/DashboardOwnerRule.js.map +1 -1
  377. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/RelationOnlyRuleBaseModel.js +12 -0
  378. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/RelationOnlyRuleBaseModel.js.map +1 -0
  379. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/RuleBaseModel.js +50 -0
  380. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/RuleBaseModel.js.map +1 -0
  381. package/build/dist/Models/DatabaseModels/DockerHostLabelRule.js +2 -2
  382. package/build/dist/Models/DatabaseModels/DockerHostLabelRule.js.map +1 -1
  383. package/build/dist/Models/DatabaseModels/DockerHostOwnerRule.js +2 -2
  384. package/build/dist/Models/DatabaseModels/DockerHostOwnerRule.js.map +1 -1
  385. package/build/dist/Models/DatabaseModels/DockerSwarmClusterLabelRule.js +2 -2
  386. package/build/dist/Models/DatabaseModels/DockerSwarmClusterLabelRule.js.map +1 -1
  387. package/build/dist/Models/DatabaseModels/DockerSwarmClusterOwnerRule.js +2 -2
  388. package/build/dist/Models/DatabaseModels/DockerSwarmClusterOwnerRule.js.map +1 -1
  389. package/build/dist/Models/DatabaseModels/HostLabelRule.js +2 -2
  390. package/build/dist/Models/DatabaseModels/HostLabelRule.js.map +1 -1
  391. package/build/dist/Models/DatabaseModels/HostOwnerRule.js +2 -2
  392. package/build/dist/Models/DatabaseModels/HostOwnerRule.js.map +1 -1
  393. package/build/dist/Models/DatabaseModels/IncidentEpisodeLabelRule.js +2 -2
  394. package/build/dist/Models/DatabaseModels/IncidentEpisodeLabelRule.js.map +1 -1
  395. package/build/dist/Models/DatabaseModels/IncidentEpisodeOnCallRule.js +2 -2
  396. package/build/dist/Models/DatabaseModels/IncidentEpisodeOnCallRule.js.map +1 -1
  397. package/build/dist/Models/DatabaseModels/IncidentEpisodeOwnerRule.js +2 -2
  398. package/build/dist/Models/DatabaseModels/IncidentEpisodeOwnerRule.js.map +1 -1
  399. package/build/dist/Models/DatabaseModels/IncidentEpisodePrivacyRule.js +2 -2
  400. package/build/dist/Models/DatabaseModels/IncidentEpisodePrivacyRule.js.map +1 -1
  401. package/build/dist/Models/DatabaseModels/IncidentGroupingRule.js +2 -2
  402. package/build/dist/Models/DatabaseModels/IncidentGroupingRule.js.map +1 -1
  403. package/build/dist/Models/DatabaseModels/IncidentLabelRule.js +2 -2
  404. package/build/dist/Models/DatabaseModels/IncidentLabelRule.js.map +1 -1
  405. package/build/dist/Models/DatabaseModels/IncidentOnCallRule.js +2 -2
  406. package/build/dist/Models/DatabaseModels/IncidentOnCallRule.js.map +1 -1
  407. package/build/dist/Models/DatabaseModels/IncidentOwnerRule.js +2 -2
  408. package/build/dist/Models/DatabaseModels/IncidentOwnerRule.js.map +1 -1
  409. package/build/dist/Models/DatabaseModels/IncidentPrivacyRule.js +2 -2
  410. package/build/dist/Models/DatabaseModels/IncidentPrivacyRule.js.map +1 -1
  411. package/build/dist/Models/DatabaseModels/IncidentReminderRule.js +6 -5
  412. package/build/dist/Models/DatabaseModels/IncidentReminderRule.js.map +1 -1
  413. package/build/dist/Models/DatabaseModels/IncidentSlaRule.js +2 -2
  414. package/build/dist/Models/DatabaseModels/IncidentSlaRule.js.map +1 -1
  415. package/build/dist/Models/DatabaseModels/IncomingCallPolicy.js +3 -4
  416. package/build/dist/Models/DatabaseModels/IncomingCallPolicy.js.map +1 -1
  417. package/build/dist/Models/DatabaseModels/IncomingCallPolicyLabelRule.js +2 -2
  418. package/build/dist/Models/DatabaseModels/IncomingCallPolicyLabelRule.js.map +1 -1
  419. package/build/dist/Models/DatabaseModels/IncomingCallPolicyOwnerRule.js +2 -2
  420. package/build/dist/Models/DatabaseModels/IncomingCallPolicyOwnerRule.js.map +1 -1
  421. package/build/dist/Models/DatabaseModels/IncomingCallPolicyPhoneNumber.js +277 -0
  422. package/build/dist/Models/DatabaseModels/IncomingCallPolicyPhoneNumber.js.map +1 -0
  423. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  424. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  425. package/build/dist/Models/DatabaseModels/IoTFleetLabelRule.js +2 -2
  426. package/build/dist/Models/DatabaseModels/IoTFleetLabelRule.js.map +1 -1
  427. package/build/dist/Models/DatabaseModels/IoTFleetOwnerRule.js +2 -2
  428. package/build/dist/Models/DatabaseModels/IoTFleetOwnerRule.js.map +1 -1
  429. package/build/dist/Models/DatabaseModels/KubernetesClusterLabelRule.js +2 -2
  430. package/build/dist/Models/DatabaseModels/KubernetesClusterLabelRule.js.map +1 -1
  431. package/build/dist/Models/DatabaseModels/KubernetesClusterOwnerRule.js +2 -2
  432. package/build/dist/Models/DatabaseModels/KubernetesClusterOwnerRule.js.map +1 -1
  433. package/build/dist/Models/DatabaseModels/MonitorLabelRule.js +2 -2
  434. package/build/dist/Models/DatabaseModels/MonitorLabelRule.js.map +1 -1
  435. package/build/dist/Models/DatabaseModels/MonitorOwnerRule.js +2 -2
  436. package/build/dist/Models/DatabaseModels/MonitorOwnerRule.js.map +1 -1
  437. package/build/dist/Models/DatabaseModels/NetworkDeviceAutoImportRule.js +2 -2
  438. package/build/dist/Models/DatabaseModels/NetworkDeviceAutoImportRule.js.map +1 -1
  439. package/build/dist/Models/DatabaseModels/NetworkDeviceLabelRule.js +2 -2
  440. package/build/dist/Models/DatabaseModels/NetworkDeviceLabelRule.js.map +1 -1
  441. package/build/dist/Models/DatabaseModels/NetworkDeviceOwnerRule.js +2 -2
  442. package/build/dist/Models/DatabaseModels/NetworkDeviceOwnerRule.js.map +1 -1
  443. package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js +2 -2
  444. package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js.map +1 -1
  445. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyLabelRule.js +2 -2
  446. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyLabelRule.js.map +1 -1
  447. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyOwnerRule.js +2 -2
  448. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyOwnerRule.js.map +1 -1
  449. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLabelRule.js +2 -2
  450. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLabelRule.js.map +1 -1
  451. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleOwnerRule.js +2 -2
  452. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleOwnerRule.js.map +1 -1
  453. package/build/dist/Models/DatabaseModels/PodmanHostLabelRule.js +2 -2
  454. package/build/dist/Models/DatabaseModels/PodmanHostLabelRule.js.map +1 -1
  455. package/build/dist/Models/DatabaseModels/PodmanHostOwnerRule.js +2 -2
  456. package/build/dist/Models/DatabaseModels/PodmanHostOwnerRule.js.map +1 -1
  457. package/build/dist/Models/DatabaseModels/ProxmoxClusterLabelRule.js +2 -2
  458. package/build/dist/Models/DatabaseModels/ProxmoxClusterLabelRule.js.map +1 -1
  459. package/build/dist/Models/DatabaseModels/ProxmoxClusterOwnerRule.js +2 -2
  460. package/build/dist/Models/DatabaseModels/ProxmoxClusterOwnerRule.js.map +1 -1
  461. package/build/dist/Models/DatabaseModels/RumApplicationLabelRule.js +2 -2
  462. package/build/dist/Models/DatabaseModels/RumApplicationLabelRule.js.map +1 -1
  463. package/build/dist/Models/DatabaseModels/RumApplicationOwnerRule.js +2 -2
  464. package/build/dist/Models/DatabaseModels/RumApplicationOwnerRule.js.map +1 -1
  465. package/build/dist/Models/DatabaseModels/RunbookLabelRule.js +2 -2
  466. package/build/dist/Models/DatabaseModels/RunbookLabelRule.js.map +1 -1
  467. package/build/dist/Models/DatabaseModels/RunbookOwnerRule.js +2 -2
  468. package/build/dist/Models/DatabaseModels/RunbookOwnerRule.js.map +1 -1
  469. package/build/dist/Models/DatabaseModels/RunbookRule.js +2 -2
  470. package/build/dist/Models/DatabaseModels/RunbookRule.js.map +1 -1
  471. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceLabelRule.js +2 -2
  472. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceLabelRule.js.map +1 -1
  473. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceOwnerRule.js +2 -2
  474. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceOwnerRule.js.map +1 -1
  475. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceReminderRule.js +6 -5
  476. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceReminderRule.js.map +1 -1
  477. package/build/dist/Models/DatabaseModels/ServerlessFunctionLabelRule.js +2 -2
  478. package/build/dist/Models/DatabaseModels/ServerlessFunctionLabelRule.js.map +1 -1
  479. package/build/dist/Models/DatabaseModels/ServerlessFunctionOwnerRule.js +2 -2
  480. package/build/dist/Models/DatabaseModels/ServerlessFunctionOwnerRule.js.map +1 -1
  481. package/build/dist/Models/DatabaseModels/ServiceLabelRule.js +2 -2
  482. package/build/dist/Models/DatabaseModels/ServiceLabelRule.js.map +1 -1
  483. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js +281 -4
  484. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js.map +1 -1
  485. package/build/dist/Models/DatabaseModels/ServiceOwnerRule.js +2 -2
  486. package/build/dist/Models/DatabaseModels/ServiceOwnerRule.js.map +1 -1
  487. package/build/dist/Models/DatabaseModels/StatusPageLabelRule.js +2 -2
  488. package/build/dist/Models/DatabaseModels/StatusPageLabelRule.js.map +1 -1
  489. package/build/dist/Models/DatabaseModels/StatusPageMonitorRule.js +2 -2
  490. package/build/dist/Models/DatabaseModels/StatusPageMonitorRule.js.map +1 -1
  491. package/build/dist/Models/DatabaseModels/StatusPageOwnerRule.js +2 -2
  492. package/build/dist/Models/DatabaseModels/StatusPageOwnerRule.js.map +1 -1
  493. package/build/dist/Models/DatabaseModels/VMwareVCenterLabelRule.js +2 -2
  494. package/build/dist/Models/DatabaseModels/VMwareVCenterLabelRule.js.map +1 -1
  495. package/build/dist/Models/DatabaseModels/VMwareVCenterOwnerRule.js +2 -2
  496. package/build/dist/Models/DatabaseModels/VMwareVCenterOwnerRule.js.map +1 -1
  497. package/build/dist/Models/DatabaseModels/WorkflowLabelRule.js +2 -2
  498. package/build/dist/Models/DatabaseModels/WorkflowLabelRule.js.map +1 -1
  499. package/build/dist/Models/DatabaseModels/WorkflowOwnerRule.js +2 -2
  500. package/build/dist/Models/DatabaseModels/WorkflowOwnerRule.js.map +1 -1
  501. package/build/dist/Server/API/TelemetryAPI.js +211 -4
  502. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  503. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792400000000-AddSloBurnRateRuleIncidents.js +60 -0
  504. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792400000000-AddSloBurnRateRuleIncidents.js.map +1 -0
  505. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792500000000-AddConfigurableRuleCriteria.js +301 -0
  506. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792500000000-AddConfigurableRuleCriteria.js.map +1 -0
  507. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792600000000-AddIncomingCallPolicyPhoneNumbers.js +30 -0
  508. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792600000000-AddIncomingCallPolicyPhoneNumbers.js.map +1 -0
  509. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  510. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  511. package/build/dist/Server/Middleware/MultipartFormData.js +38 -21
  512. package/build/dist/Server/Middleware/MultipartFormData.js.map +1 -1
  513. package/build/dist/Server/Services/AlertEpisodeLabelRuleEngineService.js +17 -0
  514. package/build/dist/Server/Services/AlertEpisodeLabelRuleEngineService.js.map +1 -1
  515. package/build/dist/Server/Services/AlertEpisodeOnCallRuleEngineService.js +17 -0
  516. package/build/dist/Server/Services/AlertEpisodeOnCallRuleEngineService.js.map +1 -1
  517. package/build/dist/Server/Services/AlertEpisodeOwnerRuleEngineService.js +17 -0
  518. package/build/dist/Server/Services/AlertEpisodeOwnerRuleEngineService.js.map +1 -1
  519. package/build/dist/Server/Services/AlertEpisodePrivacyRuleEngineService.js +17 -0
  520. package/build/dist/Server/Services/AlertEpisodePrivacyRuleEngineService.js.map +1 -1
  521. package/build/dist/Server/Services/AlertGroupingEngineService.js +21 -0
  522. package/build/dist/Server/Services/AlertGroupingEngineService.js.map +1 -1
  523. package/build/dist/Server/Services/AlertLabelRuleEngineService.js +21 -0
  524. package/build/dist/Server/Services/AlertLabelRuleEngineService.js.map +1 -1
  525. package/build/dist/Server/Services/AlertOnCallRuleEngineService.js +21 -0
  526. package/build/dist/Server/Services/AlertOnCallRuleEngineService.js.map +1 -1
  527. package/build/dist/Server/Services/AlertOwnerRuleEngineService.js +21 -0
  528. package/build/dist/Server/Services/AlertOwnerRuleEngineService.js.map +1 -1
  529. package/build/dist/Server/Services/AlertPrivacyRuleEngineService.js +21 -0
  530. package/build/dist/Server/Services/AlertPrivacyRuleEngineService.js.map +1 -1
  531. package/build/dist/Server/Services/AlertReminderRuleService.js +44 -26
  532. package/build/dist/Server/Services/AlertReminderRuleService.js.map +1 -1
  533. package/build/dist/Server/Services/AutoRemediationRuleEngineService.js +54 -11
  534. package/build/dist/Server/Services/AutoRemediationRuleEngineService.js.map +1 -1
  535. package/build/dist/Server/Services/CephClusterLabelRuleEngineService.js +16 -0
  536. package/build/dist/Server/Services/CephClusterLabelRuleEngineService.js.map +1 -1
  537. package/build/dist/Server/Services/CephClusterOwnerRuleEngineService.js +16 -0
  538. package/build/dist/Server/Services/CephClusterOwnerRuleEngineService.js.map +1 -1
  539. package/build/dist/Server/Services/CloudResourceLabelRuleEngineService.js +16 -0
  540. package/build/dist/Server/Services/CloudResourceLabelRuleEngineService.js.map +1 -1
  541. package/build/dist/Server/Services/CloudResourceOwnerRuleEngineService.js +16 -0
  542. package/build/dist/Server/Services/CloudResourceOwnerRuleEngineService.js.map +1 -1
  543. package/build/dist/Server/Services/DashboardLabelRuleEngineService.js +16 -0
  544. package/build/dist/Server/Services/DashboardLabelRuleEngineService.js.map +1 -1
  545. package/build/dist/Server/Services/DashboardOwnerRuleEngineService.js +16 -0
  546. package/build/dist/Server/Services/DashboardOwnerRuleEngineService.js.map +1 -1
  547. package/build/dist/Server/Services/DatabaseService.js +235 -10
  548. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  549. package/build/dist/Server/Services/DockerHostLabelRuleEngineService.js +16 -0
  550. package/build/dist/Server/Services/DockerHostLabelRuleEngineService.js.map +1 -1
  551. package/build/dist/Server/Services/DockerHostOwnerRuleEngineService.js +16 -0
  552. package/build/dist/Server/Services/DockerHostOwnerRuleEngineService.js.map +1 -1
  553. package/build/dist/Server/Services/DockerSwarmClusterLabelRuleEngineService.js +16 -0
  554. package/build/dist/Server/Services/DockerSwarmClusterLabelRuleEngineService.js.map +1 -1
  555. package/build/dist/Server/Services/DockerSwarmClusterOwnerRuleEngineService.js +16 -0
  556. package/build/dist/Server/Services/DockerSwarmClusterOwnerRuleEngineService.js.map +1 -1
  557. package/build/dist/Server/Services/HostLabelRuleEngineService.js +12 -0
  558. package/build/dist/Server/Services/HostLabelRuleEngineService.js.map +1 -1
  559. package/build/dist/Server/Services/HostOwnerRuleEngineService.js +12 -0
  560. package/build/dist/Server/Services/HostOwnerRuleEngineService.js.map +1 -1
  561. package/build/dist/Server/Services/IncidentEpisodeLabelRuleEngineService.js +17 -0
  562. package/build/dist/Server/Services/IncidentEpisodeLabelRuleEngineService.js.map +1 -1
  563. package/build/dist/Server/Services/IncidentEpisodeOnCallRuleEngineService.js +17 -0
  564. package/build/dist/Server/Services/IncidentEpisodeOnCallRuleEngineService.js.map +1 -1
  565. package/build/dist/Server/Services/IncidentEpisodeOwnerRuleEngineService.js +17 -0
  566. package/build/dist/Server/Services/IncidentEpisodeOwnerRuleEngineService.js.map +1 -1
  567. package/build/dist/Server/Services/IncidentEpisodePrivacyRuleEngineService.js +17 -0
  568. package/build/dist/Server/Services/IncidentEpisodePrivacyRuleEngineService.js.map +1 -1
  569. package/build/dist/Server/Services/IncidentGroupingEngineService.js +39 -13
  570. package/build/dist/Server/Services/IncidentGroupingEngineService.js.map +1 -1
  571. package/build/dist/Server/Services/IncidentLabelRuleEngineService.js +39 -9
  572. package/build/dist/Server/Services/IncidentLabelRuleEngineService.js.map +1 -1
  573. package/build/dist/Server/Services/IncidentOnCallRuleEngineService.js +39 -10
  574. package/build/dist/Server/Services/IncidentOnCallRuleEngineService.js.map +1 -1
  575. package/build/dist/Server/Services/IncidentOwnerRuleEngineService.js +39 -10
  576. package/build/dist/Server/Services/IncidentOwnerRuleEngineService.js.map +1 -1
  577. package/build/dist/Server/Services/IncidentPrivacyRuleEngineService.js +39 -10
  578. package/build/dist/Server/Services/IncidentPrivacyRuleEngineService.js.map +1 -1
  579. package/build/dist/Server/Services/IncidentReminderRuleService.js +44 -26
  580. package/build/dist/Server/Services/IncidentReminderRuleService.js.map +1 -1
  581. package/build/dist/Server/Services/IncidentSlaRuleService.js +33 -12
  582. package/build/dist/Server/Services/IncidentSlaRuleService.js.map +1 -1
  583. package/build/dist/Server/Services/IncomingCallPolicyLabelRuleEngineService.js +16 -0
  584. package/build/dist/Server/Services/IncomingCallPolicyLabelRuleEngineService.js.map +1 -1
  585. package/build/dist/Server/Services/IncomingCallPolicyOwnerRuleEngineService.js +16 -0
  586. package/build/dist/Server/Services/IncomingCallPolicyOwnerRuleEngineService.js.map +1 -1
  587. package/build/dist/Server/Services/IncomingCallPolicyPhoneNumberService.js +127 -0
  588. package/build/dist/Server/Services/IncomingCallPolicyPhoneNumberService.js.map +1 -0
  589. package/build/dist/Server/Services/IncomingCallPolicyService.js +187 -4
  590. package/build/dist/Server/Services/IncomingCallPolicyService.js.map +1 -1
  591. package/build/dist/Server/Services/Index.js +2 -0
  592. package/build/dist/Server/Services/Index.js.map +1 -1
  593. package/build/dist/Server/Services/IoTFleetLabelRuleEngineService.js +16 -0
  594. package/build/dist/Server/Services/IoTFleetLabelRuleEngineService.js.map +1 -1
  595. package/build/dist/Server/Services/IoTFleetOwnerRuleEngineService.js +16 -0
  596. package/build/dist/Server/Services/IoTFleetOwnerRuleEngineService.js.map +1 -1
  597. package/build/dist/Server/Services/KubernetesClusterLabelRuleEngineService.js +16 -0
  598. package/build/dist/Server/Services/KubernetesClusterLabelRuleEngineService.js.map +1 -1
  599. package/build/dist/Server/Services/KubernetesClusterOwnerRuleEngineService.js +16 -0
  600. package/build/dist/Server/Services/KubernetesClusterOwnerRuleEngineService.js.map +1 -1
  601. package/build/dist/Server/Services/LabelService.js +39 -7
  602. package/build/dist/Server/Services/LabelService.js.map +1 -1
  603. package/build/dist/Server/Services/MonitorLabelRuleEngineService.js +16 -0
  604. package/build/dist/Server/Services/MonitorLabelRuleEngineService.js.map +1 -1
  605. package/build/dist/Server/Services/MonitorOwnerRuleEngineService.js +16 -0
  606. package/build/dist/Server/Services/MonitorOwnerRuleEngineService.js.map +1 -1
  607. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +2 -0
  608. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
  609. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js +57 -1
  610. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js.map +1 -1
  611. package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js +17 -0
  612. package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js.map +1 -1
  613. package/build/dist/Server/Services/NetworkDeviceOwnerRuleEngineService.js +16 -0
  614. package/build/dist/Server/Services/NetworkDeviceOwnerRuleEngineService.js.map +1 -1
  615. package/build/dist/Server/Services/NetworkDeviceService.js +2 -0
  616. package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
  617. package/build/dist/Server/Services/NetworkSiteAssignmentRuleService.js +56 -1
  618. package/build/dist/Server/Services/NetworkSiteAssignmentRuleService.js.map +1 -1
  619. package/build/dist/Server/Services/NetworkSiteService.js +187 -22
  620. package/build/dist/Server/Services/NetworkSiteService.js.map +1 -1
  621. package/build/dist/Server/Services/NetworkSiteTypeService.js +126 -51
  622. package/build/dist/Server/Services/NetworkSiteTypeService.js.map +1 -1
  623. package/build/dist/Server/Services/OnCallDutyPolicyLabelRuleEngineService.js +16 -0
  624. package/build/dist/Server/Services/OnCallDutyPolicyLabelRuleEngineService.js.map +1 -1
  625. package/build/dist/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.js +16 -0
  626. package/build/dist/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.js.map +1 -1
  627. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.js +16 -0
  628. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.js.map +1 -1
  629. package/build/dist/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.js +16 -0
  630. package/build/dist/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.js.map +1 -1
  631. package/build/dist/Server/Services/PodmanHostLabelRuleEngineService.js +16 -0
  632. package/build/dist/Server/Services/PodmanHostLabelRuleEngineService.js.map +1 -1
  633. package/build/dist/Server/Services/PodmanHostOwnerRuleEngineService.js +16 -0
  634. package/build/dist/Server/Services/PodmanHostOwnerRuleEngineService.js.map +1 -1
  635. package/build/dist/Server/Services/ProjectCallSMSConfigService.js +115 -6
  636. package/build/dist/Server/Services/ProjectCallSMSConfigService.js.map +1 -1
  637. package/build/dist/Server/Services/ProxmoxClusterLabelRuleEngineService.js +16 -0
  638. package/build/dist/Server/Services/ProxmoxClusterLabelRuleEngineService.js.map +1 -1
  639. package/build/dist/Server/Services/ProxmoxClusterOwnerRuleEngineService.js +16 -0
  640. package/build/dist/Server/Services/ProxmoxClusterOwnerRuleEngineService.js.map +1 -1
  641. package/build/dist/Server/Services/RumApplicationLabelRuleEngineService.js +16 -0
  642. package/build/dist/Server/Services/RumApplicationLabelRuleEngineService.js.map +1 -1
  643. package/build/dist/Server/Services/RumApplicationOwnerRuleEngineService.js +16 -0
  644. package/build/dist/Server/Services/RumApplicationOwnerRuleEngineService.js.map +1 -1
  645. package/build/dist/Server/Services/RunbookLabelRuleEngineService.js +16 -0
  646. package/build/dist/Server/Services/RunbookLabelRuleEngineService.js.map +1 -1
  647. package/build/dist/Server/Services/RunbookOwnerRuleEngineService.js +16 -0
  648. package/build/dist/Server/Services/RunbookOwnerRuleEngineService.js.map +1 -1
  649. package/build/dist/Server/Services/RunbookRuleEngineService.js +12 -0
  650. package/build/dist/Server/Services/RunbookRuleEngineService.js.map +1 -1
  651. package/build/dist/Server/Services/ScheduledMaintenanceLabelRuleEngineService.js +38 -9
  652. package/build/dist/Server/Services/ScheduledMaintenanceLabelRuleEngineService.js.map +1 -1
  653. package/build/dist/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.js +38 -10
  654. package/build/dist/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.js.map +1 -1
  655. package/build/dist/Server/Services/ScheduledMaintenanceReminderRuleService.js +32 -14
  656. package/build/dist/Server/Services/ScheduledMaintenanceReminderRuleService.js.map +1 -1
  657. package/build/dist/Server/Services/ServerlessFunctionLabelRuleEngineService.js +16 -0
  658. package/build/dist/Server/Services/ServerlessFunctionLabelRuleEngineService.js.map +1 -1
  659. package/build/dist/Server/Services/ServerlessFunctionOwnerRuleEngineService.js +16 -0
  660. package/build/dist/Server/Services/ServerlessFunctionOwnerRuleEngineService.js.map +1 -1
  661. package/build/dist/Server/Services/ServiceLabelRuleEngineService.js +16 -0
  662. package/build/dist/Server/Services/ServiceLabelRuleEngineService.js.map +1 -1
  663. package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js +554 -12
  664. package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js.map +1 -1
  665. package/build/dist/Server/Services/ServiceLevelObjectiveService.js +50 -14
  666. package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -1
  667. package/build/dist/Server/Services/ServiceOwnerRuleEngineService.js +16 -0
  668. package/build/dist/Server/Services/ServiceOwnerRuleEngineService.js.map +1 -1
  669. package/build/dist/Server/Services/StatusPageLabelRuleEngineService.js +16 -0
  670. package/build/dist/Server/Services/StatusPageLabelRuleEngineService.js.map +1 -1
  671. package/build/dist/Server/Services/StatusPageMonitorRuleEngineService.js +25 -2
  672. package/build/dist/Server/Services/StatusPageMonitorRuleEngineService.js.map +1 -1
  673. package/build/dist/Server/Services/StatusPageMonitorRuleService.js +19 -1
  674. package/build/dist/Server/Services/StatusPageMonitorRuleService.js.map +1 -1
  675. package/build/dist/Server/Services/StatusPageOwnerRuleEngineService.js +16 -0
  676. package/build/dist/Server/Services/StatusPageOwnerRuleEngineService.js.map +1 -1
  677. package/build/dist/Server/Services/UserService.js +14 -49
  678. package/build/dist/Server/Services/UserService.js.map +1 -1
  679. package/build/dist/Server/Services/VMwareVCenterLabelRuleEngineService.js +16 -0
  680. package/build/dist/Server/Services/VMwareVCenterLabelRuleEngineService.js.map +1 -1
  681. package/build/dist/Server/Services/VMwareVCenterOwnerRuleEngineService.js +16 -0
  682. package/build/dist/Server/Services/VMwareVCenterOwnerRuleEngineService.js.map +1 -1
  683. package/build/dist/Server/Services/WorkflowLabelRuleEngineService.js +16 -0
  684. package/build/dist/Server/Services/WorkflowLabelRuleEngineService.js.map +1 -1
  685. package/build/dist/Server/Services/WorkflowOwnerRuleEngineService.js +16 -0
  686. package/build/dist/Server/Services/WorkflowOwnerRuleEngineService.js.map +1 -1
  687. package/build/dist/Server/Types/Database/QueryHelper.js +67 -0
  688. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  689. package/build/dist/Server/Utils/AI/Toolbox/SloTools.js +21 -4
  690. package/build/dist/Server/Utils/AI/Toolbox/SloTools.js.map +1 -1
  691. package/build/dist/Server/Utils/IncomingCallPhoneNumber.js +9 -3
  692. package/build/dist/Server/Utils/IncomingCallPhoneNumber.js.map +1 -1
  693. package/build/dist/Server/Utils/Profiling.js +10 -1
  694. package/build/dist/Server/Utils/Profiling.js.map +1 -1
  695. package/build/dist/Server/Utils/Rules/MonitorRuleCriteriaCache.js +30 -0
  696. package/build/dist/Server/Utils/Rules/MonitorRuleCriteriaCache.js.map +1 -0
  697. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +344 -0
  698. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
  699. package/build/dist/Server/Utils/Telemetry.js +1 -1
  700. package/build/dist/Server/Utils/Telemetry.js.map +1 -1
  701. package/build/dist/Server/Utils/VendorAssets.js +2 -0
  702. package/build/dist/Server/Utils/VendorAssets.js.map +1 -1
  703. package/build/dist/Types/Dashboard/DashboardTemplates.js +425 -0
  704. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  705. package/build/dist/Types/Rules/RuleCriteria.js +18 -0
  706. package/build/dist/Types/Rules/RuleCriteria.js.map +1 -0
  707. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +426 -0
  708. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -0
  709. package/build/dist/Types/Rum/SessionReplay.js +64 -0
  710. package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
  711. package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -1
  712. package/build/dist/UI/Components/Alerts/Alert.js +63 -41
  713. package/build/dist/UI/Components/Alerts/Alert.js.map +1 -1
  714. package/build/dist/UI/Components/Button/Button.js +3 -1
  715. package/build/dist/UI/Components/Button/Button.js.map +1 -1
  716. package/build/dist/UI/Components/Dropdown/Dropdown.js +1 -1
  717. package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
  718. package/build/dist/UI/Components/Feed/Feed.js +4 -1
  719. package/build/dist/UI/Components/Feed/Feed.js.map +1 -1
  720. package/build/dist/UI/Components/Feed/useFeedItems.js +137 -0
  721. package/build/dist/UI/Components/Feed/useFeedItems.js.map +1 -0
  722. package/build/dist/UI/Components/Forms/BasicForm.js +38 -19
  723. package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
  724. package/build/dist/UI/Components/Forms/ModelForm.js +65 -1
  725. package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
  726. package/build/dist/UI/Components/Icon/Icon.js +3 -35
  727. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  728. package/build/dist/UI/Components/ModelTable/ModelTable.js +12 -1
  729. package/build/dist/UI/Components/ModelTable/ModelTable.js.map +1 -1
  730. package/build/dist/UI/Components/Navbar/NavBar.js +1 -0
  731. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  732. package/build/dist/UI/Components/RuleCriteria/RuleCriteriaBuilder.js +383 -0
  733. package/build/dist/UI/Components/RuleCriteria/RuleCriteriaBuilder.js.map +1 -0
  734. package/build/dist/UI/Components/RuleCriteria/RuleCriteriaModelForm.js +124 -0
  735. package/build/dist/UI/Components/RuleCriteria/RuleCriteriaModelForm.js.map +1 -0
  736. package/build/dist/UI/Components/RuleCriteria/RuleCriteriaModelTable.js +126 -0
  737. package/build/dist/UI/Components/RuleCriteria/RuleCriteriaModelTable.js.map +1 -0
  738. package/build/dist/UI/Components/RuleCriteria/RuleCriteriaSummary.js +63 -0
  739. package/build/dist/UI/Components/RuleCriteria/RuleCriteriaSummary.js.map +1 -0
  740. package/build/dist/UI/Components/Table/Table.js +1 -1
  741. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  742. package/build/dist/UI/Components/Table/TableBody.js +4 -2
  743. package/build/dist/UI/Components/Table/TableBody.js.map +1 -1
  744. package/build/dist/UI/Components/Table/TableRow.js +3 -2
  745. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  746. package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigForm.js +14 -2
  747. package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigForm.js.map +1 -1
  748. package/build/dist/UI/Utils/LabelRuleImportExport.js +81 -5
  749. package/build/dist/UI/Utils/LabelRuleImportExport.js.map +1 -1
  750. package/build/dist/UI/Utils/Navigation.js.map +1 -1
  751. package/build/dist/Utils/Faker.js +76 -6
  752. package/build/dist/Utils/Faker.js.map +1 -1
  753. package/build/dist/Utils/LabelRuleImportExport.js +157 -3
  754. package/build/dist/Utils/LabelRuleImportExport.js.map +1 -1
  755. package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js +81 -5
  756. package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js.map +1 -1
  757. package/build/dist/Utils/NetworkSite/CidrMatchUtil.js +77 -0
  758. package/build/dist/Utils/NetworkSite/CidrMatchUtil.js.map +1 -1
  759. package/build/dist/Utils/NetworkSite/TypeHierarchyUtil.js +109 -2
  760. package/build/dist/Utils/NetworkSite/TypeHierarchyUtil.js.map +1 -1
  761. package/build/dist/Utils/Rules/RuleCriteriaMatcher.js +526 -0
  762. package/build/dist/Utils/Rules/RuleCriteriaMatcher.js.map +1 -0
  763. package/build/dist/Utils/Rum/SessionIdentity.js +13 -1
  764. package/build/dist/Utils/Rum/SessionIdentity.js.map +1 -1
  765. package/build/dist/Utils/Slo/SloBurnRateRuleState.js +28 -15
  766. package/build/dist/Utils/Slo/SloBurnRateRuleState.js.map +1 -1
  767. package/build/dist/Utils/Telemetry/OriginAllowList.js +61 -0
  768. package/build/dist/Utils/Telemetry/OriginAllowList.js.map +1 -1
  769. package/package.json +20 -20
@@ -111,13 +111,17 @@ function fakeSite(overrides: Record<string, unknown>): NetworkSite {
111
111
 
112
112
  function fakeNetworkSiteType(data: {
113
113
  id: ObjectID;
114
+ name?: string | undefined;
114
115
  parentNetworkSiteTypeId?: ObjectID | undefined;
115
116
  projectId?: ObjectID | undefined;
117
+ isUnitLevel?: boolean | undefined;
116
118
  }): any {
117
119
  return {
118
120
  id: data.id,
119
121
  _id: data.id.toString(),
122
+ name: data.name,
120
123
  projectId: data.projectId || PROJECT_ID,
124
+ isUnitLevel: data.isUnitLevel,
121
125
  parentNetworkSiteTypeId: data.parentNetworkSiteTypeId,
122
126
  };
123
127
  }
@@ -1249,7 +1253,12 @@ describe("NetworkSiteService site-type hierarchy enforcement on create", () => {
1249
1253
  );
1250
1254
  });
1251
1255
 
1252
- it("rejects a parent for a root type", async () => {
1256
+ /*
1257
+ * Regression block for GitHub issue #3744. Each of these placements was
1258
+ * refused before the placement rule was relaxed to "a parent may be any site
1259
+ * whose type is not below this one's".
1260
+ */
1261
+ it("accepts a parent of the same type", async () => {
1253
1262
  mockNetworkSiteTypes([fakeNetworkSiteType({ id: ROOT_SITE_TYPE_ID })]);
1254
1263
  jest.spyOn(NetworkSiteService, "findOneById").mockResolvedValue(
1255
1264
  fakeSite({
@@ -1258,22 +1267,25 @@ describe("NetworkSiteService site-type hierarchy enforcement on create", () => {
1258
1267
  networkSiteTypeId: ROOT_SITE_TYPE_ID,
1259
1268
  }),
1260
1269
  );
1270
+ jest
1271
+ .spyOn(NetworkSiteService, "getMaterializedPathForSite")
1272
+ .mockResolvedValue(`/${PARENT_SITE_ID.toString()}/`);
1261
1273
 
1262
- await expect(
1263
- (NetworkSiteService as any).onBeforeCreate({
1264
- data: {
1265
- projectId: PROJECT_ID,
1266
- networkSiteTypeId: ROOT_SITE_TYPE_ID,
1267
- parentSiteId: PARENT_SITE_ID,
1268
- },
1269
- props: { tenantId: PROJECT_ID },
1270
- }),
1271
- ).rejects.toThrow(
1272
- "A site with a root network site type cannot have a parent site.",
1274
+ const result: any = await (NetworkSiteService as any).onBeforeCreate({
1275
+ data: {
1276
+ projectId: PROJECT_ID,
1277
+ networkSiteTypeId: ROOT_SITE_TYPE_ID,
1278
+ parentSiteId: PARENT_SITE_ID,
1279
+ },
1280
+ props: { tenantId: PROJECT_ID },
1281
+ });
1282
+
1283
+ expect(result.carryForward.parentPath).toBe(
1284
+ `/${PARENT_SITE_ID.toString()}/`,
1273
1285
  );
1274
1286
  });
1275
1287
 
1276
- it("requires a parent for a type configured below another type", async () => {
1288
+ it("accepts no parent for a type configured below another type", async () => {
1277
1289
  mockNetworkSiteTypes([
1278
1290
  fakeNetworkSiteType({
1279
1291
  id: CHILD_SITE_TYPE_ID,
@@ -1281,15 +1293,15 @@ describe("NetworkSiteService site-type hierarchy enforcement on create", () => {
1281
1293
  }),
1282
1294
  ]);
1283
1295
 
1284
- await expect(
1285
- (NetworkSiteService as any).onBeforeCreate({
1286
- data: {
1287
- projectId: PROJECT_ID,
1288
- networkSiteTypeId: CHILD_SITE_TYPE_ID,
1289
- },
1290
- props: { tenantId: PROJECT_ID },
1291
- }),
1292
- ).rejects.toThrow("This network site type requires a parent site.");
1296
+ const result: any = await (NetworkSiteService as any).onBeforeCreate({
1297
+ data: {
1298
+ projectId: PROJECT_ID,
1299
+ networkSiteTypeId: CHILD_SITE_TYPE_ID,
1300
+ },
1301
+ props: { tenantId: PROJECT_ID },
1302
+ });
1303
+
1304
+ expect(result.carryForward.parentPath).toBeNull();
1293
1305
  });
1294
1306
 
1295
1307
  it("accepts a direct parent with exactly the configured type through relation fields", async () => {
@@ -1298,6 +1310,7 @@ describe("NetworkSiteService site-type hierarchy enforcement on create", () => {
1298
1310
  id: CHILD_SITE_TYPE_ID,
1299
1311
  parentNetworkSiteTypeId: ROOT_SITE_TYPE_ID,
1300
1312
  }),
1313
+ fakeNetworkSiteType({ id: ROOT_SITE_TYPE_ID }),
1301
1314
  ]);
1302
1315
  jest.spyOn(NetworkSiteService, "findOneById").mockResolvedValue(
1303
1316
  fakeSite({
@@ -1324,12 +1337,15 @@ describe("NetworkSiteService site-type hierarchy enforcement on create", () => {
1324
1337
  );
1325
1338
  });
1326
1339
 
1327
- it("rejects a parent whose type is not the configured direct parent", async () => {
1340
+ // The issue's own case: a Market (nested type) under an Other (root type).
1341
+ it("accepts a parent whose type is unrelated to the configured one", async () => {
1328
1342
  mockNetworkSiteTypes([
1329
1343
  fakeNetworkSiteType({
1330
1344
  id: CHILD_SITE_TYPE_ID,
1345
+ name: "Market",
1331
1346
  parentNetworkSiteTypeId: ROOT_SITE_TYPE_ID,
1332
1347
  }),
1348
+ fakeNetworkSiteType({ id: ALTERNATE_ROOT_SITE_TYPE_ID, name: "Other" }),
1333
1349
  ]);
1334
1350
  jest.spyOn(NetworkSiteService, "findOneById").mockResolvedValue(
1335
1351
  fakeSite({
@@ -1338,18 +1354,223 @@ describe("NetworkSiteService site-type hierarchy enforcement on create", () => {
1338
1354
  networkSiteTypeId: ALTERNATE_ROOT_SITE_TYPE_ID,
1339
1355
  }),
1340
1356
  );
1357
+ jest
1358
+ .spyOn(NetworkSiteService, "getMaterializedPathForSite")
1359
+ .mockResolvedValue(`/${PARENT_SITE_ID.toString()}/`);
1360
+
1361
+ const result: any = await (NetworkSiteService as any).onBeforeCreate({
1362
+ data: {
1363
+ projectId: PROJECT_ID,
1364
+ networkSiteTypeId: CHILD_SITE_TYPE_ID,
1365
+ parentSiteId: PARENT_SITE_ID,
1366
+ },
1367
+ props: { tenantId: PROJECT_ID },
1368
+ });
1369
+
1370
+ expect(result.carryForward.parentPath).toBe(
1371
+ `/${PARENT_SITE_ID.toString()}/`,
1372
+ );
1373
+ });
1374
+
1375
+ it("accepts a parent that skips a configured level", async () => {
1376
+ mockNetworkSiteTypes([
1377
+ fakeNetworkSiteType({
1378
+ id: GRANDCHILD_SITE_TYPE_ID,
1379
+ parentNetworkSiteTypeId: CHILD_SITE_TYPE_ID,
1380
+ }),
1381
+ fakeNetworkSiteType({
1382
+ id: CHILD_SITE_TYPE_ID,
1383
+ parentNetworkSiteTypeId: ROOT_SITE_TYPE_ID,
1384
+ }),
1385
+ fakeNetworkSiteType({ id: ROOT_SITE_TYPE_ID }),
1386
+ ]);
1387
+ jest.spyOn(NetworkSiteService, "findOneById").mockResolvedValue(
1388
+ fakeSite({
1389
+ id: PARENT_SITE_ID,
1390
+ _id: PARENT_SITE_ID.toString(),
1391
+ networkSiteTypeId: ROOT_SITE_TYPE_ID,
1392
+ }),
1393
+ );
1394
+ jest
1395
+ .spyOn(NetworkSiteService, "getMaterializedPathForSite")
1396
+ .mockResolvedValue(`/${PARENT_SITE_ID.toString()}/`);
1397
+
1398
+ const result: any = await (NetworkSiteService as any).onBeforeCreate({
1399
+ data: {
1400
+ projectId: PROJECT_ID,
1401
+ networkSiteTypeId: GRANDCHILD_SITE_TYPE_ID,
1402
+ parentSiteId: PARENT_SITE_ID,
1403
+ },
1404
+ props: { tenantId: PROJECT_ID },
1405
+ });
1406
+
1407
+ expect(result.carryForward.parentPath).toBe(
1408
+ `/${PARENT_SITE_ID.toString()}/`,
1409
+ );
1410
+ });
1411
+
1412
+ it("accepts a parent that has no site type at all", async () => {
1413
+ mockNetworkSiteTypes([
1414
+ fakeNetworkSiteType({
1415
+ id: CHILD_SITE_TYPE_ID,
1416
+ parentNetworkSiteTypeId: ROOT_SITE_TYPE_ID,
1417
+ }),
1418
+ ]);
1419
+ jest.spyOn(NetworkSiteService, "findOneById").mockResolvedValue(
1420
+ fakeSite({
1421
+ id: PARENT_SITE_ID,
1422
+ _id: PARENT_SITE_ID.toString(),
1423
+ }),
1424
+ );
1425
+ jest
1426
+ .spyOn(NetworkSiteService, "getMaterializedPathForSite")
1427
+ .mockResolvedValue(`/${PARENT_SITE_ID.toString()}/`);
1428
+
1429
+ const result: any = await (NetworkSiteService as any).onBeforeCreate({
1430
+ data: {
1431
+ projectId: PROJECT_ID,
1432
+ networkSiteTypeId: CHILD_SITE_TYPE_ID,
1433
+ parentSiteId: PARENT_SITE_ID,
1434
+ },
1435
+ props: { tenantId: PROJECT_ID },
1436
+ });
1437
+
1438
+ expect(result.carryForward.parentPath).toBe(
1439
+ `/${PARENT_SITE_ID.toString()}/`,
1440
+ );
1441
+ });
1442
+
1443
+ it("rejects a parent whose type sits below this site's type", async () => {
1444
+ mockNetworkSiteTypes([
1445
+ fakeNetworkSiteType({ id: ROOT_SITE_TYPE_ID, name: "Region" }),
1446
+ fakeNetworkSiteType({
1447
+ id: CHILD_SITE_TYPE_ID,
1448
+ name: "Market",
1449
+ parentNetworkSiteTypeId: ROOT_SITE_TYPE_ID,
1450
+ }),
1451
+ ]);
1452
+ jest.spyOn(NetworkSiteService, "findOneById").mockResolvedValue(
1453
+ fakeSite({
1454
+ id: PARENT_SITE_ID,
1455
+ _id: PARENT_SITE_ID.toString(),
1456
+ networkSiteTypeId: CHILD_SITE_TYPE_ID,
1457
+ }),
1458
+ );
1341
1459
 
1342
1460
  await expect(
1343
1461
  (NetworkSiteService as any).onBeforeCreate({
1344
1462
  data: {
1345
1463
  projectId: PROJECT_ID,
1346
- networkSiteTypeId: CHILD_SITE_TYPE_ID,
1464
+ networkSiteTypeId: ROOT_SITE_TYPE_ID,
1465
+ parentSiteId: PARENT_SITE_ID,
1466
+ },
1467
+ props: { tenantId: PROJECT_ID },
1468
+ }),
1469
+ ).rejects.toThrow(
1470
+ 'A site of network site type "Region" cannot be placed under a site of network site type "Market", because "Market" sits below "Region" in the site type hierarchy.',
1471
+ );
1472
+ });
1473
+
1474
+ it("rejects a parent whose type sits below it through a skipped level", async () => {
1475
+ mockNetworkSiteTypes([
1476
+ fakeNetworkSiteType({ id: ROOT_SITE_TYPE_ID, name: "Region" }),
1477
+ fakeNetworkSiteType({
1478
+ id: CHILD_SITE_TYPE_ID,
1479
+ name: "Franchisee",
1480
+ parentNetworkSiteTypeId: ROOT_SITE_TYPE_ID,
1481
+ }),
1482
+ fakeNetworkSiteType({
1483
+ id: GRANDCHILD_SITE_TYPE_ID,
1484
+ name: "Market",
1485
+ parentNetworkSiteTypeId: CHILD_SITE_TYPE_ID,
1486
+ }),
1487
+ ]);
1488
+ jest.spyOn(NetworkSiteService, "findOneById").mockResolvedValue(
1489
+ fakeSite({
1490
+ id: PARENT_SITE_ID,
1491
+ _id: PARENT_SITE_ID.toString(),
1492
+ networkSiteTypeId: GRANDCHILD_SITE_TYPE_ID,
1493
+ }),
1494
+ );
1495
+
1496
+ await expect(
1497
+ (NetworkSiteService as any).onBeforeCreate({
1498
+ data: {
1499
+ projectId: PROJECT_ID,
1500
+ networkSiteTypeId: ROOT_SITE_TYPE_ID,
1501
+ parentSiteId: PARENT_SITE_ID,
1502
+ },
1503
+ props: { tenantId: PROJECT_ID },
1504
+ }),
1505
+ ).rejects.toThrow('"Market" sits below "Region"');
1506
+ });
1507
+
1508
+ it("rejects a parent whose type is the unit level", async () => {
1509
+ mockNetworkSiteTypes([
1510
+ fakeNetworkSiteType({ id: ALTERNATE_ROOT_SITE_TYPE_ID, name: "Other" }),
1511
+ fakeNetworkSiteType({
1512
+ id: CHILD_SITE_TYPE_ID,
1513
+ name: "Unit",
1514
+ parentNetworkSiteTypeId: ROOT_SITE_TYPE_ID,
1515
+ isUnitLevel: true,
1516
+ }),
1517
+ ]);
1518
+ jest.spyOn(NetworkSiteService, "findOneById").mockResolvedValue(
1519
+ fakeSite({
1520
+ id: PARENT_SITE_ID,
1521
+ _id: PARENT_SITE_ID.toString(),
1522
+ networkSiteTypeId: CHILD_SITE_TYPE_ID,
1523
+ }),
1524
+ );
1525
+
1526
+ await expect(
1527
+ (NetworkSiteService as any).onBeforeCreate({
1528
+ data: {
1529
+ projectId: PROJECT_ID,
1530
+ networkSiteTypeId: ALTERNATE_ROOT_SITE_TYPE_ID,
1347
1531
  parentSiteId: PARENT_SITE_ID,
1348
1532
  },
1349
1533
  props: { tenantId: PROJECT_ID },
1350
1534
  }),
1351
1535
  ).rejects.toThrow(
1352
- "Parent site must use the configured parent network site type.",
1536
+ 'Sites of network site type "Unit" are unit level, so they cannot have child sites.',
1537
+ );
1538
+ });
1539
+
1540
+ it("terminates on a cyclic site type catalog instead of looping forever", async () => {
1541
+ mockNetworkSiteTypes([
1542
+ fakeNetworkSiteType({
1543
+ id: ROOT_SITE_TYPE_ID,
1544
+ parentNetworkSiteTypeId: CHILD_SITE_TYPE_ID,
1545
+ }),
1546
+ fakeNetworkSiteType({
1547
+ id: CHILD_SITE_TYPE_ID,
1548
+ parentNetworkSiteTypeId: ROOT_SITE_TYPE_ID,
1549
+ }),
1550
+ fakeNetworkSiteType({ id: ALTERNATE_ROOT_SITE_TYPE_ID }),
1551
+ ]);
1552
+ jest.spyOn(NetworkSiteService, "findOneById").mockResolvedValue(
1553
+ fakeSite({
1554
+ id: PARENT_SITE_ID,
1555
+ _id: PARENT_SITE_ID.toString(),
1556
+ networkSiteTypeId: ROOT_SITE_TYPE_ID,
1557
+ }),
1558
+ );
1559
+ jest
1560
+ .spyOn(NetworkSiteService, "getMaterializedPathForSite")
1561
+ .mockResolvedValue(`/${PARENT_SITE_ID.toString()}/`);
1562
+
1563
+ const result: any = await (NetworkSiteService as any).onBeforeCreate({
1564
+ data: {
1565
+ projectId: PROJECT_ID,
1566
+ networkSiteTypeId: ALTERNATE_ROOT_SITE_TYPE_ID,
1567
+ parentSiteId: PARENT_SITE_ID,
1568
+ },
1569
+ props: { tenantId: PROJECT_ID },
1570
+ });
1571
+
1572
+ expect(result.carryForward.parentPath).toBe(
1573
+ `/${PARENT_SITE_ID.toString()}/`,
1353
1574
  );
1354
1575
  });
1355
1576
 
@@ -1511,7 +1732,7 @@ describe("NetworkSiteService site-type hierarchy enforcement on update", () => {
1511
1732
  } as unknown as UpdateBy<NetworkSite>;
1512
1733
  }
1513
1734
 
1514
- it("rejects attaching a root-typed site to a parent", async () => {
1735
+ it("attaches a root-typed site to a parent of the same type", async () => {
1515
1736
  mockNetworkSiteTypes([fakeNetworkSiteType({ id: ROOT_SITE_TYPE_ID })]);
1516
1737
  jest
1517
1738
  .spyOn(NetworkSiteService, "findBy")
@@ -1527,16 +1748,49 @@ describe("NetworkSiteService site-type hierarchy enforcement on update", () => {
1527
1748
  .spyOn(NetworkSiteService, "getMaterializedPathForSite")
1528
1749
  .mockResolvedValue(`/${PARENT_SITE_ID.toString()}/`);
1529
1750
 
1530
- await expect(
1531
- (NetworkSiteService as any).onBeforeUpdate(
1532
- makeTypeUpdate({ parentSiteId: PARENT_SITE_ID }),
1533
- ),
1534
- ).rejects.toThrow(
1535
- "A site with a root network site type cannot have a parent site.",
1751
+ const result: any = await (NetworkSiteService as any).onBeforeUpdate(
1752
+ makeTypeUpdate({ parentSiteId: PARENT_SITE_ID }),
1753
+ );
1754
+
1755
+ expect(result.carryForward.newParentPath).toBe(
1756
+ `/${PARENT_SITE_ID.toString()}/`,
1536
1757
  );
1537
1758
  });
1538
1759
 
1539
- it("rejects detaching a site whose type requires a parent", async () => {
1760
+ // Linking an existing child to an existing parent - the second half of #3744.
1761
+ it("attaches an existing site to a parent of an unrelated type", async () => {
1762
+ mockNetworkSiteTypes([
1763
+ fakeNetworkSiteType({
1764
+ id: CHILD_SITE_TYPE_ID,
1765
+ name: "Market",
1766
+ parentNetworkSiteTypeId: ROOT_SITE_TYPE_ID,
1767
+ }),
1768
+ fakeNetworkSiteType({ id: ALTERNATE_ROOT_SITE_TYPE_ID, name: "Other" }),
1769
+ ]);
1770
+ jest
1771
+ .spyOn(NetworkSiteService, "findBy")
1772
+ .mockResolvedValue([fakeSite({ networkSiteTypeId: CHILD_SITE_TYPE_ID })]);
1773
+ jest.spyOn(NetworkSiteService, "findOneById").mockResolvedValue(
1774
+ fakeSite({
1775
+ id: PARENT_SITE_ID,
1776
+ _id: PARENT_SITE_ID.toString(),
1777
+ networkSiteTypeId: ALTERNATE_ROOT_SITE_TYPE_ID,
1778
+ }),
1779
+ );
1780
+ jest
1781
+ .spyOn(NetworkSiteService, "getMaterializedPathForSite")
1782
+ .mockResolvedValue(`/${PARENT_SITE_ID.toString()}/`);
1783
+
1784
+ const result: any = await (NetworkSiteService as any).onBeforeUpdate(
1785
+ makeTypeUpdate({ parentSiteId: PARENT_SITE_ID }),
1786
+ );
1787
+
1788
+ expect(result.carryForward.newParentId.toString()).toBe(
1789
+ PARENT_SITE_ID.toString(),
1790
+ );
1791
+ });
1792
+
1793
+ it("detaches a site whose type is configured below another type", async () => {
1540
1794
  mockNetworkSiteTypes([
1541
1795
  fakeNetworkSiteType({
1542
1796
  id: CHILD_SITE_TYPE_ID,
@@ -1550,17 +1804,50 @@ describe("NetworkSiteService site-type hierarchy enforcement on update", () => {
1550
1804
  }),
1551
1805
  ]);
1552
1806
 
1807
+ const result: any = await (NetworkSiteService as any).onBeforeUpdate(
1808
+ makeTypeUpdate({ parentSite: null }),
1809
+ );
1810
+
1811
+ expect(result.carryForward.newParentId).toBeNull();
1812
+ expect(result.carryForward.newParentPath).toBeNull();
1813
+ });
1814
+
1815
+ it("rejects re-parenting a site under a site whose type sits below it", async () => {
1816
+ mockNetworkSiteTypes([
1817
+ fakeNetworkSiteType({ id: ROOT_SITE_TYPE_ID, name: "Region" }),
1818
+ fakeNetworkSiteType({
1819
+ id: CHILD_SITE_TYPE_ID,
1820
+ name: "Market",
1821
+ parentNetworkSiteTypeId: ROOT_SITE_TYPE_ID,
1822
+ }),
1823
+ ]);
1824
+ jest
1825
+ .spyOn(NetworkSiteService, "findBy")
1826
+ .mockResolvedValue([fakeSite({ networkSiteTypeId: ROOT_SITE_TYPE_ID })]);
1827
+ jest.spyOn(NetworkSiteService, "findOneById").mockResolvedValue(
1828
+ fakeSite({
1829
+ id: PARENT_SITE_ID,
1830
+ _id: PARENT_SITE_ID.toString(),
1831
+ networkSiteTypeId: CHILD_SITE_TYPE_ID,
1832
+ }),
1833
+ );
1834
+ jest
1835
+ .spyOn(NetworkSiteService, "getMaterializedPathForSite")
1836
+ .mockResolvedValue(`/${PARENT_SITE_ID.toString()}/`);
1837
+
1553
1838
  await expect(
1554
1839
  (NetworkSiteService as any).onBeforeUpdate(
1555
- makeTypeUpdate({ parentSite: null }),
1840
+ makeTypeUpdate({ parentSiteId: PARENT_SITE_ID }),
1556
1841
  ),
1557
- ).rejects.toThrow("This network site type requires a parent site.");
1842
+ ).rejects.toThrow('"Market" sits below "Region"');
1558
1843
  });
1559
1844
 
1560
1845
  it("validates a type-only update against the site's existing parent", async () => {
1561
1846
  mockNetworkSiteTypes([
1847
+ fakeNetworkSiteType({ id: ROOT_SITE_TYPE_ID, name: "Region" }),
1562
1848
  fakeNetworkSiteType({
1563
1849
  id: CHILD_SITE_TYPE_ID,
1850
+ name: "Market",
1564
1851
  parentNetworkSiteTypeId: ROOT_SITE_TYPE_ID,
1565
1852
  }),
1566
1853
  ]);
@@ -1625,11 +1912,12 @@ describe("NetworkSiteService site-type hierarchy enforcement on update", () => {
1625
1912
  );
1626
1913
  });
1627
1914
 
1628
- it("rejects a type change that would invalidate a direct child", async () => {
1915
+ it("rejects a type change that would push this site below its own child", async () => {
1629
1916
  mockNetworkSiteTypes([
1630
- fakeNetworkSiteType({ id: ALTERNATE_ROOT_SITE_TYPE_ID }),
1917
+ fakeNetworkSiteType({ id: ROOT_SITE_TYPE_ID, name: "Region" }),
1631
1918
  fakeNetworkSiteType({
1632
1919
  id: CHILD_SITE_TYPE_ID,
1920
+ name: "Market",
1633
1921
  parentNetworkSiteTypeId: ROOT_SITE_TYPE_ID,
1634
1922
  }),
1635
1923
  ]);
@@ -1639,25 +1927,61 @@ describe("NetworkSiteService site-type hierarchy enforcement on update", () => {
1639
1927
  jest
1640
1928
  .spyOn(NetworkSiteService, "findBy")
1641
1929
  .mockResolvedValueOnce([
1642
- fakeSite({ networkSiteTypeId: ROOT_SITE_TYPE_ID }),
1930
+ fakeSite({ networkSiteTypeId: ALTERNATE_ROOT_SITE_TYPE_ID }),
1643
1931
  ])
1644
1932
  .mockResolvedValueOnce([
1645
1933
  fakeSite({
1646
1934
  id: childId,
1647
1935
  _id: childId.toString(),
1648
1936
  parentSiteId: SITE_ID,
1649
- networkSiteTypeId: CHILD_SITE_TYPE_ID,
1937
+ networkSiteTypeId: ROOT_SITE_TYPE_ID,
1650
1938
  }),
1651
1939
  ]);
1652
1940
 
1653
1941
  await expect(
1654
1942
  (NetworkSiteService as any).onBeforeUpdate(
1655
1943
  makeTypeUpdate({
1944
+ networkSiteTypeId: CHILD_SITE_TYPE_ID,
1945
+ }),
1946
+ ),
1947
+ ).rejects.toThrow('"Market" sits below "Region"');
1948
+ });
1949
+
1950
+ it("rejects a type change to a unit-level type while the site has children", async () => {
1951
+ mockNetworkSiteTypes([
1952
+ fakeNetworkSiteType({
1953
+ id: CHILD_SITE_TYPE_ID,
1954
+ name: "Unit",
1955
+ parentNetworkSiteTypeId: ROOT_SITE_TYPE_ID,
1956
+ isUnitLevel: true,
1957
+ }),
1958
+ fakeNetworkSiteType({ id: ALTERNATE_ROOT_SITE_TYPE_ID, name: "Other" }),
1959
+ ]);
1960
+ const childId: ObjectID = new ObjectID(
1961
+ "99999999-9999-4999-8999-999999999999",
1962
+ );
1963
+ jest
1964
+ .spyOn(NetworkSiteService, "findBy")
1965
+ .mockResolvedValueOnce([
1966
+ fakeSite({ networkSiteTypeId: ROOT_SITE_TYPE_ID }),
1967
+ ])
1968
+ .mockResolvedValueOnce([
1969
+ fakeSite({
1970
+ id: childId,
1971
+ _id: childId.toString(),
1972
+ parentSiteId: SITE_ID,
1656
1973
  networkSiteTypeId: ALTERNATE_ROOT_SITE_TYPE_ID,
1657
1974
  }),
1975
+ ]);
1976
+
1977
+ await expect(
1978
+ (NetworkSiteService as any).onBeforeUpdate(
1979
+ makeTypeUpdate({
1980
+ networkSiteTypeId: CHILD_SITE_TYPE_ID,
1981
+ }),
1658
1982
  ),
1659
1983
  ).rejects.toThrow(
1660
- "Parent site must use the configured parent network site type.",
1984
+ 'Sites of network site type "Unit" are unit level, so they cannot have child sites.',
1661
1985
  );
1662
1986
  });
1663
1987
 
@@ -1703,31 +2027,34 @@ describe("NetworkSiteService site-type hierarchy enforcement on update", () => {
1703
2027
 
1704
2028
  it("pages past a full batch so wide sites cannot hide invalid direct children", async () => {
1705
2029
  mockNetworkSiteTypes([
1706
- fakeNetworkSiteType({ id: ALTERNATE_ROOT_SITE_TYPE_ID }),
1707
- fakeNetworkSiteType({
1708
- id: GRANDCHILD_SITE_TYPE_ID,
1709
- parentNetworkSiteTypeId: ALTERNATE_ROOT_SITE_TYPE_ID,
1710
- }),
2030
+ fakeNetworkSiteType({ id: ROOT_SITE_TYPE_ID, name: "Region" }),
1711
2031
  fakeNetworkSiteType({
1712
2032
  id: CHILD_SITE_TYPE_ID,
2033
+ name: "Market",
1713
2034
  parentNetworkSiteTypeId: ROOT_SITE_TYPE_ID,
1714
2035
  }),
2036
+ fakeNetworkSiteType({ id: ALTERNATE_ROOT_SITE_TYPE_ID, name: "Other" }),
1715
2037
  ]);
2038
+ /*
2039
+ * Every child on page one is fine under the relaxed rule; the one that
2040
+ * inverts the hierarchy is alone on page two, so only a loop that keeps
2041
+ * reading finds it.
2042
+ */
1716
2043
  const child: NetworkSite = fakeSite({
1717
2044
  id: new ObjectID("99999999-9999-4999-8999-999999999999"),
1718
- networkSiteTypeId: GRANDCHILD_SITE_TYPE_ID,
2045
+ networkSiteTypeId: ALTERNATE_ROOT_SITE_TYPE_ID,
1719
2046
  });
1720
2047
  const childReadSkips: Array<number> = [];
1721
2048
  const invalidChildOnSecondPage: NetworkSite = fakeSite({
1722
2049
  id: new ObjectID("aaaaaaaa-1111-4111-8111-111111111111"),
1723
- networkSiteTypeId: CHILD_SITE_TYPE_ID,
2050
+ networkSiteTypeId: ROOT_SITE_TYPE_ID,
1724
2051
  });
1725
2052
  const findBySpy: jest.SpyInstance = jest
1726
2053
  .spyOn(NetworkSiteService, "findBy")
1727
2054
  .mockImplementation((input: any) => {
1728
2055
  if (input.query._id) {
1729
2056
  return Promise.resolve([
1730
- fakeSite({ networkSiteTypeId: ROOT_SITE_TYPE_ID }),
2057
+ fakeSite({ networkSiteTypeId: ALTERNATE_ROOT_SITE_TYPE_ID }),
1731
2058
  ]);
1732
2059
  }
1733
2060
 
@@ -1746,12 +2073,10 @@ describe("NetworkSiteService site-type hierarchy enforcement on update", () => {
1746
2073
  await expect(
1747
2074
  (NetworkSiteService as any).onBeforeUpdate(
1748
2075
  makeTypeUpdate({
1749
- networkSiteTypeId: ALTERNATE_ROOT_SITE_TYPE_ID,
2076
+ networkSiteTypeId: CHILD_SITE_TYPE_ID,
1750
2077
  }),
1751
2078
  ),
1752
- ).rejects.toThrow(
1753
- "Parent site must use the configured parent network site type.",
1754
- );
2079
+ ).rejects.toThrow('"Market" sits below "Region"');
1755
2080
 
1756
2081
  expect(findBySpy).toHaveBeenCalledTimes(3);
1757
2082
  expect(childReadSkips).toEqual([0, 1000]);
@@ -1785,7 +2110,7 @@ describe("NetworkSiteService site-type hierarchy enforcement on update", () => {
1785
2110
  makeTypeUpdate({ networkSiteTypeId: null }),
1786
2111
  ),
1787
2112
  ).rejects.toThrow(
1788
- "Parent site must use the configured parent network site type.",
2113
+ "A network site with child sites must have a network site type.",
1789
2114
  );
1790
2115
  });
1791
2116
 
@@ -1877,6 +2202,187 @@ describe("NetworkSiteService site-type hierarchy enforcement on update", () => {
1877
2202
  });
1878
2203
  });
1879
2204
 
2205
+ /*
2206
+ * materializedPath is varchar(500) and each segment costs 37 characters, so a
2207
+ * path holds 13 ids. The old placement rule bounded depth for free by pinning
2208
+ * a site's depth to its type's depth in the catalog. Nothing pins it now, so
2209
+ * the bound is enforced here - and it has to be enforced BEFORE the write,
2210
+ * because the subtree rebase that would overflow the column runs after the
2211
+ * parent change has already been committed.
2212
+ */
2213
+ describe("NetworkSiteService hierarchy depth bound", () => {
2214
+ afterEach(() => {
2215
+ jest.restoreAllMocks();
2216
+ });
2217
+
2218
+ function pathOfSegments(count: number): string {
2219
+ return `/${Array.from(
2220
+ { length: count },
2221
+ (_unused: unknown, index: number) => {
2222
+ return new ObjectID(
2223
+ `eeeeeeee-eeee-4eee-8eee-${index.toString().padStart(12, "0")}`,
2224
+ ).toString();
2225
+ },
2226
+ ).join("/")}/`;
2227
+ }
2228
+
2229
+ function mockRootTypedParent(): void {
2230
+ mockNetworkSiteTypes([fakeNetworkSiteType({ id: ROOT_SITE_TYPE_ID })]);
2231
+ jest.spyOn(NetworkSiteService, "findOneById").mockResolvedValue(
2232
+ fakeSite({
2233
+ id: PARENT_SITE_ID,
2234
+ _id: PARENT_SITE_ID.toString(),
2235
+ networkSiteTypeId: ROOT_SITE_TYPE_ID,
2236
+ }),
2237
+ );
2238
+ }
2239
+
2240
+ it("accepts a create that lands on the last usable level", async () => {
2241
+ mockRootTypedParent();
2242
+ jest
2243
+ .spyOn(NetworkSiteService, "getMaterializedPathForSite")
2244
+ .mockResolvedValue(pathOfSegments(12));
2245
+
2246
+ const result: any = await (NetworkSiteService as any).onBeforeCreate({
2247
+ data: {
2248
+ projectId: PROJECT_ID,
2249
+ networkSiteTypeId: ROOT_SITE_TYPE_ID,
2250
+ parentSiteId: PARENT_SITE_ID,
2251
+ },
2252
+ props: { tenantId: PROJECT_ID },
2253
+ });
2254
+
2255
+ expect(result.carryForward.parentPath).toBe(pathOfSegments(12));
2256
+ });
2257
+
2258
+ it("rejects a create one level past what the stored path can hold", async () => {
2259
+ mockRootTypedParent();
2260
+ jest
2261
+ .spyOn(NetworkSiteService, "getMaterializedPathForSite")
2262
+ .mockResolvedValue(pathOfSegments(13));
2263
+
2264
+ await expect(
2265
+ (NetworkSiteService as any).onBeforeCreate({
2266
+ data: {
2267
+ projectId: PROJECT_ID,
2268
+ networkSiteTypeId: ROOT_SITE_TYPE_ID,
2269
+ parentSiteId: PARENT_SITE_ID,
2270
+ },
2271
+ props: { tenantId: PROJECT_ID },
2272
+ }),
2273
+ ).rejects.toThrow("can be at most 13 levels deep");
2274
+ });
2275
+
2276
+ /*
2277
+ * The moved site takes its whole subtree with it, so the deepest row under
2278
+ * it is what decides whether the move fits - not the site's own new depth.
2279
+ */
2280
+ it("measures the moved subtree, not just the moved site", async () => {
2281
+ mockNetworkSiteTypes([fakeNetworkSiteType({ id: ROOT_SITE_TYPE_ID })]);
2282
+ const ownPath: string = `/${SITE_ID.toString()}/`;
2283
+ const deepestDescendantPath: string = `${ownPath}${new ObjectID(
2284
+ "dddddddd-dddd-4ddd-8ddd-dddddddddddd",
2285
+ ).toString()}/${new ObjectID(
2286
+ "dddddddd-dddd-4ddd-8ddd-ddddddddddde",
2287
+ ).toString()}/`;
2288
+
2289
+ jest
2290
+ .spyOn(NetworkSiteService, "findBy")
2291
+ .mockImplementation((input: any) => {
2292
+ if (input.query.materializedPath) {
2293
+ return Promise.resolve([
2294
+ fakeSite({ materializedPath: deepestDescendantPath }),
2295
+ ]);
2296
+ }
2297
+
2298
+ return Promise.resolve([
2299
+ fakeSite({
2300
+ networkSiteTypeId: ROOT_SITE_TYPE_ID,
2301
+ materializedPath: ownPath,
2302
+ }),
2303
+ ]);
2304
+ });
2305
+ jest.spyOn(NetworkSiteService, "findOneById").mockResolvedValue(
2306
+ fakeSite({
2307
+ id: PARENT_SITE_ID,
2308
+ _id: PARENT_SITE_ID.toString(),
2309
+ networkSiteTypeId: ROOT_SITE_TYPE_ID,
2310
+ }),
2311
+ );
2312
+ // Eleven ancestors + the moved site + its two levels = fourteen.
2313
+ jest
2314
+ .spyOn(NetworkSiteService, "getMaterializedPathForSite")
2315
+ .mockResolvedValue(pathOfSegments(11));
2316
+
2317
+ await expect(
2318
+ (NetworkSiteService as any).onBeforeUpdate({
2319
+ query: { _id: SITE_ID.toString() },
2320
+ data: { parentSiteId: PARENT_SITE_ID },
2321
+ props: { tenantId: PROJECT_ID },
2322
+ } as unknown as UpdateBy<NetworkSite>),
2323
+ ).rejects.toThrow("can be at most 13 levels deep");
2324
+ });
2325
+
2326
+ it("allows the same move when the subtree ends one level higher", async () => {
2327
+ mockNetworkSiteTypes([fakeNetworkSiteType({ id: ROOT_SITE_TYPE_ID })]);
2328
+ const ownPath: string = `/${SITE_ID.toString()}/`;
2329
+ const deepestDescendantPath: string = `${ownPath}${new ObjectID(
2330
+ "dddddddd-dddd-4ddd-8ddd-dddddddddddd",
2331
+ ).toString()}/`;
2332
+
2333
+ jest
2334
+ .spyOn(NetworkSiteService, "findBy")
2335
+ .mockImplementation((input: any) => {
2336
+ if (input.query.materializedPath) {
2337
+ return Promise.resolve([
2338
+ fakeSite({ materializedPath: deepestDescendantPath }),
2339
+ ]);
2340
+ }
2341
+
2342
+ return Promise.resolve([
2343
+ fakeSite({
2344
+ networkSiteTypeId: ROOT_SITE_TYPE_ID,
2345
+ materializedPath: ownPath,
2346
+ }),
2347
+ ]);
2348
+ });
2349
+ jest.spyOn(NetworkSiteService, "findOneById").mockResolvedValue(
2350
+ fakeSite({
2351
+ id: PARENT_SITE_ID,
2352
+ _id: PARENT_SITE_ID.toString(),
2353
+ networkSiteTypeId: ROOT_SITE_TYPE_ID,
2354
+ }),
2355
+ );
2356
+ jest
2357
+ .spyOn(NetworkSiteService, "getMaterializedPathForSite")
2358
+ .mockResolvedValue(pathOfSegments(11));
2359
+
2360
+ const result: any = await (NetworkSiteService as any).onBeforeUpdate({
2361
+ query: { _id: SITE_ID.toString() },
2362
+ data: { parentSiteId: PARENT_SITE_ID },
2363
+ props: { tenantId: PROJECT_ID },
2364
+ } as unknown as UpdateBy<NetworkSite>);
2365
+
2366
+ expect(result.carryForward.newParentPath).toBe(pathOfSegments(11));
2367
+ });
2368
+
2369
+ it("does not read the subtree when the site is being detached", async () => {
2370
+ const findBySpy: jest.SpyInstance = jest
2371
+ .spyOn(NetworkSiteService, "findBy")
2372
+ .mockResolvedValue([
2373
+ fakeSite({ materializedPath: `/${SITE_ID.toString()}/` }),
2374
+ ]);
2375
+
2376
+ await (NetworkSiteService as any).onBeforeUpdate({
2377
+ query: { _id: SITE_ID.toString() },
2378
+ data: { parentSiteId: null },
2379
+ props: { tenantId: PROJECT_ID },
2380
+ } as unknown as UpdateBy<NetworkSite>);
2381
+
2382
+ expect(findBySpy).toHaveBeenCalledTimes(1);
2383
+ });
2384
+ });
2385
+
1880
2386
  describe("NetworkSiteService.onUpdateSuccess (subtree rebase)", () => {
1881
2387
  afterEach(() => {
1882
2388
  jest.restoreAllMocks();