@kumori/aurora-backend-handler 1.0.88 → 1.0.90

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.
@@ -642,6 +642,7 @@ export const createAccount = async (account: Account, security: Security) => {
642
642
  account: account.name,
643
643
  tenant: account.tenant,
644
644
  },
645
+ userError: true,
645
646
  };
646
647
  eventHelper.notification.publish.creation(accountErrorNotification);
647
648
  throw error;
@@ -758,6 +759,7 @@ export const deleteAccount = async (account: Account, security: Security) => {
758
759
  account: account.name,
759
760
  tenant: account.tenant,
760
761
  },
762
+ userError: true,
761
763
  };
762
764
  eventHelper.notification.publish.creation(accountErrorNotification);
763
765
  throw error;
@@ -818,6 +820,7 @@ export const clearAccount = async (account: Account, security: Security) => {
818
820
  account: account.name,
819
821
  tenant: account.tenant,
820
822
  },
823
+ userError: true,
821
824
  };
822
825
  eventHelper.notification.publish.creation(accountErrorNotification);
823
826
  throw error;
@@ -143,7 +143,8 @@ export const createEnvironment = async (
143
143
  environment: env.name,
144
144
  account: env.account,
145
145
  tenant: env.tenant
146
- }
146
+ },
147
+ userError: true,
147
148
  };
148
149
  eventHelper.notification.publish.creation(envErrorNotification);
149
150
  throw error;
@@ -232,7 +233,8 @@ export const deleteEnvironment = async (
232
233
  environment: env.name,
233
234
  account: env.account,
234
235
  tenant: env.tenant
235
- }
236
+ },
237
+ userError: true,
236
238
  };
237
239
  eventHelper.notification.publish.creation(envErrorNotification);
238
240
  throw error;
@@ -319,7 +321,8 @@ export const clearEnvironment = async (
319
321
  environment: env.name,
320
322
  account: env.account,
321
323
  tenant: env.tenant
322
- }
324
+ },
325
+ userError: true,
323
326
  };
324
327
  eventHelper.notification.publish.creation(envErrorNotification);
325
328
  throw error;
@@ -456,7 +459,8 @@ export const updateEnvironment = async (
456
459
  environment: env.name,
457
460
  account: env.account,
458
461
  tenant: env.tenant
459
- }
462
+ },
463
+ userError: true
460
464
  };
461
465
  eventHelper.notification.publish.creation(envErrorNotification);
462
466
  throw error;
@@ -534,7 +538,8 @@ export const scaleEnvironment = async (
534
538
  environment: env.name,
535
539
  account: env.account,
536
540
  tenant: env.tenant
537
- }
541
+ },
542
+ userError: true
538
543
  };
539
544
  eventHelper.notification.publish.creation(envErrorNotification);
540
545
  throw error;
@@ -98,7 +98,8 @@ export const createDomain = async (
98
98
  data: {
99
99
  resource: domain.name,
100
100
  tenant: tenant
101
- }
101
+ },
102
+ userError: true,
102
103
  };
103
104
  eventHelper.notification.publish.creation(resourceErrorNotification);
104
105
  throw error;
@@ -177,7 +178,8 @@ export const createPort = async (
177
178
  data: {
178
179
  resource: port.name,
179
180
  tenant: tenant
180
- }
181
+ },
182
+ userError: true,
181
183
  };
182
184
  eventHelper.notification.publish.creation(resourceErrorNotification);
183
185
  throw error;
@@ -256,7 +258,8 @@ export const createCA = async (
256
258
  data: {
257
259
  resource: ca.name,
258
260
  tenant: tenant
259
- }
261
+ },
262
+ userError: true,
260
263
  };
261
264
  eventHelper.notification.publish.creation(resourceErrorNotification);
262
265
  throw error;
@@ -348,7 +351,8 @@ export const createCertificate = async (
348
351
  data: {
349
352
  resource: certificate.name,
350
353
  tenant: tenant
351
- }
354
+ },
355
+ userError: true,
352
356
  };
353
357
  eventHelper.notification.publish.creation(resourceErrorNotification);
