@oneuptime/common 12.0.0 → 12.0.2

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 (237) hide show
  1. package/Models/DatabaseModels/Host.ts +12 -4
  2. package/Models/DatabaseModels/KubernetesContainer.ts +5 -4
  3. package/Models/DatabaseModels/KubernetesResource.ts +8 -7
  4. package/Models/DatabaseModels/OnCallDutyPolicyScheduleLayer.ts +12 -2
  5. package/Models/DatabaseModels/PodmanResource.ts +6 -6
  6. package/Models/DatabaseModels/ServiceLevelObjective.ts +91 -0
  7. package/Models/DatabaseModels/StatusPage.ts +95 -0
  8. package/Server/API/TeamMemberAPI.ts +85 -0
  9. package/Server/Infrastructure/Postgres/LocalMigrationGenerationDataSource.ts +12 -2
  10. package/Server/Infrastructure/Postgres/SchemaMigrations/1785900000000-AddSloMonitorLabelRule.ts +84 -0
  11. package/Server/Infrastructure/Postgres/SchemaMigrations/1785915638551-IncreaseHostIpAddressesLength.ts +40 -0
  12. package/Server/Infrastructure/Postgres/SchemaMigrations/1785930000000-WidenInventoryResourceNameColumns.ts +131 -0
  13. package/Server/Infrastructure/Postgres/SchemaMigrations/1785930709405-AddStatusPageReportPeriod.ts +25 -0
  14. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
  15. package/Server/Middleware/ProjectAuthorization.ts +66 -4
  16. package/Server/Services/BillingService.ts +600 -51
  17. package/Server/Services/CephClusterService.ts +47 -5
  18. package/Server/Services/CephResourceService.ts +43 -4
  19. package/Server/Services/CloudResourceService.ts +47 -5
  20. package/Server/Services/DatabaseService.ts +87 -6
  21. package/Server/Services/DockerHostService.ts +47 -5
  22. package/Server/Services/DockerResourceService.ts +62 -8
  23. package/Server/Services/DockerSwarmClusterService.ts +48 -5
  24. package/Server/Services/DockerSwarmResourceService.ts +53 -4
  25. package/Server/Services/HostService.ts +48 -5
  26. package/Server/Services/IoTDeviceService.ts +1 -17
  27. package/Server/Services/IoTFleetService.ts +47 -5
  28. package/Server/Services/KubernetesClusterService.ts +48 -5
  29. package/Server/Services/KubernetesContainerService.ts +50 -9
  30. package/Server/Services/KubernetesResourceService.ts +53 -7
  31. package/Server/Services/LabelService.ts +106 -1
  32. package/Server/Services/LlmProviderService.ts +69 -9
  33. package/Server/Services/MonitorService.ts +57 -0
  34. package/Server/Services/PodmanHostService.ts +47 -5
  35. package/Server/Services/PodmanResourceService.ts +62 -8
  36. package/Server/Services/ProjectService.ts +165 -35
  37. package/Server/Services/ProxmoxClusterService.ts +47 -5
  38. package/Server/Services/ProxmoxResourceService.ts +43 -4
  39. package/Server/Services/RumApplicationService.ts +48 -5
  40. package/Server/Services/RunnerService.ts +1 -7
  41. package/Server/Services/ServerlessFunctionService.ts +48 -5
  42. package/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.ts +426 -0
  43. package/Server/Services/ServiceLevelObjectiveService.ts +39 -0
  44. package/Server/Services/StatusPageService.ts +95 -36
  45. package/Server/Services/StatusPageSubscriberNotificationTemplateService.ts +18 -1
  46. package/Server/Services/StatusPageSubscriberService.ts +3 -0
  47. package/Server/Types/Database/JSONColumnQuery.ts +621 -0
  48. package/Server/Types/Database/Permissions/PublicPermission.ts +9 -2
  49. package/Server/Types/Database/QueryHelper.ts +17 -32
  50. package/Server/Utils/Database/TruncateColumnValue.ts +84 -0
  51. package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +12 -0
  52. package/Tests/App/Dashboard/RunnerInstallInstructions.test.tsx +119 -0
  53. package/Tests/App/Dashboard/RunnerStatus.test.tsx +274 -0
  54. package/Tests/App/Dashboard/UsersTableGroupsByPerson.test.tsx +448 -0
  55. package/Tests/Server/API/BaseAPIApiKeyAuth.test.ts +704 -0
  56. package/Tests/Server/API/TeamMemberRemoveUserFromProjectAPI.test.ts +303 -0
  57. package/Tests/Server/Middleware/MasterAdminAuthorization.test.ts +350 -0
  58. package/Tests/Server/Middleware/ProjectAuthorizationApiKeyHeader.test.ts +362 -0
  59. package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +687 -0
  60. package/Tests/Server/Services/BillingService.test.ts +78 -3
  61. package/Tests/Server/Services/BillingServiceChangePlanCancel.test.ts +645 -0
  62. package/Tests/Server/Services/BillingServiceTrialPlanChange.test.ts +1005 -0
  63. package/Tests/Server/Services/HookFreeWriteLengthClamp.test.ts +503 -0
  64. package/Tests/Server/Services/HostIpAddressesColumnWidth.test.ts +198 -0
  65. package/Tests/Server/Services/HostServiceUpdateLastSeen.test.ts +510 -0
  66. package/Tests/Server/Services/InventoryResourceNameColumnWidth.test.ts +500 -0
  67. package/Tests/Server/Services/InventoryUpsertSchemaParity.test.ts +586 -0
  68. package/Tests/Server/Services/InventoryUpsertTruncationGuard.test.ts +1242 -0
  69. package/Tests/Server/Services/LlmProviderUsableByProject.test.ts +293 -0
  70. package/Tests/Server/Services/ProjectServiceChangePlan.test.ts +650 -0
  71. package/Tests/Server/Services/ProjectServiceExtendTrial.test.ts +1 -0
  72. package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +387 -0
  73. package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.test.ts +770 -0
  74. package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +130 -0
  75. package/Tests/Server/Services/SloMonitorLabelRuleHooks.test.ts +352 -0
  76. package/Tests/Server/Services/StatusPageSubscriberReport.test.ts +29 -13
  77. package/Tests/Server/TestingUtils/Services/BillingServiceHelper.ts +69 -8
  78. package/Tests/Server/Types/Database/JSONColumnQuery.test.ts +593 -0
  79. package/Tests/Server/Types/Database/Permissions/PublicPermission.test.ts +495 -0
  80. package/Tests/Server/Types/Database/QueryUtil.test.ts +113 -0
  81. package/Tests/Server/Utils/AI/ToolArgsExtractors.test.ts +141 -0
  82. package/Tests/Server/Utils/AI/Toolbox/WidgetBuilder.test.ts +205 -0
  83. package/Tests/Server/Utils/Database/TruncateColumnValue.test.ts +179 -0
  84. package/Tests/Server/Utils/Monitor/Criteria/CompareCriteria.test.ts +897 -0
  85. package/Tests/Types/Events/Recurring.test.ts +157 -0
  86. package/Tests/Types/Runner/RunnerLiveStatus.test.ts +320 -0
  87. package/Tests/UI/Components/AiInvestigationSettingsCard.test.tsx +285 -0
  88. package/Tests/UI/Components/Detail/EntityFields.test.tsx +166 -0
  89. package/Tests/UI/Components/ModelTable/ModelTableGroupsProjectUsers.test.tsx +375 -0
  90. package/Tests/UI/Components/ModelTable/useCustomFieldColumns.test.tsx +196 -0
  91. package/Tests/UI/Utils/ProjectUsersModelAPI.test.ts +739 -0
  92. package/Tests/UI/Utils/TeamMembersByUser.test.ts +633 -0
  93. package/Tests/Utils/StatusPage/ReportPeriod.test.ts +218 -0
  94. package/Tests/Utils/Telemetry/HostIpAddresses.test.ts +291 -0
  95. package/Types/CustomField/CustomFieldDefinition.ts +24 -0
  96. package/Types/Date.ts +112 -0
  97. package/Types/Events/Recurring.ts +99 -1
  98. package/Types/Runbook/RunbookStep.ts +15 -0
  99. package/Types/Runner/RunnerLiveStatus.ts +114 -0
  100. package/Types/StatusPage/StatusPageReport.ts +11 -0
  101. package/Types/StatusPage/StatusPageReportPeriodType.ts +21 -0
  102. package/UI/Components/Detail/Detail.tsx +155 -0
  103. package/UI/Components/ModelTable/CustomFieldColumns.tsx +2 -6
  104. package/UI/Components/ModelTable/useCustomFieldColumns.ts +21 -2
  105. package/UI/Utils/ModelAPI/ProjectUsersModelAPI.ts +305 -0
  106. package/UI/Utils/TeamMembersByUser.ts +302 -0
  107. package/Utils/StatusPage/ReportPeriod.ts +236 -0
  108. package/Utils/Telemetry/HostIpAddresses.ts +98 -0
  109. package/build/dist/Models/DatabaseModels/Host.js +12 -4
  110. package/build/dist/Models/DatabaseModels/Host.js.map +1 -1
  111. package/build/dist/Models/DatabaseModels/KubernetesContainer.js +4 -4
  112. package/build/dist/Models/DatabaseModels/KubernetesContainer.js.map +1 -1
  113. package/build/dist/Models/DatabaseModels/KubernetesResource.js +7 -7
  114. package/build/dist/Models/DatabaseModels/KubernetesResource.js.map +1 -1
  115. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLayer.js +16 -4
  116. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLayer.js.map +1 -1
  117. package/build/dist/Models/DatabaseModels/PodmanResource.js +6 -6
  118. package/build/dist/Models/DatabaseModels/PodmanResource.js.map +1 -1
  119. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js +87 -0
  120. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js.map +1 -1
  121. package/build/dist/Models/DatabaseModels/StatusPage.js +98 -0
  122. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  123. package/build/dist/Server/API/TeamMemberAPI.js +57 -2
  124. package/build/dist/Server/API/TeamMemberAPI.js.map +1 -1
  125. package/build/dist/Server/Infrastructure/Postgres/LocalMigrationGenerationDataSource.js +11 -1
  126. package/build/dist/Server/Infrastructure/Postgres/LocalMigrationGenerationDataSource.js.map +1 -1
  127. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785900000000-AddSloMonitorLabelRule.js +45 -0
  128. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785900000000-AddSloMonitorLabelRule.js.map +1 -0
  129. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785915638551-IncreaseHostIpAddressesLength.js +31 -0
  130. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785915638551-IncreaseHostIpAddressesLength.js.map +1 -0
  131. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785930000000-WidenInventoryResourceNameColumns.js +90 -0
  132. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785930000000-WidenInventoryResourceNameColumns.js.map +1 -0
  133. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785930709405-AddStatusPageReportPeriod.js +14 -0
  134. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785930709405-AddStatusPageReportPeriod.js.map +1 -0
  135. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
  136. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  137. package/build/dist/Server/Middleware/ProjectAuthorization.js +59 -4
  138. package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
  139. package/build/dist/Server/Services/BillingService.js +466 -36
  140. package/build/dist/Server/Services/BillingService.js.map +1 -1
  141. package/build/dist/Server/Services/CephClusterService.js +42 -5
  142. package/build/dist/Server/Services/CephClusterService.js.map +1 -1
  143. package/build/dist/Server/Services/CephResourceService.js +28 -3
  144. package/build/dist/Server/Services/CephResourceService.js.map +1 -1
  145. package/build/dist/Server/Services/CloudResourceService.js +42 -5
  146. package/build/dist/Server/Services/CloudResourceService.js.map +1 -1
  147. package/build/dist/Server/Services/DatabaseService.js +69 -2
  148. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  149. package/build/dist/Server/Services/DockerHostService.js +42 -5
  150. package/build/dist/Server/Services/DockerHostService.js.map +1 -1
  151. package/build/dist/Server/Services/DockerResourceService.js +34 -4
  152. package/build/dist/Server/Services/DockerResourceService.js.map +1 -1
  153. package/build/dist/Server/Services/DockerSwarmClusterService.js +43 -5
  154. package/build/dist/Server/Services/DockerSwarmClusterService.js.map +1 -1
  155. package/build/dist/Server/Services/DockerSwarmResourceService.js +28 -3
  156. package/build/dist/Server/Services/DockerSwarmResourceService.js.map +1 -1
  157. package/build/dist/Server/Services/HostService.js +43 -5
  158. package/build/dist/Server/Services/HostService.js.map +1 -1
  159. package/build/dist/Server/Services/IoTDeviceService.js +1 -8
  160. package/build/dist/Server/Services/IoTDeviceService.js.map +1 -1
  161. package/build/dist/Server/Services/IoTFleetService.js +42 -5
  162. package/build/dist/Server/Services/IoTFleetService.js.map +1 -1
  163. package/build/dist/Server/Services/KubernetesClusterService.js +43 -5
  164. package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
  165. package/build/dist/Server/Services/KubernetesContainerService.js +29 -3
  166. package/build/dist/Server/Services/KubernetesContainerService.js.map +1 -1
  167. package/build/dist/Server/Services/KubernetesResourceService.js +32 -4
  168. package/build/dist/Server/Services/KubernetesResourceService.js.map +1 -1
  169. package/build/dist/Server/Services/LabelService.js +92 -0
  170. package/build/dist/Server/Services/LabelService.js.map +1 -1
  171. package/build/dist/Server/Services/LlmProviderService.js +61 -8
  172. package/build/dist/Server/Services/LlmProviderService.js.map +1 -1
  173. package/build/dist/Server/Services/MonitorService.js +47 -0
  174. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  175. package/build/dist/Server/Services/PodmanHostService.js +42 -5
  176. package/build/dist/Server/Services/PodmanHostService.js.map +1 -1
  177. package/build/dist/Server/Services/PodmanResourceService.js +34 -4
  178. package/build/dist/Server/Services/PodmanResourceService.js.map +1 -1
  179. package/build/dist/Server/Services/ProjectService.js +135 -21
  180. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  181. package/build/dist/Server/Services/ProxmoxClusterService.js +42 -5
  182. package/build/dist/Server/Services/ProxmoxClusterService.js.map +1 -1
  183. package/build/dist/Server/Services/ProxmoxResourceService.js +28 -3
  184. package/build/dist/Server/Services/ProxmoxResourceService.js.map +1 -1
  185. package/build/dist/Server/Services/RumApplicationService.js +43 -5
  186. package/build/dist/Server/Services/RumApplicationService.js.map +1 -1
  187. package/build/dist/Server/Services/RunnerService.js +1 -6
  188. package/build/dist/Server/Services/RunnerService.js.map +1 -1
  189. package/build/dist/Server/Services/ServerlessFunctionService.js +43 -5
  190. package/build/dist/Server/Services/ServerlessFunctionService.js.map +1 -1
  191. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js +347 -0
  192. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js.map +1 -0
  193. package/build/dist/Server/Services/ServiceLevelObjectiveService.js +33 -1
  194. package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -1
  195. package/build/dist/Server/Services/StatusPageService.js +69 -46
  196. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  197. package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js +17 -1
  198. package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js.map +1 -1
  199. package/build/dist/Server/Services/StatusPageSubscriberService.js +3 -0
  200. package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
  201. package/build/dist/Server/Types/Database/JSONColumnQuery.js +402 -0
  202. package/build/dist/Server/Types/Database/JSONColumnQuery.js.map +1 -0
  203. package/build/dist/Server/Types/Database/Permissions/PublicPermission.js +9 -2
  204. package/build/dist/Server/Types/Database/Permissions/PublicPermission.js.map +1 -1
  205. package/build/dist/Server/Types/Database/QueryHelper.js +17 -27
  206. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  207. package/build/dist/Server/Utils/Database/TruncateColumnValue.js +32 -0
  208. package/build/dist/Server/Utils/Database/TruncateColumnValue.js.map +1 -0
  209. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +11 -0
  210. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js.map +1 -1
  211. package/build/dist/Types/CustomField/CustomFieldDefinition.js +2 -0
  212. package/build/dist/Types/CustomField/CustomFieldDefinition.js.map +1 -0
  213. package/build/dist/Types/Date.js +68 -0
  214. package/build/dist/Types/Date.js.map +1 -1
  215. package/build/dist/Types/Events/Recurring.js +63 -0
  216. package/build/dist/Types/Events/Recurring.js.map +1 -1
  217. package/build/dist/Types/Runbook/RunbookStep.js.map +1 -1
  218. package/build/dist/Types/Runner/RunnerLiveStatus.js +69 -0
  219. package/build/dist/Types/Runner/RunnerLiveStatus.js.map +1 -0
  220. package/build/dist/Types/StatusPage/StatusPageReportPeriodType.js +22 -0
  221. package/build/dist/Types/StatusPage/StatusPageReportPeriodType.js.map +1 -0
  222. package/build/dist/UI/Components/Detail/Detail.js +97 -0
  223. package/build/dist/UI/Components/Detail/Detail.js.map +1 -1
  224. package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js.map +1 -1
  225. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +18 -2
  226. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -1
  227. package/build/dist/UI/Utils/ModelAPI/ProjectUsersModelAPI.js +213 -0
  228. package/build/dist/UI/Utils/ModelAPI/ProjectUsersModelAPI.js.map +1 -0
  229. package/build/dist/UI/Utils/TeamMembersByUser.js +195 -0
  230. package/build/dist/UI/Utils/TeamMembersByUser.js.map +1 -0
  231. package/build/dist/Utils/StatusPage/ReportPeriod.js +131 -0
  232. package/build/dist/Utils/StatusPage/ReportPeriod.js.map +1 -0
  233. package/build/dist/Utils/Telemetry/HostIpAddresses.js +82 -0
  234. package/build/dist/Utils/Telemetry/HostIpAddresses.js.map +1 -0
  235. package/jest.config.json +2 -0
  236. package/package.json +1 -1
  237. package/tsconfig.json +12 -1
