@kumori/aurora-backend-handler 1.0.100 → 1.0.112

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.
package/.gitlab-ci.yml CHANGED
@@ -18,27 +18,27 @@ install:
18
18
  paths:
19
19
  - node_modules/
20
20
 
21
- # test:
22
- # stage: test
23
- # image: node:16-alpine
24
- # tags:
25
- # - docker
26
- # dependencies:
27
- # - install
28
- # script:
29
- # - npm install --no-save jest-junit
30
- # - npm run test
31
- # coverage: '/All files.*?\|\s*[\d\.]+\s*\|\s*[\d\.]+\s*\|\s*[\d\.]+\s*\|\s*([\d\.]+)/'
32
- # artifacts:
33
- # when: always
34
- # paths:
35
- # - report.xml
36
- # reports:
37
- # junit: report.xml
38
- # only:
39
- # - merge_requests
40
- # - master
41
- # - tags
21
+ test:
22
+ stage: test
23
+ image: node:16-alpine
24
+ tags:
25
+ - docker
26
+ dependencies:
27
+ - install
28
+ script:
29
+ - npm install --no-save jest-junit
30
+ - npm run test
31
+ coverage: '/All files.*?\|\s*[\d\.]+\s*\|\s*[\d\.]+\s*\|\s*[\d\.]+\s*\|\s*([\d\.]+)/'
32
+ artifacts:
33
+ when: always
34
+ paths:
35
+ - report.xml
36
+ reports:
37
+ junit: report.xml
38
+ only:
39
+ - merge_requests
40
+ - master
41
+ - tags
42
42
 
43
43
  release:
44
44
  stage: release