354
358
  throw error;
@@ -427,7 +431,8 @@ export const createSecret = async (
427
431
  data: {
428
432
  resource: secret.name,
429
433
  tenant: tenant
430
- }
434
+ },
435
+ userError: true,
431
436
  };
432
437
  eventHelper.notification.publish.creation(resourceErrorNotification);
433
438
  throw error;
@@ -526,7 +531,8 @@ export const createVolume = async (
526
531
  data: {
527
532
  resource: volume.name,
528
533
  tenant: tenant
529
- }
534
+ },
535
+ userError: true,
530
536
  };
531
537
  eventHelper.notification.publish.creation(resourceErrorNotification);
532
538
  throw error;
@@ -632,7 +638,8 @@ const deleteResourceBase = async (
632
638
  resource: resource.name,
633
639
  type: resource.type,
634
640
  tenant: tenant
635
- }
641
+ },
642
+ userError: true,
636
643
  };
637
644
  eventHelper.notification.publish.creation(resourceErrorNotification);
638
645
  throw error;
@@ -726,7 +733,8 @@ const updateResourceBase = async (
726
733
  resource: resource.name,
727
734
  type: resource.type,
728
735
  tenant: tenant
729
- }
736
+ },
737
+ userError: true,
730
738
  };
731
739
  eventHelper.notification.publish.creation(resourceErrorNotification);
732
740
  throw error;
@@ -636,6 +636,7 @@ export const updateService = async (
636
636
  service: data.name,
637
637
  tenant: data.tenant,
638
638
  },
639
+ userError: true,
639
640
  };
640
641
  eventHelper.notification.publish.creation(notification);
641
642
  eventHelper.service.publish.updateError(data);
@@ -692,6 +693,7 @@ export const unlinkServices = async (service: Service, token: string) => {
692
693
  service: service.name,
693
694
  tenant: service.tenant,
694
695
  },
696
+ userError: true,
695
697
  };
696
698
  eventHelper.notification.publish.creation(notification);
697
699
  }
@@ -753,6 +755,7 @@ export const updateServiceLinks = async (link: Link, token: string) => {
753
755
  service: link.origin,
754
756
  tenant: link.tenant,
755
757
  },
758
+ userError: true,
756
759
  };
757
760
  eventHelper.notification.publish.creation(notification);
758
761
  }
@@ -109,6 +109,7 @@ export const createTenant = async (tenant: Tenant, security: Security) => {
109
109
  data: {
110
110
  tenant: tenant.name,
111
111
  },
112
+ userError: true,
112
113
  };
113
114
  eventHelper.notification.publish.creation(tenantCreationErrorNotification);
114
115
  throw error;
@@ -176,6 +177,7 @@ export const deleteTenant = async (tenant: Tenant, security: string) => {
176
177
  data: {
177
178
  tenant: tenant.name,
178
179
  },
180
+ userError: true,
179
181
  };
180
182
  eventHelper.notification.publish.creation(tenantDeletionErrorNotification);
181
183
  throw err;
@@ -265,6 +267,7 @@ export const updateTenant = async (tenant: Tenant, security: string) => {
265
267
  data: {
266
268
  tenant: tenant.name,
267
269
  },
270
+ userError: true,
268
271
  };
269
272
  eventHelper.notification.publish.creation(tenantUpdateErrorNotification);
270
273
  throw err;
@@ -364,6 +367,7 @@ export const createTenantHTTP = async (tenant: Tenant) => {
364
367
  data: {
365
368
  tenant: tenant.name,
366
369
  },
370
+ userError: true,
367
371
  };
368
372
 
369
373
  eventHelper.notification.publish.creation(tenantCreationErrorNotification);
@@ -423,6 +427,7 @@ export const deleteTenantHTTP = async (tenant: Tenant) => {
423
427
  data: {
424
428
  tenant: tenant.name,
425
429
  },
430
+ userError: true,
426
431
  };
427
432
  eventHelper.notification.publish.creation(tenantDeletionErrorNotification);
428
433
  }