@@ -594,6 +594,15 @@ export default class Host extends BaseModel {
594
594
  })
595
595
  public hostType?: string = undefined;
596
596
 
597
+ /*
598
+ * `text`, not varchar(500). A Docker/Kubernetes host with IPv6 enabled
599
+ * reports one host.ip entry per interface — physical NICs, docker
600
+ * bridges, every veth, plus an IPv6 link-local per interface. Real
601
+ * reports of 55 addresses / ~1450 characters exist, and the count grows
602
+ * with the number of containers, so any fixed bound is the wrong shape
603
+ * here. Overflowing it used to abort the whole Host metadata write and
604
+ * strand the host as "disconnected" (issue #3006).
605
+ */
597
606
  @ColumnAccessControl({
598
607
  create: [],
599
608
  read: [
@@ -614,17 +623,16 @@ export default class Host extends BaseModel {
614
623
  })
615
624
  @TableColumn({
616
625
  required: false,
617
- type: TableColumnType.LongText,
626
+ type: TableColumnType.VeryLongText,
618
627
  canReadOnRelationQuery: true,
619
628
  title: "Host IP Addresses",
620
629
  description:
621
- "Comma-separated list of IP addresses reported by the OTel host.ip resource attribute. The first non-loopback IPv4 is used for display.",
630
+ "Comma-separated list of every IP address reported by the OTel host.ip resource attribute, in the order the collector reported them, deduplicated. The Hosts list shows the most routable one (IPv4, non-loopback, non-link-local) first; the host detail page groups them all by category.",
622
631
  example: "192.168.1.42, 10.0.0.5",
623
632
  })
624
633
  @Column({
625
634
  nullable: true,
626
- type: ColumnType.LongText,
627
- length: ColumnLength.LongText,
635
+ type: ColumnType.VeryLongText,
628
636
  })
629
637
  public hostIpAddresses?: string = undefined;
630
638
 
@@ -193,15 +193,16 @@ export default class KubernetesContainer extends BaseModel {
193
193
  })
194
194
  @TableColumn({
195
195
  required: true,
196
- type: TableColumnType.ShortText,
196
+ type: TableColumnType.LongText,
197
197
  canReadOnRelationQuery: true,
198
198
  title: "Pod Name",
199
- description: "metadata.name of the parent Pod.",
199
+ description:
200
+ "metadata.name of the parent Pod. Generated pod names (deployment + replicaset hash + pod hash) routinely run past 100 characters, so this is a 500-char column rather than the usual 100.",
200
201
  })
201
202
  @Column({
202
203
  nullable: false,
203
- type: ColumnType.ShortText,
204
- length: ColumnLength.ShortText,
204
+ type: ColumnType.LongText,
205
+ length: ColumnLength.LongText,
205
206
  })
206
207
  public podName?: string = undefined;
207
208
 
@@ -214,15 +214,16 @@ export default class KubernetesResource extends BaseModel {
214
214
  })