package/CHANGELOG.md ADDED
@@ -0,0 +1,10 @@
1
+ # CHANGELOG 1.0.0 (2026-04-28)
2
+
3
+ ## Added (2 change)
4
+
5
+ * More tests to improve coverage.
6
+ * CHANGELOG.md file to follow the new reposiotry structure.
7
+
8
+ ## Changes (1 change)
9
+
10
+ * Updated the DSL library to ["@kumori/kumori-dsl-generator": "1.0.6"]
@@ -1,4 +1,4 @@
1
- import { Account, Notification } from "@kumori/aurora-interfaces";
1
+ import { Account, getWuiErrorCode, Notification } from "@kumori/aurora-interfaces";
2
2
  import {
3
3
  initializeGlobalWebSocketClient,
4
4
  getWebSocketStatus,
@@ -8,6 +8,13 @@ import { eventHelper } from "../backend-handler";
8
8
 
9
9
  type Security = string;
10
10
  function extractErrorInfo(error: unknown): { code: string; message: string } {
11
+ if ((error as any)?.isTimeout) {
12
+ return {
13
+ code: "timeout",
14
+ message:
15
+ "The request is taking too long, but it does not mean it failed. If you need more help, please contact support.",
16
+ };
17
+ }
11
18
  const err = (error as any)?.error;
12
19
  return {
13
20
  code: err?.code ?? "unknown_error",
@@ -630,14 +637,14 @@ export const createAccount = async (account: Account, security: Security) => {
630
637
 
631
638
  const accountErrorNotification: Notification = {
632
639
  type: "error",
633
- subtype: "account-creation-error",
640
+ subtype: getWuiErrorCode("account", "createAccount", code) ?? "account-creation-error",
634
641
  info_content: {
635
642
  code,
636
643
  message,
637
644
  },
638
645
  date: Date.now().toString(),
639
646
  status: "unread",
640
- callToAction: false,
647
+ notificationType: "regular",
641
648
  data: {
642
649
  account: account.name,
643
650
  tenant: account.tenant,
@@ -729,10 +736,10 @@ export const deleteAccount = async (account: Account, security: Security) => {
729
736
 
730
737
  const accountNotification: Notification = {
731
738
  type: "success",
732
- subtype: "account-deleteing",
739
+ subtype: "account-deleting",
733
740
  date: Date.now().toString(),
734
741
  status: "unread",
735
- callToAction: false,
742
+ notificationType: "regular",
736
743
  data: {
737
744
  account: account.name,
738
745
  tenant: account.tenant,
@@ -747,14 +754,14 @@ export const deleteAccount = async (account: Account, security: Security) => {
747
754
 
748
755
  const accountErrorNotification: Notification = {
749
756
  type: "error",
750
- subtype: "account-deletion-error",
757
+ subtype: getWuiErrorCode("account", "deleteAccount", code) ?? "account-deletion-error",
751
758
  date: Date.now().toString(),
752
759
  info_content: {
753
760
  code,
754
761
  message,
755
762
  },
756
763
  status: "unread",
757
- callToAction: false,
764
+ notificationType: "regular",
758
765
  data: {
759
766
  account: account.name,
760
767
  tenant: account.tenant,
@@ -793,7 +800,7 @@ export const clearAccount = async (account: Account, security: Security) => {
793
800
  subtype: "account-cleaned",
794
801
  date: Date.now().toString(),
795
802
  status: "unread",
796
- callToAction: false,
803
+ notificationType: "regular",
797
804
  data: {
798
805
  account: account.name,
799
806
  tenant: account.tenant,
@@ -808,14 +815,14 @@ export const clearAccount = async (account: Account, security: Security) => {
808
815
 
809
816
  const accountErrorNotification: Notification = {
810
817
  type: "error",
811
- subtype: "account-clean-error",
818
+ subtype: getWuiErrorCode("account", "deleteAccount", code) ?? "account-clean-error",
812
819
  date: Date.now().toString(),
813
820
  info_content: {
814
821
  code,
815
822
  message,
816
823
  },
817
824
  status: "unread",
818
- callToAction: false,
825
+ notificationType: "regular",
819
826
  data: {
820
827
  account: account.name,
821
828
  tenant: account.tenant,
@@ -1422,24 +1429,25 @@ export const updateAccount = async (account: Account, security: Security) => {
1422
1429
  provider: account.cloudProvider?.name,
1423
1430
  });
1424
1431
  eventHelper.account.publish.updateError(account);
1425
- // const { code, message } = extractErrorInfo(error);
1432
+ const { code, message } = extractErrorInfo(error);
1426
1433
 
1427
- // const accountErrorNotification: Notification = {
1428
- // type: "error",
1429
- // subtype: "account-update-error",
1430
- // date: Date.now().toString(),
1431
- // info_content: {
1432
- // code,
1433
- // message,
1434
- // },
1435
- // status: "unread",
1436
- // callToAction: false,
1437
- // data: {
1438
- // account: account.name,
1439
- // tenant: account.tenant,
1440
- // },
1441
- // };
1442
- // eventHelper.notification.publish.creation(accountErrorNotification);
1434
+ const accountErrorNotification: Notification = {
1435
+ type: "error",
1436
+ subtype: getWuiErrorCode("account", "updateAccount", code) ?? "account-update-error",
1437
+ date: Date.now().toString(),
1438
+ info_content: {
1439
+ code,
1440
+ message,
1441
+ },
1442
+ status: "unread",
1443
+ notificationType: "regular",
1444
+ data: {
1445
+ account: account.name,
1446
+ tenant: account.tenant,
1447
+ },
1448
+ userError: true,
1449
+ };
1450
+ eventHelper.notification.publish.creation(accountErrorNotification);
1443
1451
  throw error;
1444
1452
  }
1445
1453
  };
@@ -84,6 +84,8 @@ export interface ServiceSpecForm {
84
84
  cpuRequirements: number;
85
85
  memoryRequirements: number;
86
86
  registryUrl: string;
87
+ registryCredentialsSecret?: string;
88
+ registryCredentialSecret?: string;
87
89
  imageTag: string;
88
90
  clientChannels: Array<{ name: string }>;
89
91
  channels: Array<{
@@ -98,6 +100,7 @@ export interface ServiceSpecForm {
98
100
  certificateResource?: string;
99
101
  withMtls?: boolean;
100
102
  caResource?: string;
103
+ gatewayName?: string;
101
104
  }>;
102
105
  clientChannelsExtra?: Array<{ name: string }>;
103
106
  defaultExecutable: { cmd?: string; entryPoint?: string };
@@ -136,6 +139,7 @@ export interface ServiceSpecForm {
136
139
  };
137
140
  histeresys: string;
138
141
  };
142
+ hsize?: number;
139
143
  }
140
144
 
141
145
  export interface ServiceWithLocalComponentSpec {
@@ -180,7 +184,8 @@ interface ArtifactConfigParameterDto {
180
184
  type ParameterTypeDto = "string" | "number" | "bool";
181
185
  type ComponentEnvironmentDto =
182
186
  | ComponentEnvironmentParamDto
183
- | ComponentEnvironmentSecretDto;
187
+ | ComponentEnvironmentSecretDto
188
+ | ComponentEnvironmentValueDto;
184
189
  interface ComponentEnvironmentParamDto {
185
190
  varName: string;
186
191
  param: string;
@@ -189,6 +194,10 @@ interface ComponentEnvironmentSecretDto {
189
194
  varName: string;
190
195
  secret: string;
191
196
  }
197
+ interface ComponentEnvironmentValueDto {
198
+ varName: string;
199
+ value: string;
200
+ }
192
201
  type ArtifactConfigResource =
193
202
  | CA<ArtifactConfigResourceSpec>
194
203
  | Secret<ArtifactConfigResourceSpec>
@@ -218,13 +227,21 @@ interface Port<VARIANT> {
218
227
  interface Certificate<VARIANT> {
219
228
  certificate: VARIANT;
220
229
  }
221
- type ComponentFilesystemDto = FilesystemVolumeDto | FilesystemFileDto;
230
+ type ComponentFilesystemDto =
231
+ | FilesystemVolumeDto
232
+ | FilesystemSecretDto
233
+ | FilesystemFileDto;
222
234
 
223
235
  interface FilesystemVolumeDto {
224
236
  path: string;
225
237
  resourceVolume: string;
226
238
  }
227
239
 
240
+ interface FilesystemSecretDto {
241
+ path: string;
242
+ resourceSecret: string;
243
+ }
244
+
228
245
  interface FilesystemFileDto {
229
246
  path: string;
230
247
  param?: string;
@@ -378,6 +395,13 @@ export function handleParametersToGenerateData(
378
395
  });
379
396
  break;
380
397
 
398
+ case "clientChannel":
399
+ environmentResult.push({
400
+ varName: parameter.name,
401
+ value: `0.${parameter.value}`,
402
+ });
403
+ break;
404
+
381
405
  default:
382
406
  console.warn(`Unknown parameter type: ${parameter.type}`);
383
407
  parametersResult.push({
@@ -396,10 +420,17 @@ export function handleParametersToGenerateData(
396
420
  switch (resource.type) {
397
421
  case "secret":
398
422
  resourcesResult.push({ secret: { name: resource.name } });
399
- environmentResult.push({
400
- varName: resource.name,
401
- secret: resource.name as string,
402
- });
423
+ if (resource.key) {
424
+ fileSystemResult.push({
425
+ path: resource.key,
426
+ resourceSecret: resource.name,
427
+ });
428
+ } else {
429
+ environmentResult.push({
430
+ varName: resource.name,
431
+ secret: resource.name as string,
432
+ });
433
+ }
403
434
  break;
404
435
  case "volume":
405
436
  resourcesResult.push({ volume: { name: resource.name } });
@@ -444,6 +475,7 @@ export function transformServiceToForm(service: Service): ServiceSpecForm {
444
475
  cpuRequirements: service.usage.limit.cpu.max,
445
476
  memoryRequirements: service.usage.limit.memory.max,
446
477
  registryUrl: service.registry,
478
+ registryCredentialsSecret: service.registryCredentialSecret,
447
479
  imageTag: service.imageName,
448
480
  clientChannels: service.clientChannels.map((ch) => ({ name: ch.name })),
449
481
  channels: service.serverChannels.map((ch) => ({
@@ -461,6 +493,7 @@ export function transformServiceToForm(service: Service): ServiceSpecForm {
461
493
  certificateResource: ch.certificateResource,
462
494
  withMtls: ch.withMtls,
463
495
  caResource: ch.caResource,
496
+ gatewayName: ch.gatewayName,
464
497
  })),
465
498
  clientChannelsExtra: service.duplexChannels.map((ch) => ({
466
499
  name: ch.name,
@@ -485,13 +518,22 @@ export function transformServiceToForm(service: Service): ServiceSpecForm {
485
518
  })),
486
519
  },
487
520
  environment: [service.environment],
488
- fileSystem: service.resources
489
- .filter((resource) => resource.type === "volume")
490
- .map((resource) => ({
491
- path: resource.key,
492
- resourceVolume: resource.name,
493
- })),
521
+ fileSystem: [
522
+ ...service.resources
523
+ .filter((resource) => resource.type === "volume")
524
+ .map((resource) => ({
525
+ path: resource.key,
526
+ resourceVolume: resource.name,
527
+ })),
528
+ ...service.resources
529
+ .filter((resource) => resource.type === "secret" && resource.key)
530
+ .map((resource) => ({
531
+ path: resource.key,
532
+ resourceSecret: resource.name,
533
+ })),
534
+ ],
494
535
  scaling: service.role[0].scalling,
536
+ hsize: service.role[0].hsize
495
537
  };
496
538
  }
497
539
  /**
@@ -626,7 +668,7 @@ export async function generateServiceSpec(
626
668
  .map((channel) => {
627
669
  if (channel.protocol === "HTTPS") {
628
670
  return {
629
- name: `${channel.channelName}_inbound`,
671
+ name: channel.gatewayName || `${channel.channelName}_inbound`,
630
672
  artifact: {
631
673
  artifactKind: "service",
632
674
  moduleDomain: "kumori.systems",
@@ -669,7 +711,7 @@ export async function generateServiceSpec(
669
711
  };
670
712
  }
671
713
  return {
672
- name: `${channel.channelName}_inbound`,
714
+ name: channel.gatewayName || `${channel.channelName}_inbound`,
673
715
  artifact: {
674
716
  artifactKind: "service",
675
717
  moduleDomain: " ",
@@ -703,7 +745,7 @@ export async function generateServiceSpec(
703
745
  ];
704
746
  if (channel.isPublic) {
705
747
  result.push({
706
- clientRole: `${channel.channelName}_inbound`,
748
+ clientRole: channel.gatewayName || `${channel.channelName}_inbound`,
707
749
  clientChannel: "inbound",
708
750
  serverRole: withDefaultValue(form.serviceId, ""),
709
751
  serverChannel: channel.channelName,
@@ -1055,7 +1097,7 @@ export async function generateServiceSpec(
1055
1097
  detail: (marketplaceItem.roles ?? []).reduce(
1056
1098
  (acc, role) => ({
1057
1099
  ...acc,
1058
- [withDefaultValue(role, "")]: 1,
1100
+ [withDefaultValue(role, "")]: (marketplaceItem.deploymentData.role ?? []).find((r) => r.name === withDefaultValue(role, ""))?.hsize || 1,
1059
1101
  }),
1060
1102
  {},
1061
1103
  ),
@@ -1098,7 +1140,7 @@ export async function generateServiceSpec(
1098
1140
  ],
1099
1141
  scale: {
1100
1142
  detail: {
1101
- [withDefaultValue(form.serviceId, "")]: 1,
1143
+ [withDefaultValue(form.serviceId, "")]: form.hsize || 1,
1102
1144
  },
1103
1145
  },
1104
1146
  meta: autoscalingDefined
@@ -1129,7 +1171,6 @@ async function generateServiceSpecDSL(
1129
1171
  fileSystem,
1130
1172
  resources: componentResources,
1131
1173
  } = handleParametersToGenerateData(formParams, formResources);
1132
-
1133
1174
  const serverConfigDomainResources: ArtifactConfigResource[] = form.channels
1134
1175
  .filter((channel) => channel.protocol === "HTTPS" && channel.isPublic)
1135
1176
  .map((channel) => ({ domain: { name: `${channel.channelName}_domain` } }));
@@ -1240,7 +1281,7 @@ async function generateServiceSpecDSL(
1240
1281
  .map((channel) => {
1241
1282
  if (channel.protocol === "HTTPS") {
1242
1283
  return {
1243
- name: `${channel.channelName}_inbound`,
1284
+ name: channel.gatewayName || `${channel.channelName}_inbound`,
1244
1285
  artifact: {
1245
1286
  artifactKind: "service" as const,
1246
1287
  moduleDomain: "kumori",
@@ -1283,7 +1324,7 @@ async function generateServiceSpecDSL(
1283
1324
  };
1284
1325
  }
1285
1326
  return {
1286
- name: `${channel.channelName}_inbound`,
1327
+ name: channel.gatewayName || `${channel.channelName}_inbound`,
1287
1328
  artifact: {
1288
1329
  artifactKind: "service" as const,
1289
1330
  moduleDomain: "kumori",
@@ -1318,7 +1359,7 @@ async function generateServiceSpecDSL(
1318
1359
  ];
1319
1360
  if (channel.isPublic) {
1320
1361
  result.push({
1321
- clientRole: `${channel.channelName}_inbound`,
1362
+ clientRole: channel.gatewayName || `${channel.channelName}_inbound`,
1322
1363
  clientChannel: "inbound",
1323
1364
  serverRole: withDefaultValue(form.serviceId, ""),
1324
1365
  serverChannel: channel.channelName,
@@ -1498,7 +1539,6 @@ async function generateServiceSpecDSL(
1498
1539
  } = {
1499
1540
  simple: {},
1500
1541
  };
1501
-
1502
1542
  scaling.simple[form.serviceId] = {
1503
1543
  scale_up: {
1504
1544
  cpu: parseInt(form.scaling?.cpu.up || "") || 0,
@@ -1512,7 +1552,7 @@ async function generateServiceSpecDSL(
1512
1552
  min_replicas: form.scaling?.instances.min || 0,
1513
1553
  max_replicas: form.scaling?.instances.max || 0,
1514
1554
  };
1515
-
1555
+ const autoscalingDefined = form.scaling;
1516
1556
  const hasMarketplacePackage = marketplaceItem?.package;
1517
1557
 
1518
1558
  const serviceSpec: ServiceSpecDSLWithLocalComponent = {
@@ -1608,14 +1648,13 @@ async function generateServiceSpecDSL(
1608
1648
  ],
1609
1649
  scale: {
1610
1650
  detail: {
1611
- [withDefaultValue(form.serviceId, "")]: 1,
1651
+ [withDefaultValue(form.serviceId, "")]: form.hsize || 1,
1612
1652
  },
1613
1653
  },
1614
1654
  meta: {
1615
- deploymentMeta: {
1616
1655
  environment: form.environment || [],
1617
1656
  team: "development",
1618
- },
1657
+ scaling: autoscalingDefined ? scaling : {}
1619
1658
  },
1620
1659
  },
1621
1660
  };
@@ -1651,13 +1690,13 @@ async function generateServiceSpecDSL(
1651
1690
  memoryRequirements: withDefaultValue(form.memoryRequirements, 0) * 1000,
1652
1691
  registryUrl: withDefaultValue(form.registryUrl, "docker.io").trim(),
1653
1692
  imageTag: withDefaultValue(form.imageTag, "").trim(),
1654
- registryCredentialsSecret: form.config.resources
1655
- .map((r) => {
1656
- if (r.type === "secret" && r.key === "registryCredentials") {
1657
- return r.name;
1658
- }
1659
- })
1660
- .find((name) => name !== undefined),
1693
+ registryCredentialsSecret: form.registryCredentialsSecret
1694
+ ? form.config.resources.find(
1695
+ (r) => r.type === "secret" && r.name === form.registryCredentialsSecret,
1696
+ )?.name
1697
+ : form.config.resources.find(
1698
+ (r) => r.type === "secret" && r.key === "registryCredentials",
1699
+ )?.name,
1661
1700
  config: {
1662
1701
  parameters,
1663
1702
  resources: componentResources,
@@ -1,10 +1,11 @@
1
1
 
2
- import { Environment, Notification } from "@kumori/aurora-interfaces";
2
+ import { Environment, getWuiErrorCode, Notification } from "@kumori/aurora-interfaces";
3
3
  import { eventHelper } from "../backend-handler";
4
4
  import {
5
5
  initializeGlobalWebSocketClient,
6
6
  getWebSocketStatus,
7
7
  makeGlobalWebSocketRequest,
8
+ markEnvironmentAsPurging,
8
9
  } from "../websocket-manager";
9
10
 
10
11
  type Security = string;
@@ -131,14 +132,14 @@ export const createEnvironment = async (
131
132
  }
132
133
  const envErrorNotification: Notification = {
133
134
  type: "error",
134
- subtype: "environment-creation-error",
135
+ subtype: getWuiErrorCode("environment", "createEnvironment", contentMessage) ?? "environment-creation-error",
135
136
  info_content: {
136
137
  code: contentMessage,
137
138
  message: errorContent,
138
139
  },
139
140
  date: Date.now().toString(),
140
141
  status: "unread",
141
- callToAction: false,
142
+ notificationType: "regular",
142
143
  data: {
143
144
  environment: env.name,
144
145
  account: env.account,
@@ -184,7 +185,7 @@ export const deleteEnvironment = async (
184
185
  subtype: "environment-deleting",
185
186
  date: Date.now().toString(),
186
187
  status: "unread",
187
- callToAction: false,
188
+ notificationType: "regular",
188
189
  data: {
189
190
  environment: env.name,
190
191
  account: env.account,
@@ -221,14 +222,14 @@ export const deleteEnvironment = async (
221
222
  }
222
223
  const envErrorNotification: Notification = {
223
224
  type: "error",
224
- subtype: "environment-deletion-error",
225
+ subtype: getWuiErrorCode("environment", "deleteEnvironment", contentMessage) ?? "environment-deletion-error",
225
226
  info_content: {
226
227
  code: contentMessage,
227
228
  message: errorContent,
228
229
  },
229
230
  date: Date.now().toString(),
230
231
  status: "unread",
231
- callToAction: false,
232
+ notificationType: "regular",
232
233
  data: {
233
234
  environment: env.name,
234
235
  account: env.account,
@@ -251,7 +252,7 @@ export const clearEnvironment = async (
251
252
  subtype: "environment-cleaning",
252
253
  date: Date.now().toString(),
253
254
  status: "unread",
254
- callToAction: false,
255
+ notificationType: "regular",
255
256
  data: {
256
257
  environment: env.name,
257
258
  account: env.account,
@@ -259,6 +260,10 @@ export const clearEnvironment = async (
259
260
  }
260
261
  };
261
262
  eventHelper.notification.publish.creation(envNotification);
263
+ const purgeKey = env.tenant && env.account
264
+ ? `${env.tenant}/${env.account}/${env.name}`
265
+ : env.name;
266
+ markEnvironmentAsPurging(purgeKey);
262
267
  await initializeGlobalWebSocketClient(security, "environment", env.name);
263
268
  const status = getWebSocketStatus();
264
269
 
@@ -309,14 +314,14 @@ export const clearEnvironment = async (
309
314
  }
310
315
  const envErrorNotification: Notification = {
311
316
  type: "error",
312
- subtype: "environment-cleaning-error",
317
+ subtype: getWuiErrorCode("environment", "deleteEnvironment", contentMessage) ?? "environment-cleaning-error",
313
318
  info_content: {
314
319
  code: contentMessage,
315
320
  message: errorContent,
316
321
  },
317
322
  date: Date.now().toString(),
318
323
  status: "unread",
319
- callToAction: false,
324
+ notificationType: "regular",
320
325
  data: {
321
326
  environment: env.name,
322
327
  account: env.account,
@@ -410,7 +415,7 @@ export const updateEnvironment = async (
410
415
  subtype: "environment-updated",
411
416
  date: Date.now().toString(),
412
417
  status: "unread",
413
- callToAction: false,
418
+ notificationType: "regular",
414
419
  data: {
415
420
  environment: env.name,
416
421
  account: env.account,
@@ -447,14 +452,14 @@ export const updateEnvironment = async (
447
452
  }
448
453
  const envErrorNotification: Notification = {
449
454
  type: "error",
450
- subtype: "environment-update-error",
455
+ subtype: getWuiErrorCode("environment", "updateEnvironment", contentMessage) ?? "environment-update-error",
451
456
  info_content: {
452
457
  code: contentMessage,
453
458
  message: errorContent,
454
459
  },
455
460
  date: Date.now().toString(),
456
461
  status: "unread",
457
- callToAction: false,
462
+ notificationType: "regular",
458
463
  data: {
459
464
  environment: env.name,
460
465
  account: env.account,
@@ -495,7 +500,7 @@ export const scaleEnvironment = async (
495
500
  subtype: "environment-scaled",
496
501
  date: Date.now().toString(),
497
502
  status: "unread",
498
- callToAction: false,
503
+ notificationType: "regular",
499
504
  data: {
500
505
  environment: env.name,
501
506
  account: env.account,
@@ -526,14 +531,14 @@ export const scaleEnvironment = async (
526
531
  }
527
532
  const envErrorNotification: Notification = {
528
533
  type: "error",
529
- subtype: "environment-scale-error",
534
+ subtype: getWuiErrorCode("environment", "scaleEnvironment", contentMessage) ?? "environment-scale-error",
530
535
  info_content: {
531
536
  code: contentMessage,
532
537
  message: errorContent,
533
538
  },
534
539
  date: Date.now().toString(),
535
540
  status: "unread",
536
- callToAction: false,
541
+ notificationType: "regular",
537
542
  data: {
538
543
  environment: env.name,
539
544
  account: env.account,