@@ -514,6 +519,7 @@ export const updateTenantHTTP = async (tenant: Tenant) => {
514
519
  data: {
515
520
  tenant: tenant.name,
516
521
  },
522
+ userError: true,
517
523
  };
518
524
  eventHelper.notification.publish.creation(tenantUpdateErrorNotification);
519
525
  }
@@ -602,6 +608,7 @@ export const createRegistry = async (
602
608
  data: {
603
609
  tenant: tenant.name,
604
610
  },
611
+ userError: true,
605
612
  };
606
613
  eventHelper.notification.publish.creation(
607
614
  dregistryCreationErrorNotification
@@ -703,6 +710,7 @@ export const updateRegistry = async (
703
710
  data: {
704
711
  tenant: tenant.name,
705
712
  },
713
+ userError: true,
706
714
  };
707
715
  eventHelper.notification.publish.creation(dregistryUpdateErrorNotification);
708
716
  throw error;
@@ -785,6 +793,7 @@ export const deleteRegistry = async (
785
793
  data: {
786
794
  tenant: tenant.name,
787
795
  },
796
+ userError: true,
788
797
  };
789
798
  eventHelper.notification.publish.creation(
790
799
  dregistryDeletionErrorNotification
@@ -872,6 +881,7 @@ export const inviteUser = async (
872
881
  role,
873
882
  tenantRole,
874
883
  },
884
+ userError: true,
875
885
  };
876
886
  eventHelper.notification.publish.creation(tenantInviteErrorNotification);
877
887
  throw error;
@@ -948,6 +958,7 @@ export const removeUser = async (
948
958
  tenant: tenant,
949
959
  user: userId,
950
960
  },
961
+ userError: true,
951
962
  };
952
963
  eventHelper.notification.publish.creation(
953
964
  tenantUserRemovedErrorNotification
@@ -1031,6 +1042,7 @@ export const updateUserRole = async (
1031
1042
  user: userId,
1032
1043
  role: role,
1033
1044
  },
1045
+ userError: true,
1034
1046
  };
1035
1047
  eventHelper.notification.publish.creation(
1036
1048
  tenantUserUpdatedErrorNotification
@@ -1099,6 +1111,7 @@ export const acceptInvite = async (tenant: string, security: string) => {
1099
1111
  data: {
1100
1112
  tenant: tenant,
1101
1113
  },
1114
+ userError: true,
1102
1115
  };
1103
1116
  eventHelper.notification.publish.creation(
1104
1117
  tenantInviteAcceptedErrorNotification
@@ -1167,6 +1180,7 @@ export const rejectInvite = async (tenant: string, security: string) => {
1167
1180
  data: {
1168
1181
  tenant: tenant,
1169
1182
  },
1183
+ userError: true,
1170
1184
  };
1171
1185
  eventHelper.notification.publish.creation(
1172
1186
  tenantInviteRejectedErrorNotification
@@ -1091,6 +1091,7 @@ export const updateUser = async (user: User) => {
1091
1091
  message: (error as any).error.content,
1092
1092
  },
1093
1093
  data: { user: user.name },
1094
+ userError: true,
1094
1095
  });
1095
1096
  throw error;
1096
1097
  }
@@ -1129,6 +1130,7 @@ export const deleteUSer = async (user: User, security: string) => {
1129
1130
  message: (error as any).error.content,
1130
1131
  },
1131
1132
  data: { user: user.name },
1133
+ userError: true,
1132
1134
  });
1133
1135
  throw error;
1134
1136
  }
@@ -1,5 +1,28 @@
1
1
  import { Account, Notification } from "@kumori/aurora-interfaces";
2
+ const CREDENTIAL_ERROR_CODES = new Set([
3
+ "_error_retrieving_credentials_",
4
+ "_invalid_account_credentials_",
5
+ "_unsupported_region_",
6
+ ]);
2
7
 