215
215
  @TableColumn({
216
216
  required: true,
217
- type: TableColumnType.ShortText,
217
+ type: TableColumnType.LongText,
218
218
  canReadOnRelationQuery: true,
219
219
  title: "Name",
220
- description: "Kubernetes resource name (metadata.name).",
220
+ description:
221
+ "Kubernetes resource name (metadata.name). Kubernetes allows DNS-subdomain names up to 253 characters, so this is a 500-char column rather than the usual 100.",
221
222
  })
222
223
  @Column({
223
224
  nullable: false,
224
- type: ColumnType.ShortText,
225
- length: ColumnLength.ShortText,
225
+ type: ColumnType.LongText,
226
+ length: ColumnLength.LongText,
226
227
  })
227
228
  public name?: string = undefined;
228
229
 
@@ -449,7 +450,7 @@ export default class KubernetesResource extends BaseModel {
449
450
  })
450
451
  @TableColumn({
451
452
  required: false,
452
- type: TableColumnType.ShortText,
453
+ type: TableColumnType.LongText,
453
454
  canReadOnRelationQuery: true,
454
455
  title: "Controller Deployment Name",
455
456
  description:
@@ -457,8 +458,8 @@ export default class KubernetesResource extends BaseModel {
457
458
  })
458
459
  @Column({
459
460
  nullable: true,
460
- type: ColumnType.ShortText,
461
- length: ColumnLength.ShortText,
461
+ type: ColumnType.LongText,
462
+ length: ColumnLength.LongText,
462
463
  })
463
464
  public controllerDeploymentName?: string = undefined;
464
465
 
@@ -571,10 +571,19 @@ export default class OnCallDutyPolicyScheduleLayer extends BaseModel {
571
571
  Permission.EditOnCallDutyPolicyScheduleLayer,
572
572
  ],
573
573
  })
574
+ /*
575
+ * The default is `.toJSON()` rather than the Recurring instance itself. Both
576
+ * serialize to the identical JSON, so the DDL is unchanged — but TypeORM
577
+ * compares a jsonb default by deep-comparing the entity default against the
578
+ * value parsed back out of the database, and that comparison rejects any pair
579
+ * whose constructors differ (OrmUtils.compare2Objects). An instance never
580
+ * equals the plain object Postgres hands back, so every generated migration
581
+ * re-emitted this SET DEFAULT as phantom drift. A plain object compares equal.
582
+ */
574
583
  @Column({
575
584
  nullable: false,
576
585
  type: ColumnType.JSON,
577
- default: Recurring.getDefault(),
586
+ default: Recurring.getDefault().toJSON(),
578
587
  transformer: Recurring.getDatabaseTransformer(),
579
588
  })
580
589
  public rotation?: Recurring = undefined;
@@ -654,10 +663,11 @@ export default class OnCallDutyPolicyScheduleLayer extends BaseModel {
654
663
  Permission.EditOnCallDutyPolicyScheduleLayer,
655
664
  ],
656
665
  })
666
+ // Plain object, not the instance — see the note on `rotation` above.
657
667
  @Column({
658
668
  nullable: false,
659
669
  type: ColumnType.JSON,
660
- default: RestrictionTimes.getDefault(),
670
+ default: RestrictionTimes.getDefault().toJSON(),
661
671
  transformer: RestrictionTimes.getDatabaseTransformer(),
662
672
  })