8
+ /**
9
+ * All statuses that mean the account has reached a final error state.
10
+ * Pollers and status-strategy consumers should treat these as terminal.
11
+ */
12
+ export const ACCOUNT_ERROR_STATUSES = new Set([
13
+ "error",
14
+ "invalid_credentials",
15
+ "failed",
16
+ ]);
17
+
18
+ /**
19
+ * Map a raw backend error code to the normalized account status
20
+ * we write to accountsMap / the Account object.
21
+ */
22
+ export const resolveErrorStatus = (
23
+ code: string,
24
+ ): "invalid_credentials" | "error" =>
25
+ CREDENTIAL_ERROR_CODES.has(code) ? "invalid_credentials" : "error";
3
26
 
4
27
  interface HandleAccountEventParams {
5
28
  entityId: string;
@@ -39,10 +62,10 @@ interface HandleAccountOperationErrorResult {
39
62
  eventType: "creationError" | "updateError" | "deletionError";
40
63
  }
41
64
  /**
42
- * Extract cloud provider credentials from event data
65
+ * Extract cloud provider credentials from event data.
43
66
  */
44
67
  const extractCloudProviderCredentials = (
45
- eventData: any
68
+ eventData: any,
46
69
  ): { providerType: string; credentials: any } => {
47
70
  let providerType = "";
48
71
  let credentials = {};
@@ -52,18 +75,24 @@ const extractCloudProviderCredentials = (
52
75
  credentials = {
53
76
  region: eventData.spec.credentials.openstack?.region_name || "",
54
77
  interface: eventData.spec.credentials.openstack?.interface || "",
55
- apiVersion: eventData.spec.credentials.openstack?.identity_api_version || "",
78
+ apiVersion:
79
+ eventData.spec.credentials.openstack?.identity_api_version || "",
56
80
  authType: eventData.spec.credentials.openstack?.auth_type || "",
57
81
  authUrl: eventData.spec.credentials.openstack?.auth?.auth_url || "",
58
- credentialId: eventData.spec.credentials.openstack?.auth?.application_credential_id || "",
59
- credentialSecret: eventData.spec.credentials.openstack?.auth?.application_credential_secret || "",
82
+ credentialId:
83
+ eventData.spec.credentials.openstack?.auth?.application_credential_id ||
84
+ "",
85
+ credentialSecret:
86
+ eventData.spec.credentials.openstack?.auth
87
+ ?.application_credential_secret || "",
60
88
  };
61
89
  } else if (eventData.spec.credentials.aws) {
62
90
  providerType = "aws";
63
91
  credentials = {
64
92
  region: eventData.spec.credentials.aws?.region || "",
65
93
  credentialId: eventData.spec.credentials.aws?.aws_access_key_id || "",
66
- credentialSecret: eventData.spec.credentials.aws?.aws_secret_access_key || "",
94
+ credentialSecret:
95
+ eventData.spec.credentials.aws?.aws_secret_access_key || "",
67
96
  };
68
97
  } else if (eventData.spec.credentials.azure) {
69
98
  providerType = "azure";
@@ -87,28 +116,72 @@ const extractCloudProviderCredentials = (
87
116
  };
88
117
 
89
118
  /**
90
- * Determine account status from event data
119
+ * Determine the canonical account status from a WebSocket event.
120
+ *
121
+ * Priority order:
122
+ * 1. Soft-deleted accounts → 'deleting'
123
+ * 2. validCredentials status reported by the backend (covers both
124
+ * success and the async credential-validation path)
125
+ * 3. Keep the existing status so we never regress a terminal state
126
+ * (e.g. don't overwrite 'invalid_credentials' with 'pending')
127
+ * 4. Default to 'pending' for brand-new accounts
91
128
  */
92
129
  const determineAccountStatus = (
93
130
  eventData: any,
94
- existingAccount: Account | undefined
131
+ existingAccount: Account | undefined,
95
132
  ): string => {
96
133
  if (eventData.meta?.deleted) {
97
134
  return "deleting";
98
135
  }
99
- if (eventData.status.validCredentials?.status) {
100
- return eventData.status.validCredentials.status;
136
+ const rawStatus: string | undefined =
137
+ eventData.status?.validCredentials?.status;
138
+ if (rawStatus) {
139
+ if (CREDENTIAL_ERROR_CODES.has(rawStatus)) {
140
+ return "invalid_credentials";
141
+ }
142
+ return rawStatus;
101
143
  }
102
- if (existingAccount?.status) {
144
+ if (existingAccount?.status && existingAccount.status !== "pending") {
103
145
  return existingAccount.status;
104
146
  }
105
147
  return "pending";
106
148
  };
107
149
 
150
+ /**
151
+ * Translates account error notifications → account.status on accountsMap
152
+ * so that waitForAccountStatus only needs to poll account.status, not notifications.
153
+ *
154
+ * Called from the websocket-manager's `user` event case immediately after
155
+ * handleUserEvent so the status is always written in the same event-loop tick.
156
+ */
157
+ export const syncAccountStatusFromNotifications = (
158
+ notifications: any[] = [],
159
+ accountsMap: Map<string, Account>,
160
+ ): void => {
161
+ for (const notification of notifications) {
162
+ if (notification.type !== "error") continue;
163
+ if (
164
+ notification.subtype !== "account-creation-error" &&
165
+ notification.subtype !== "account-update-error"
166
+ )
167
+ continue;
168
+
169
+ const accountName: string = notification.data?.account;
170
+ if (!accountName) continue;
171
+
172
+ const account = accountsMap.get(accountName);
173
+ if (!account || ACCOUNT_ERROR_STATUSES.has(account.status)) continue;
174
+
175
+ const code: string = notification.info_content?.code ?? "";
176
+ accountsMap.set(accountName, {
177
+ ...account,
178
+ status: resolveErrorStatus(code),
179
+ });
180
+ }
181
+ };
108
182
 
109
183
  /**
110
- * Handles the "account" event from WebSocket messages
111
- * Processes account data updates and cloud provider credentials
184
+ * Handles the "account" kind event from WebSocket messages.
112
185
  */
113
186
  export const handleAccountEvent = ({
114
187
  entityId,
@@ -117,11 +190,13 @@ export const handleAccountEvent = ({
117
190
  accountsMap,
118
191
  }: HandleAccountEventParams): HandleAccountEventResult => {
119
192
  const accountTenantId = parentParts.tenant;
120
- const { providerType, credentials } = extractCloudProviderCredentials(eventData);
193
+ const { providerType, credentials } =
194
+ extractCloudProviderCredentials(eventData);
121
195
  const accountLabels: Record<string, string> = eventData.meta.labels;
122
196
  const hasCredentials = "__axebow::managedCredentials" in accountLabels;
123
197
  const existingAccount = accountsMap.get(entityId);
124
198
  const accountStatus = determineAccountStatus(eventData, existingAccount);
199
+
125
200
  const newAccount: Account = {
126
201
  id: entityId,
127
202
  name: entityId,
@@ -196,9 +271,8 @@ export const handleAccountEvent = ({
196
271
  };
197
272
  };
198
273
 
199
-
200
274
  /**
201
- * Handles successful account operations (CREATE, UPDATE, DELETE)
275
+ * Handles successful account operations (CREATE, UPDATE, DELETE).
202
276
  */
203
277
  export const handleAccountOperationSuccess = ({
204
278
  action,
@@ -206,57 +280,37 @@ export const handleAccountOperationSuccess = ({
206
280
  originalData,
207
281
  }: HandleAccountOperationSuccessParams): HandleAccountOperationSuccessResult => {
208
282
  if (action === "DELETE") {
209
- const accountNotification: Notification = {
210
- type: "success",
211
- subtype: "account-deleted",
212
- date: Date.now().toString(),
213
- status: "unread",
214
- callToAction: false,
215
- data: {
216
- account: originalData.name,
217
- tenant: originalData.tenant,
218
- },
219
- };
220
-
221
283
  return {
222
284
  updatedAccount: null,
223
285
  shouldDelete: true,
224
- notification: accountNotification,
286
+ notification: {
287
+ type: "success",
288
+ subtype: "account-deleted",
289
+ date: Date.now().toString(),
290
+ status: "unread",
291
+ callToAction: false,
292
+ data: { account: originalData.name, tenant: originalData.tenant },
293
+ },
225
294
  eventType: "deleted",
226
295
  };
227
296
  }
228
297
 
229
298
  if (originalData) {
230
- const updatedAccount = { ...originalData, status: "active" };
231
-
232
- let subtype: string;
233
- let eventType: "created" | "updated" | null = null;
234
-
235
- if (action === "CREATE") {
236
- subtype = "account-created";
237
- eventType = "created";
238
- } else {
239
- subtype = "account-updated";
240
- eventType = "updated";
241
- }
242
-
243
- const accountNotification: Notification = {
244
- type: "success",
245
- subtype,
246
- date: Date.now().toString(),
247
- status: "unread",
248
- callToAction: false,
249
- data: {
250
- account: updatedAccount.name,
251
- tenant: updatedAccount.tenant,
252
- },
253
- };
299
+ const updatedAccount: Account = { ...originalData, status: "active" };
300
+ const isCreate = action === "CREATE";
254
301
 
255
302
  return {
256
303
  updatedAccount,
257
304
  shouldDelete: false,
258
- notification: accountNotification,
259
- eventType,
305
+ notification: {
306
+ type: "success",
307
+ subtype: isCreate ? "account-created" : "account-updated",
308
+ date: Date.now().toString(),
309
+ status: "unread",
310
+ callToAction: false,
311
+ data: { account: updatedAccount.name, tenant: updatedAccount.tenant },
312
+ },
313
+ eventType: isCreate ? "created" : "updated",
260
314
  };
261
315
  }
262
316
 
@@ -275,9 +329,12 @@ export const handleAccountOperationSuccess = ({
275
329
  };
276
330
  };
277
331
 
278
-
279
332
  /**
280
- * Handles failed account operations (CREATE, UPDATE, DELETE)
333
+ * Handles failed account operations (CREATE, UPDATE, DELETE).
334
+ *
335
+ * For CREATE failures the account is removed from the map (shouldDelete = true).
336
+ * For UPDATE failures the existing account is kept but stamped with the
337
+ * resolved error status so waitForAccountStatus can terminate cleanly.
281
338
  */
282
339
  export const handleAccountOperationError = ({
283
340
  action,
@@ -285,52 +342,53 @@ export const handleAccountOperationError = ({
285
342
  originalData,
286
343
  error,
287
344
  }: HandleAccountOperationErrorParams): HandleAccountOperationErrorResult => {
288
- let subtype: string;
289
- let eventType: "creationError" | "updateError" | "deletionError";
290
- let shouldDelete = false;
345
+ const isCreate = action === "CREATE";
346
+ const isUpdate = action === "UPDATE";
291
347
 
292
- if (action === "CREATE") {
293
- subtype = "account-creation-error";
294
- eventType = "creationError";
295
- shouldDelete = true;
296
- } else if (action === "UPDATE") {
297
- subtype = "account-update-error";
298
- eventType = "updateError";
299
- } else {
300
- subtype = "account-deletion-error";
301
- eventType = "deletionError";
302
- }
348
+ const subtype = isCreate
349
+ ? "account-creation-error"
350
+ : isUpdate
351
+ ? "account-update-error"
352
+ : "account-deletion-error";
353
+
354
+ const eventType: "creationError" | "updateError" | "deletionError" = isCreate
355
+ ? "creationError"
356
+ : isUpdate
357
+ ? "updateError"
358
+ : "deletionError";
359
+ const errorCode: string = error?.error?.code ?? error?.code ?? "";
360
+ const errorStatus = resolveErrorStatus(errorCode);
303
361
 
304
- const accountErrorNotification: Notification = {
362
+ const notification: Notification = {
305
363
  type: "error",
306
364
  subtype,
307
365
  date: Date.now().toString(),
308
366
  status: "unread",
309
367
  info_content: {
310
- code: error?.error?.code || "UNKNOWN_ERROR",
311
- message: error?.error?.content || error?.error?.message || "Unknown error",
312
- timestamp: error?.error?.timestamp || Date.now().toString(),
368
+ code: errorCode || "UNKNOWN_ERROR",
369
+ message:
370
+ error?.error?.content ?? error?.error?.message ?? "Unknown error",
371
+ timestamp: error?.error?.timestamp ?? Date.now().toString(),
313
372
  },
314
373
  callToAction: false,
315
374
  data: {
316
- account: entityName || originalData?.name || originalData?.account || "unknown",
317
- tenant: originalData?.tenant || "unknown",
375
+ account:
376
+ entityName || originalData?.name || originalData?.account || "unknown",
377
+ tenant: originalData?.tenant ?? "unknown",
318
378
  },
379
+ userError: true,
319
380
  };
320
-
321
- let updatedAccount: Account | null = null;
322
-
323
- if (!shouldDelete && originalData) {
324
- updatedAccount = {
325
- ...originalData,
326
- status: "error",
381
+ if (isCreate) {
382
+ return {
383
+ updatedAccount: null,
384
+ shouldDelete: true,
385
+ notification,
386
+ eventType,
327
387
  };
328
388
  }
389
+ const updatedAccount: Account | null = originalData
390
+ ? { ...originalData, status: errorStatus }
391
+ : null;
329
392
 
330
- return {
331
- updatedAccount,
332
- shouldDelete,
333
- notification: accountErrorNotification,
334
- eventType,
335
- };
336
- };
393
+ return { updatedAccount, shouldDelete: false, notification, eventType };
394
+ };
@@ -270,6 +270,7 @@ export const handleEnvironmentOperationError = ({
270
270
  account: originalData.account,
271
271
  tenant: originalData.tenant,
272
272
  },
273
+ userError: true,
273
274
  };
274
275
 
275
276
  const updatedEnvironment: Environment = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kumori/aurora-backend-handler",
3
- "version": "1.0.88",
3
+ "version": "1.0.90",
4
4
  "description": "backend handler",
5
5
  "main": "backend-handler.ts",
6
6
  "scripts": {
@@ -11,7 +11,7 @@
11
11
  "glob": "^11.0.0"
12
12
  },
13
13
  "dependencies": {
14
- "@kumori/aurora-interfaces": "^1.0.9",
14
+ "@kumori/aurora-interfaces": "^1.0.11",
15
15
  "@kumori/kumori-dsl-generator": "^1.0.4",
16
16
  "@kumori/kumori-module-generator": "^1.1.6",
17
17
  "ts-node": "^10.9.2",
@@ -53,6 +53,7 @@ import {
53
53
  handleAccountEvent,
54
54
  handleAccountOperationError,
55
55
  handleAccountOperationSuccess,
56
+ syncAccountStatusFromNotifications,
56
57
  } from "./helpers/account-helper";
57
58
  import {
58
59
  handleCAEvent,
@@ -191,7 +192,6 @@ const REPORTING_ITERATIONS = 5;
191
192
  const REPORTING_INTERVAL = 1000;
192
193
  let hasLoadedReportingOnce = false;
193
194
  let recentlyUpdatedServices = new Map<string, Service>();
194
-
195
195
  /**
196
196
  * Helper function to safely stringify error objects
197
197
  */
@@ -644,6 +644,7 @@ const handleEvent = async (message: WSMessage) => {
644
644
  userEventResult.deletedTenantKeys.forEach((key) => {
645
645
  tenantsMap.delete(key);
646
646
  });
647
+ syncAccountStatusFromNotifications(userData.notifications, accountsMap);
647
648
  break;
648
649
  case "environment":
649
650
  const envEventResult = handleEnvironmentEvent({
@@ -1453,6 +1454,7 @@ const handleOperationError = (operation: PendingOperation, error: any) => {
1453
1454
  } else if (accErrorResult.updatedAccount) {
1454
1455
  accountsMap.set(entityName, accErrorResult.updatedAccount);
1455
1456
  }
1457
+
1456
1458
  if (accErrorResult.eventType === "creationError") {
1457
1459
  eventHelper.account.publish.creationError(originalData);
1458
1460
  } else if (accErrorResult.eventType === "updateError") {