663
673
  public restrictionTimes?: RestrictionTimes = undefined;
@@ -192,7 +192,7 @@ export default class PodmanResource extends BaseModel {
192
192
  })
193
193
  @TableColumn({
194
194
  required: true,
195
- type: TableColumnType.ShortText,
195
+ type: TableColumnType.LongText,
196
196
  canReadOnRelationQuery: true,
197
197
  title: "Name",
198
198
  description:
@@ -200,8 +200,8 @@ export default class PodmanResource extends BaseModel {
200
200
  })
201
201
  @Column({
202
202
  nullable: false,
203
- type: ColumnType.ShortText,
204
- length: ColumnLength.ShortText,
203
+ type: ColumnType.LongText,
204
+ length: ColumnLength.LongText,
205
205
  })
206
206
  public name?: string = undefined;
207
207
 
@@ -232,7 +232,7 @@ export default class PodmanResource extends BaseModel {
232
232
  })
233
233
  @TableColumn({
234
234
  required: false,
235
- type: TableColumnType.ShortText,
235
+ type: TableColumnType.LongText,
236
236
  canReadOnRelationQuery: true,
237
237
  title: "Image Name",
238
238
  description:
@@ -240,8 +240,8 @@ export default class PodmanResource extends BaseModel {
240
240
  })
241
241
  @Column({
242
242
  nullable: true,
243
- type: ColumnType.ShortText,
244
- length: ColumnLength.ShortText,
243
+ type: ColumnType.LongText,
244
+ length: ColumnLength.LongText,
245
245
  })
246
246
  public imageName?: string = undefined;
247
247
 
@@ -493,6 +493,97 @@ export default class ServiceLevelObjective extends BaseModel {
493
493
  })
494
494
  public monitors?: Array<Monitor> = undefined;
495
495
 
496
+ @ColumnAccessControl({
497
+ create: [
498
+ Permission.ProjectOwner,
499
+ Permission.ProjectAdmin,
500
+ Permission.CreateServiceLevelObjective,
501
+ ],
502
+ read: [
503
+ Permission.ProjectOwner,
504
+ Permission.ProjectAdmin,
505
+ Permission.ProjectMember,
506
+ Permission.Viewer,
507
+ Permission.ReadServiceLevelObjective,
508
+ ],
509
+ update: [
510
+ Permission.ProjectOwner,
511
+ Permission.ProjectAdmin,
512
+ Permission.EditServiceLevelObjective,
513
+ ],
514
+ })
515
+ @TableColumn({
516
+ required: false,
517
+ type: TableColumnType.EntityArray,
518
+ modelType: Label,
519
+ title: "Auto-Add Monitors With Labels",
520
+ description:
521
+ "Monitor labels that automatically attach monitors to this SLO. Any monitor in the project carrying at least one of these labels is added to the Monitors list, and is removed again when it stops carrying any of them.",
522
+ })
523
+ @ManyToMany(
524
+ () => {
525
+ return Label;
526
+ },
527
+ { eager: false },
528
+ )
529
+ @JoinTable({
530
+ name: "ServiceLevelObjectiveMonitorLabel",
531
+ inverseJoinColumn: {
532
+ name: "labelId",
533
+ referencedColumnName: "_id",
534
+ },
535
+ joinColumn: {
536
+ name: "serviceLevelObjectiveId",
537
+ referencedColumnName: "_id",
538
+ },
539
+ })
540
+ public monitorLabels?: Array<Label> = undefined;
541
+
542
+ /*
543
+ * Bookkeeping shadow of `monitors`: the subset of attached monitors that the
544
+ * label rule put there. Without it the rule could not tell a monitor it
545
+ * added from one a human attached by hand, so "this monitor no longer
546
+ * matches, detach it" would silently delete deliberate, manual attachments.
547
+ * Root-only: it is derived state, never something a client sets.
548
+ */
549
+ @ColumnAccessControl({
550
+ create: [],
551
+ read: [
552
+ Permission.ProjectOwner,
553
+ Permission.ProjectAdmin,
554
+ Permission.ProjectMember,
555
+ Permission.Viewer,
556
+ Permission.ReadServiceLevelObjective,
557
+ ],
558
+ update: [],
559
+ })
560
+ @TableColumn({
561
+ required: false,
562
+ type: TableColumnType.EntityArray,
563
+ modelType: Monitor,
564
+ title: "Auto Added Monitors",
565
+ description:
566
+ "Monitors that were attached to this SLO by its label rule rather than by hand. Maintained by the server.",
567
+ })
568
+ @ManyToMany(
569
+ () => {
570
+ return Monitor;
571
+ },
572
+ { eager: false },
573
+ )
574
+ @JoinTable({
575
+ name: "ServiceLevelObjectiveAutoAddedMonitor",
576
+ inverseJoinColumn: {
577
+ name: "monitorId",
578
+ referencedColumnName: "_id",
579
+ },
580
+ joinColumn: {
581
+ name: "serviceLevelObjectiveId",
582
+ referencedColumnName: "_id",
583
+ },
584
+ })
585
+ public autoAddedMonitors?: Array<Monitor> = undefined;
586
+
496
587
  @ColumnAccessControl({
497
588
  create: [
498
589
  Permission.ProjectOwner,
@@ -44,6 +44,7 @@ import {
44
44
  ManyToOne,
45
45
  } from "typeorm";
46
46
  import UptimePrecision from "../../Types/StatusPage/UptimePrecision";
47
+ import StatusPageReportPeriodType from "../../Types/StatusPage/StatusPageReportPeriodType";
47
48
  import { DEFAULT_STATUS_PAGE_LANGUAGE } from "../../Types/StatusPage/StatusPageLanguage";
48
49
 
49
50
  @OperationalResource()
@@ -2633,6 +2634,100 @@ export default class StatusPage extends BaseModel {
2633
2634
  })
2634
2635
  public reportDataInDays?: number = undefined;
2635
2636
 
2637
+ @ColumnAccessControl({
2638
+ create: [
2639
+ Permission.ProjectOwner,
2640
+ Permission.ProjectAdmin,
2641
+ Permission.ProjectMember,
2642
+ Permission.StatusPageAdmin,
2643
+ Permission.StatusPageMember,
2644
+ Permission.CreateProjectStatusPage,
2645
+ ],
2646
+ read: [
2647
+ Permission.ProjectOwner,
2648
+ Permission.ProjectAdmin,
2649
+ Permission.ProjectMember,
2650
+ Permission.Viewer,
2651
+ Permission.StatusPageAdmin,
2652
+ Permission.StatusPageMember,
2653
+ Permission.StatusPageViewer,
2654
+ Permission.ReadProjectStatusPage,
2655
+ ],
2656
+ update: [
2657
+ Permission.ProjectOwner,
2658
+ Permission.ProjectAdmin,
2659
+ Permission.ProjectMember,
2660
+ Permission.StatusPageAdmin,
2661
+ Permission.StatusPageMember,
2662
+ Permission.EditProjectStatusPage,
2663
+ ],
2664
+ })
2665
+ @TableColumn({
2666
+ type: TableColumnType.ShortText,
2667
+ defaultValue: StatusPageReportPeriodType.Rolling,
2668
+ title: "Report Period Type",
2669
+ description:
2670
+ "Should the report cover a rolling number of days, or the previous whole calendar period?",
2671
+ })
2672
+ @Column({
2673
+ type: ColumnType.ShortText,
2674
+ nullable: true,
2675
+ default: StatusPageReportPeriodType.Rolling,
2676
+ })
2677
+ @ColumnBillingAccessControl({
2678
+ read: PlanType.Free,
2679
+ update: PlanType.Growth,
2680
+ create: PlanType.Free,
2681
+ })
2682
+ public reportPeriodType?: StatusPageReportPeriodType = undefined;
2683
+
2684
+ @ColumnAccessControl({
2685
+ create: [
2686
+ Permission.ProjectOwner,
2687
+ Permission.ProjectAdmin,
2688
+ Permission.ProjectMember,
2689
+ Permission.StatusPageAdmin,
2690
+ Permission.StatusPageMember,
2691
+ Permission.CreateProjectStatusPage,
2692
+ ],
2693
+ read: [
2694
+ Permission.ProjectOwner,
2695
+ Permission.ProjectAdmin,
2696
+ Permission.ProjectMember,
2697
+ Permission.Viewer,
2698
+ Permission.StatusPageAdmin,
2699
+ Permission.StatusPageMember,
2700
+ Permission.StatusPageViewer,
2701
+ Permission.ReadProjectStatusPage,
2702
+ ],
2703
+ update: [
2704
+ Permission.ProjectOwner,
2705
+ Permission.ProjectAdmin,
2706
+ Permission.ProjectMember,
2707
+ Permission.StatusPageAdmin,
2708
+ Permission.StatusPageMember,
2709
+ Permission.EditProjectStatusPage,
2710
+ ],
2711
+ })
2712
+ @TableColumn({
2713
+ type: TableColumnType.ShortText,
2714
+ defaultValue: Timezone.UTC,
2715
+ title: "Report Timezone",
2716
+ description:
2717
+ "The timezone report periods and send times are resolved in. A monthly report in this timezone runs from the 1st at 00:00 to the last day at 23:59.",
2718
+ })
2719
+ @Column({
2720
+ type: ColumnType.ShortText,
2721
+ nullable: true,
2722
+ default: Timezone.UTC,
2723
+ })
2724
+ @ColumnBillingAccessControl({
2725
+ read: PlanType.Free,
2726
+ update: PlanType.Growth,
2727
+ create: PlanType.Free,
2728
+ })
2729
+ public reportTimezone?: Timezone = undefined;
2730
+
2636
2731
  @ColumnAccessControl({
2637
2732
  create: [
2638
2733
  Permission.ProjectOwner,
@@ -1,3 +1,4 @@
1
+ import CommonAPI from "./CommonAPI";
1
2
  import UserMiddleware from "../Middleware/UserAuthorization";
2
3
  import ProjectSCIMService from "../Services/ProjectSCIMService";
3
4
  import TeamMemberService, {
@@ -12,6 +13,9 @@ import {
12
13
  } from "../Utils/Express";
13
14
  import Response from "../Utils/Response";
14
15
  import BaseAPI from "./BaseAPI";
16
+ import DatabaseCommonInteractionProps from "../../Types/BaseDatabase/DatabaseCommonInteractionProps";
17
+ import Query from "../../Types/BaseDatabase/Query";
18
+ import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
15
19
  import Email from "../../Types/Email";
16
20
  import BadDataException from "../../Types/Exception/BadDataException";
17
21
  import NotAuthorizedException from "../../Types/Exception/NotAuthorizedException";
@@ -77,6 +81,87 @@ export default class TeamMemberAPI extends BaseAPI<
77
81
  },
78
82
  );
79
83
 
84
+ /*
85
+ * Removes one user from the current project - every team they belong to in
86
+ * it - in a single call.
87
+ *
88
+ * The Users table lists people rather than memberships, so "remove" there
89
+ * means "remove from the project". Doing that as N separate DELETEs from
90
+ * the browser is not equivalent: TeamMemberService.onBeforeDelete rejects
91
+ * the removal of the last accepted member of a team that
92
+ * `shouldHaveAtLeastOneMember` (the Owners team), and it rejects it per
93
+ * request - so a client-side loop deletes every other membership first and
94
+ * only then hits the guard, leaving the user stripped of the teams the
95
+ * caller was told they had not been removed from. One deleteBy over the
96
+ * whole set runs that guard against all of the user's memberships before
97
+ * anything is deleted, so the removal either happens or it does not.
98
+ *
99
+ * The project is taken from the request's tenant, never from the body, and
100
+ * the delete runs with the caller's own permissions - so this grants
101
+ * nothing that DELETE /team-member/:id did not already grant.
102
+ */
103
+ this.router.post(
104
+ `${new this.entityType().getCrudApiPath()?.toString()}/remove-user-from-project`,
105
+ UserMiddleware.getUserMiddleware,
106
+ async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
107
+ try {
108
+ const oneUptimeRequest: OneUptimeRequest = req as OneUptimeRequest;
109
+
110
+ if (!oneUptimeRequest.userAuthorization?.userId) {
111
+ return Response.sendErrorResponse(
112
+ req,
113
+ res,
114
+ new NotAuthorizedException("Not authenticated"),
115
+ );
116
+ }
117
+
118
+ const props: DatabaseCommonInteractionProps =
119
+ await CommonAPI.getDatabaseCommonInteractionProps(req);
120
+
121
+ const projectId: ObjectID | undefined = props.tenantId;
122
+
123
+ if (!projectId) {
124
+ return Response.sendErrorResponse(
125
+ req,
126
+ res,
127
+ new BadDataException("Project ID is required"),
128
+ );
129
+ }
130
+
131
+ const userIdParam: string = (
132
+ (req.body?.["userId"] as string) || ""
133
+ ).trim();
134
+
135
+ if (!userIdParam) {
136
+ return Response.sendErrorResponse(
137
+ req,
138
+ res,
139
+ new BadDataException("User ID is required"),
140
+ );
141
+ }
142
+
143
+ ObjectID.validateUUID(userIdParam);
144
+
145
+ const numberOfMembershipsDeleted: number =
146
+ await this.service.deleteBy({
147
+ query: {
148
+ userId: new ObjectID(userIdParam),
149
+ projectId: projectId,
150
+ } as Query<TeamMember>,
151
+ limit: LIMIT_PER_PROJECT,
152
+ skip: 0,
153
+ props: props,
154
+ });
155
+
156
+ return Response.sendJsonObjectResponse(req, res, {
157
+ numberOfMembershipsDeleted: numberOfMembershipsDeleted,
158
+ });
159
+ } catch (err) {
160
+ return next(err);
161
+ }
162
+ },
163
+ );
164
+
80
165
  this.router.post(
81
166
  `${new this.entityType().getCrudApiPath()?.toString()}/:id/leave`,
82
167
  UserMiddleware.getUserMiddleware,
@@ -1,10 +1,20 @@
1
1
  import dataSourceOptions from "./DataSourceOptions";
2
2
  import { DataSource } from "typeorm";
3
3
 
4
+ /*
5
+ * The app reaches Postgres over the compose network as `postgres:5432`, but the
6
+ * migration CLI runs on the host, where the same server is published on
7
+ * localhost:5400 — hence the defaults below.
8
+ *
9
+ * DATABASE_MIGRATIONS_HOST / DATABASE_MIGRATIONS_PORT (already in
10
+ * config.example.env, already honoured by migration-run.sh) override them, so
11
+ * the schema-drift job can point this at a CI service container on a different
12
+ * port without editing the file.
13
+ */
4
14
  const dataSourceOptionToMigrate: any = {
5
15
  ...dataSourceOptions,
6
- host: "localhost",
7
- port: 5400,
16
+ host: process.env["DATABASE_MIGRATIONS_HOST"] || "localhost",
17
+ port: parseInt(process.env["DATABASE_MIGRATIONS_PORT"] || "5400", 10),
8
18
  };
9
19
 
10
20
  const PostgresDataSource: DataSource = new DataSource(
@@ -0,0 +1,84 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ /*
4
+ * The SLO monitor label rule: two many-to-many join tables for
5
+ * ServiceLevelObjective.
6
+ *
7
+ * - ServiceLevelObjectiveMonitorLabel is the rule itself — the monitor
8
+ * labels an SLO auto-attaches monitors by.
9
+ *
10
+ * - ServiceLevelObjectiveAutoAddedMonitor is its bookkeeping: which of the
11
+ * SLO's attached monitors the rule put there. It is what lets the rule
12
+ * detach a monitor that stopped matching without ever touching one a
13
+ * human attached by hand.
14
+ *
15
+ * Both are pure additions; no backfill. An existing SLO has no rule, so it
16
+ * keeps its hand-curated monitor list untouched until someone gives it one.
17
+ */
18
+ export class AddSloMonitorLabelRule1785900000000 implements MigrationInterface {
19
+ public name = "AddSloMonitorLabelRule1785900000000";
20
+
21
+ public async up(queryRunner: QueryRunner): Promise<void> {
22
+ await queryRunner.query(
23
+ `CREATE TABLE "ServiceLevelObjectiveMonitorLabel" ("serviceLevelObjectiveId" uuid NOT NULL, "labelId" uuid NOT NULL, CONSTRAINT "PK_daea26f6963106215a4fea2da89" PRIMARY KEY ("serviceLevelObjectiveId", "labelId"))`,
24
+ );
25
+ await queryRunner.query(
26
+ `CREATE INDEX "IDX_cfda767c33fdbaa6ef9f268b8e" ON "ServiceLevelObjectiveMonitorLabel" ("serviceLevelObjectiveId") `,
27
+ );
28
+ await queryRunner.query(
29
+ `CREATE INDEX "IDX_46d9376cbba06f4911ed521b30" ON "ServiceLevelObjectiveMonitorLabel" ("labelId") `,
30
+ );
31
+ await queryRunner.query(
32
+ `CREATE TABLE "ServiceLevelObjectiveAutoAddedMonitor" ("serviceLevelObjectiveId" uuid NOT NULL, "monitorId" uuid NOT NULL, CONSTRAINT "PK_2a43ef3a0f312cd6a591838383b" PRIMARY KEY ("serviceLevelObjectiveId", "monitorId"))`,
33
+ );
34
+ await queryRunner.query(
35
+ `CREATE INDEX "IDX_f6f19994d02713e1f0021843ce" ON "ServiceLevelObjectiveAutoAddedMonitor" ("serviceLevelObjectiveId") `,
36
+ );
37
+ await queryRunner.query(
38
+ `CREATE INDEX "IDX_1c0e494a9f1082373a8b7efda5" ON "ServiceLevelObjectiveAutoAddedMonitor" ("monitorId") `,
39
+ );
40
+ await queryRunner.query(
41
+ `ALTER TABLE "ServiceLevelObjectiveMonitorLabel" ADD CONSTRAINT "FK_cfda767c33fdbaa6ef9f268b8e7" FOREIGN KEY ("serviceLevelObjectiveId") REFERENCES "ServiceLevelObjective"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
42
+ );
43
+ await queryRunner.query(
44
+ `ALTER TABLE "ServiceLevelObjectiveMonitorLabel" ADD CONSTRAINT "FK_46d9376cbba06f4911ed521b308" FOREIGN KEY ("labelId") REFERENCES "Label"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
45
+ );
46
+ await queryRunner.query(
47
+ `ALTER TABLE "ServiceLevelObjectiveAutoAddedMonitor" ADD CONSTRAINT "FK_f6f19994d02713e1f0021843ce6" FOREIGN KEY ("serviceLevelObjectiveId") REFERENCES "ServiceLevelObjective"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
48
+ );
49
+ await queryRunner.query(
50
+ `ALTER TABLE "ServiceLevelObjectiveAutoAddedMonitor" ADD CONSTRAINT "FK_1c0e494a9f1082373a8b7efda5b" FOREIGN KEY ("monitorId") REFERENCES "Monitor"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
51
+ );
52
+ }
53
+
54
+ public async down(queryRunner: QueryRunner): Promise<void> {
55
+ await queryRunner.query(
56
+ `ALTER TABLE "ServiceLevelObjectiveAutoAddedMonitor" DROP CONSTRAINT "FK_1c0e494a9f1082373a8b7efda5b"`,
57
+ );
58
+ await queryRunner.query(
59
+ `ALTER TABLE "ServiceLevelObjectiveAutoAddedMonitor" DROP CONSTRAINT "FK_f6f19994d02713e1f0021843ce6"`,
60
+ );
61
+ await queryRunner.query(
62
+ `ALTER TABLE "ServiceLevelObjectiveMonitorLabel" DROP CONSTRAINT "FK_46d9376cbba06f4911ed521b308"`,
63
+ );
64
+ await queryRunner.query(
65
+ `ALTER TABLE "ServiceLevelObjectiveMonitorLabel" DROP CONSTRAINT "FK_cfda767c33fdbaa6ef9f268b8e7"`,
66
+ );
67
+ await queryRunner.query(
68
+ `DROP INDEX "public"."IDX_1c0e494a9f1082373a8b7efda5"`,
69
+ );
70
+ await queryRunner.query(
71
+ `DROP INDEX "public"."IDX_f6f19994d02713e1f0021843ce"`,
72
+ );
73
+ await queryRunner.query(
74
+ `DROP TABLE "ServiceLevelObjectiveAutoAddedMonitor"`,
75
+ );
76
+ await queryRunner.query(
77
+ `DROP INDEX "public"."IDX_46d9376cbba06f4911ed521b30"`,
78
+ );
79
+ await queryRunner.query(
80
+ `DROP INDEX "public"."IDX_cfda767c33fdbaa6ef9f268b8e"`,
81
+ );
82
+ await queryRunner.query(`DROP TABLE "ServiceLevelObjectiveMonitorLabel"`);
83
+ }
84
+ }
@@ -0,0 +1,40 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class IncreaseHostIpAddressesLength1785915638551
4
+ implements MigrationInterface
5
+ {
6
+ public name = "IncreaseHostIpAddressesLength1785915638551";
7
+
8
+ public async up(queryRunner: QueryRunner): Promise<void> {
9
+ /*
10
+ * Change hostIpAddresses from varchar(500) to text.
11
+ *
12
+ * The OTel `host.ip` resource attribute is an array of every address on
13
+ * every interface. A Docker host with IPv6 enabled reports the physical
14
+ * NIC, one address per docker bridge, one per veth, plus an IPv6
15
+ * link-local per interface — 55 addresses / ~1450 characters observed in
16
+ * the wild, and the count grows with the container count. Overflowing
17
+ * varchar(500) aborted the entire Host metadata UPDATE, so lastSeenAt
18
+ * and otelCollectorStatus never advanced and a healthy host was shown as
19
+ * "Disconnected". See issue #3006.
20
+ */
21
+ await queryRunner.query(
22
+ `ALTER TABLE "Host" ALTER COLUMN "hostIpAddresses" TYPE text`,
23
+ );
24
+ }
25
+
26
+ public async down(queryRunner: QueryRunner): Promise<void> {
27
+ /*
28
+ * Revert to varchar(500). Truncate first — rows written since `up` ran
29
+ * may exceed 500 characters, and Postgres refuses the narrowing cast
30
+ * with "value too long for type character varying(500)" rather than
31
+ * truncating for us.
32
+ */
33
+ await queryRunner.query(
34
+ `UPDATE "Host" SET "hostIpAddresses" = LEFT("hostIpAddresses", 500) WHERE LENGTH("hostIpAddresses") > 500`,
35
+ );
36
+ await queryRunner.query(
37
+ `ALTER TABLE "Host" ALTER COLUMN "hostIpAddresses" TYPE character varying(500)`,
38
+ );
39
+ }
40
+ }