@izara_project/izara-core-library-asynchronous-flow 1.0.33 → 1.0.35

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/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "author": "Sven Mason <thebarbariansven@gmail.com>",
4
4
  "license": "AGPL-3.0-or-later",
5
5
  "homepage": "https://bitbucket.org/izara-core-libraries/izara-core-library-asynchronous-flow#readme",
6
- "version": "1.0.33",
6
+ "version": "1.0.35",
7
7
  "description": "Shared asynchronous flow logic",
8
8
  "type": "module",
9
9
  "main": "index.js",
@@ -105,6 +105,10 @@ export function createParentFlowId(prefix = '') {
105
105
  * @throws {NoRetryError} If the stripped value equals the prefix (invalid)
106
106
  */
107
107
  export function explodePendingStepId(pendingStepId, prefix = '') {
108
+ if (!pendingStepId) {
109
+ throw NoRetryError('pendingStepId is required');
110
+ }
111
+
108
112
  if (prefix === '') {
109
113
  return pendingStepId;
110
114
  } else {
@@ -178,6 +182,22 @@ export async function checkUniqueRequestProcessing(
178
182
  overwriteUniqueRequestId = null,
179
183
  uniqueRequestIdFieldName = 'UniqueRequestId' // if set will check/add this fieldname with _izContext.uniqueRequestId value
180
184
  ) {
185
+ _izContext.logger.debug(
186
+ '[Lib:AsyncFlow:checkUniqueRequestProcessing] Input: ',
187
+ {
188
+ _izContext,
189
+ tableName,
190
+ primaryKey,
191
+ prefix,
192
+ overwriteUniqueRequestId,
193
+ uniqueRequestIdFieldName
194
+ }
195
+ );
196
+
197
+ if (!tableName || !primaryKey) {
198
+ throw NoRetryError('tableName and primaryKey are required');
199
+ }
200
+
181
201
  try {
182
202
  _izContext.logger.debug(
183
203
  'current uniqueRequestId:',
@@ -298,6 +318,20 @@ export async function checkTimeCacheComplete(
298
318
  timeCacheComplete,
299
319
  prefix
300
320
  ) {
321
+ _izContext.logger.debug('[Lib:AsyncFlow:checkTimeCacheComplete] Input: ', {
322
+ _izContext,
323
+ fullMainTableName,
324
+ keyValues,
325
+ timeCacheComplete,
326
+ prefix
327
+ });
328
+
329
+ if (!fullMainTableName || !keyValues || !timeCacheComplete || !prefix) {
330
+ throw NoRetryError(
331
+ 'fullMainTableName, keyValues, timeCacheComplete and prefix are required'
332
+ );
333
+ }
334
+
301
335
  let [returnValue, newTimeCacheComplete, uniqueRequestId] =
302
336
  await checkAndGetTimeCacheComplete(
303
337
  _izContext,
@@ -329,16 +363,19 @@ export async function checkAndGetTimeCacheComplete(
329
363
  timeCacheComplete,
330
364
  prefix
331
365
  ) {
332
- _izContext.logger.debug('event checkTimeCacheComplete', {
333
- fullMainTableName: fullMainTableName,
334
- keyValues: keyValues,
335
- timeCacheComplete: timeCacheComplete,
336
- prefix: prefix
337
- });
366
+ _izContext.logger.debug(
367
+ '[Lib:AsyncFlow:checkAndGetTimeCacheComplete] Input: ',
368
+ {
369
+ fullMainTableName: fullMainTableName,
370
+ keyValues: keyValues,
371
+ timeCacheComplete: timeCacheComplete,
372
+ prefix: prefix
373
+ }
374
+ );
338
375
 
339
- let uniqueRequestIdFieldName = createFieldNameUniqueRequestId('cache');
340
- let cacheCompleteFieldName = createFieldNameCacheComplete(prefix);
341
- let statusFieldName = createFieldNameStatus(prefix);
376
+ const uniqueRequestIdFieldName = createFieldNameUniqueRequestId('cache');
377
+ const cacheCompleteFieldName = createFieldNameCacheComplete(prefix);
378
+ const statusFieldName = createFieldNameStatus(prefix);
342
379
 
343
380
  let getTimeCacheComplete = await dynamodbSharedLib.getItem(
344
381
  _izContext,
@@ -436,6 +473,12 @@ export function validateStartKeyParam(
436
473
  partitionKeyFieldName,
437
474
  sortKeyFieldName
438
475
  ) {
476
+ _izContext.logger.debug('[Lib:AsyncFlow:validateStartKeyParam] Input: ', {
477
+ startKey,
478
+ partitionKeyFieldName,
479
+ sortKeyFieldName
480
+ });
481
+
439
482
  const stringNotEmptyRegex = /^[A-Za-z0-9_-]+$/;
440
483
 
441
484
  if (
@@ -482,12 +525,16 @@ export async function validateMultipleInvocations(
482
525
  numberInvocation,
483
526
  queueName
484
527
  ) {
485
- _izContext.logger.debug('Lib:validateMultipleInvocations', {
486
- messageProperty: messageProperty,
487
- passOnStartKey: passOnStartKey,
488
- numberInvocation: numberInvocation,
489
- queueName: queueName
490
- });
528
+ _izContext.logger.debug(
529
+ '[Lib:AsyncFlow:validateMultipleInvocations] Input: ',
530
+ {
531
+ messageProperty: messageProperty,
532
+ passOnStartKey: passOnStartKey,
533
+ numberInvocation: numberInvocation,
534
+ queueName: queueName
535
+ }
536
+ );
537
+
491
538
  try {
492
539
  const maxProcessInvocationCountImport = 20;
493
540
  if (numberInvocation >= maxProcessInvocationCountImport) {
@@ -504,7 +551,7 @@ export async function validateMultipleInvocations(
504
551
  }
505
552
  messageProperty['numberInvocation'] = numberInvocation;
506
553
 
507
- let messageReInvokeFunction = {
554
+ const messageReInvokeFunction = {
508
555
  MessageBody: JSON.stringify(messageProperty),
509
556
  QueueUrl: await sqsSharedLib.sqsQueueUrl(_izContext, queueName)
510
557
  };
@@ -43,16 +43,17 @@ export async function createAwaitingMultipleStepsWithAdditionalAttributes(
43
43
  pendingStepId
44
44
  ) {
45
45
  _izContext.logger.debug(
46
- 'Lib:createAwaitingMultipleStepsWithAdditionalAttributes',
46
+ '[Lib:AsyncFlow:createAwaitingMultipleStepsWithAdditionalAttributes] Input: ',
47
47
  {
48
- records: records,
49
- pendingStepId: pendingStepId
48
+ records,
49
+ pendingStepId
50
50
  }
51
51
  );
52
- let promiseArray = [];
53
52
 
54
- for (let record of records) {
55
- let attributesWhenCreate = {
53
+ const promiseArray = [];
54
+
55
+ for (const record of records) {
56
+ const attributesWhenCreate = {
56
57
  awaitingStepId: record.awaitingStepId,
57
58
  pendingStepId: pendingStepId,
58
59
  timestamp: Date.now(),
@@ -101,10 +102,13 @@ export async function initAwaitingStepsWithAttrs(
101
102
  records,
102
103
  pendingStepId
103
104
  ) {
104
- _izContext.logger.debug('Lib:initAwaitingStepsWithAttrs', {
105
- records,
106
- pendingStepId
107
- });
105
+ _izContext.logger.debug(
106
+ '[Lib:AsyncFlow:initAwaitingStepsWithAttrs] Input: ',
107
+ {
108
+ records,
109
+ pendingStepId
110
+ }
111
+ );
108
112
 
109
113
  const timestamp = Date.now();
110
114
  const promiseArray = [];
@@ -155,22 +159,26 @@ export async function createAwaitingMultipleSteps(
155
159
  records, // array of awaitingStepIds
156
160
  pendingStepId
157
161
  ) {
158
- _izContext.logger.debug('Lib:createAwaitingMultipleSteps', {
159
- records: records,
160
- pendingStepId: pendingStepId
161
- });
162
+ _izContext.logger.debug(
163
+ '[Lib:AsyncFlow:createAwaitingMultipleSteps] Input: ',
164
+ {
165
+ records: records,
166
+ pendingStepId: pendingStepId
167
+ }
168
+ );
162
169
 
163
- let promiseArray = [];
170
+ const promiseArray = [];
164
171
 
165
- for (let record of records) {
166
- let attributesWhenCreate = {
172
+ for (const record of records) {
173
+ const attributesWhenCreate = {
167
174
  awaitingStepId: record,
168
175
  pendingStepId: pendingStepId,
169
176
  timestamp: Date.now()
170
177
  };
171
- _izContext.logger.debug('putItem:AwaitingMultipleSteps +++++++', {
172
- awaitingStepId: attributesWhenCreate.awaitingStepId
173
- });
178
+ _izContext.logger.debug(
179
+ '[Lib:AsyncFlow:createAwaitingMultipleSteps] attributesWhenCreate: ',
180
+ attributesWhenCreate
181
+ );
174
182
  promiseArray.push(
175
183
  dynamodbSharedLib.putItem(
176
184
  _izContext,
@@ -179,9 +187,13 @@ export async function createAwaitingMultipleSteps(
179
187
  )
180
188
  );
181
189
 
182
- _izContext.logger.debug('putItem:AwaitingMultipleStepByPending', {
183
- awaitingStepId: attributesWhenCreate.awaitingStepId
184
- });
190
+ _izContext.logger.debug(
191
+ '[Lib:AsyncFlow:createAwaitingMultipleSteps] putItem:AwaitingMultipleStepByPending',
192
+ {
193
+ awaitingStepId: attributesWhenCreate.awaitingStepId
194
+ }
195
+ );
196
+
185
197
  promiseArray.push(
186
198
  dynamodbSharedLib.putItem(
187
199
  _izContext,
@@ -193,6 +205,7 @@ export async function createAwaitingMultipleSteps(
193
205
  )
194
206
  );
195
207
  }
208
+
196
209
  await Promise.all(promiseArray);
197
210
  }
198
211
 
@@ -229,6 +242,11 @@ export async function createNewAwaitingMultipleStep(
229
242
  errorsFound: []
230
243
  };
231
244
 
245
+ _izContext.logger.debug(
246
+ '[Lib:AsyncFlow:createNewAwaitingMultipleStep] attributesWhenCreate: ',
247
+ attributesWhenCreate
248
+ );
249
+
232
250
  await dynamodbSharedLib.putItem(
233
251
  _izContext,
234
252
  dynamodbSharedLib.tableName(_izContext, 'AwaitingMultipleSteps'),
@@ -246,6 +264,11 @@ export async function createNewAwaitingMultipleStep(
246
264
  attributesForPending
247
265
  );
248
266
 
267
+ _izContext.logger.debug(
268
+ '[Lib:AsyncFlow:createNewAwaitingMultipleStep] Returning: ',
269
+ parentFlowId
270
+ );
271
+
249
272
  return parentFlowId;
250
273
  }
251
274
 
@@ -260,9 +283,23 @@ export async function findPendingStepIdsAwaitingMultipleSteps(
260
283
  _izContext,
261
284
  awaitingStepId
262
285
  ) {
263
- let pendingStepIds = [];
286
+ _izContext.logger.debug(
287
+ '[Lib:findPendingStepIdsAwaitingMultipleSteps] Input parameters',
288
+ {
289
+ awaitingStepId: awaitingStepId
290
+ }
291
+ );
264
292
 
265
- let listPendingStepIds = await dynamodbSharedLib.query(
293
+ if (!awaitingStepId) {
294
+ _izContext.logger.error(
295
+ '[Lib:findPendingStepIdsAwaitingMultipleSteps] awaitingStepId is required'
296
+ );
297
+ throw new NoRetryError('awaitingStepId is required');
298
+ }
299
+
300
+ const pendingStepIds = [];
301
+
302
+ const listPendingStepIds = await dynamodbSharedLib.query(
266
303
  _izContext,
267
304
  dynamodbSharedLib.tableName(_izContext, 'AwaitingMultipleSteps'),
268
305
  {
@@ -270,10 +307,15 @@ export async function findPendingStepIdsAwaitingMultipleSteps(
270
307
  }
271
308
  );
272
309
 
273
- for (let idx = 0; idx < listPendingStepIds.Items.length; idx++) {
274
- pendingStepIds.push(listPendingStepIds.Items[idx].pendingStepId);
310
+ for (const item of listPendingStepIds.Items) {
311
+ pendingStepIds.push(item.pendingStepId);
275
312
  }
276
313
 
314
+ _izContext.logger.debug(
315
+ '[Lib:findPendingStepIdsAwaitingMultipleSteps] Pending step IDs',
316
+ pendingStepIds
317
+ );
318
+
277
319
  return pendingStepIds;
278
320
  }
279
321
 
@@ -288,14 +330,33 @@ export async function findPendingStepsAwaitingMultipleSteps(
288
330
  _izContext,
289
331
  awaitingStepId
290
332
  ) {
291
- let listPendingSteps = await dynamodbSharedLib.query(
333
+ _izContext.logger.debug(
334
+ '[Lib:findPendingStepsAwaitingMultipleSteps] Input parameters',
335
+ {
336
+ awaitingStepId: awaitingStepId
337
+ }
338
+ );
339
+
340
+ if (!awaitingStepId) {
341
+ _izContext.logger.error(
342
+ '[Lib:findPendingStepsAwaitingMultipleSteps] awaitingStepId is required'
343
+ );
344
+ throw new NoRetryError('awaitingStepId is required');
345
+ }
346
+
347
+ const listPendingSteps = await dynamodbSharedLib.query(
292
348
  _izContext,
293
349
  dynamodbSharedLib.tableName(_izContext, 'AwaitingMultipleSteps'),
294
350
  {
295
351
  awaitingStepId: awaitingStepId
296
352
  }
297
353
  );
298
- _izContext.logger.debug('Record of awaitingStepId', listPendingSteps);
354
+
355
+ _izContext.logger.debug(
356
+ '[Lib:findPendingStepsAwaitingMultipleSteps] Record of awaitingStepId',
357
+ listPendingSteps
358
+ );
359
+
299
360
  return listPendingSteps.Items;
300
361
  }
301
362
 
@@ -311,18 +372,40 @@ export async function findPendingStepAwaitingMultipleSteps(
311
372
  _izContext,
312
373
  awaitingStepId
313
374
  ) {
314
- let listPendingSteps = await dynamodbSharedLib.query(
375
+ _izContext.logger.debug(
376
+ '[Lib:findPendingStepAwaitingMultipleSteps] Input parameters',
377
+ {
378
+ awaitingStepId: awaitingStepId
379
+ }
380
+ );
381
+
382
+ if (!awaitingStepId) {
383
+ _izContext.logger.error(
384
+ '[Lib:findPendingStepAwaitingMultipleSteps] awaitingStepId is required'
385
+ );
386
+ throw new NoRetryError('awaitingStepId is required');
387
+ }
388
+
389
+ const listPendingSteps = await dynamodbSharedLib.query(
315
390
  _izContext,
316
391
  dynamodbSharedLib.tableName(_izContext, 'AwaitingMultipleSteps'),
317
392
  {
318
393
  awaitingStepId: awaitingStepId
319
394
  }
320
395
  );
321
- _izContext.logger.debug('Record of awaitingStepId', listPendingSteps);
396
+
397
+ _izContext.logger.debug(
398
+ '[Lib:findPendingStepAwaitingMultipleSteps] Record of awaitingStepId',
399
+ listPendingSteps
400
+ );
322
401
 
323
402
  if (listPendingSteps.Items.length !== 1) {
403
+ _izContext.logger.error(
404
+ '[Lib:findPendingStepAwaitingMultipleSteps] listPendingSteps not equals 1'
405
+ );
324
406
  throw new NoRetryError('listPendingSteps not equals 1');
325
407
  }
408
+
326
409
  return listPendingSteps.Items[0];
327
410
  }
328
411
 
@@ -343,7 +426,21 @@ export async function findAwaitingMultipleStepByPending(
343
426
  _izContext,
344
427
  pendingStepId
345
428
  ) {
346
- let listAwaitingSteps = await dynamodbSharedLib.query(
429
+ _izContext.logger.debug(
430
+ '[Lib:findAwaitingMultipleStepByPending] Input parameters',
431
+ {
432
+ pendingStepId: pendingStepId
433
+ }
434
+ );
435
+
436
+ if (!pendingStepId) {
437
+ _izContext.logger.error(
438
+ '[Lib:findAwaitingMultipleStepByPending] pendingStepId is required'
439
+ );
440
+ throw new NoRetryError('pendingStepId is required');
441
+ }
442
+
443
+ const listAwaitingSteps = await dynamodbSharedLib.query(
347
444
  _izContext,
348
445
  dynamodbSharedLib.tableName(_izContext, 'AwaitingMultipleStepByPending'),
349
446
  {
@@ -351,12 +448,24 @@ export async function findAwaitingMultipleStepByPending(
351
448
  }
352
449
  );
353
450
  _izContext.logger.debug(
354
- 'Record of AwaitingMultipleStepByPending',
451
+ '[Lib:findAwaitingMultipleStepByPending] Record of AwaitingMultipleStepByPending',
355
452
  listAwaitingSteps
356
453
  );
454
+
357
455
  return listAwaitingSteps.Items;
358
456
  }
359
457
 
458
+ /**
459
+ * Updates the completion status of a specific awaiting step within a multiple-step pending process.
460
+ * Marks the given awaiting step as complete and stores any encountered errors or additional attributes.
461
+ *
462
+ * @param {Object} _izContext - The execution context object containing logger and other utilities.
463
+ * @param {string} pendingStepId - The unique identifier of the parent pending step.
464
+ * @param {string|null} [currentAwaitingStepId=null] - The unique identifier of the specific awaiting step being processed. If null, no update is performed.
465
+ * @param {Array<Object|string>} [errorsFound=[]] - An array of errors encountered during the step's execution.
466
+ * @param {Object} [additionalAttributes={}] - Any extra data to save along with the completion status.
467
+ * @returns {Promise<void>} Resolves when the update operation is complete.
468
+ */
360
469
  export async function checkAllAwaitingStepsFinishedShared(
361
470
  _izContext,
362
471
  pendingStepId,
@@ -364,11 +473,14 @@ export async function checkAllAwaitingStepsFinishedShared(
364
473
  errorsFound = [],
365
474
  additionalAttributes = {}
366
475
  ) {
367
- _izContext.logger.debug('Lib:checkAllAwaitingStepsFinishedWithError', {
368
- pendingStepId: pendingStepId,
369
- currentAwaitingStepId: currentAwaitingStepId,
370
- errorsFound: errorsFound
371
- });
476
+ _izContext.logger.debug(
477
+ '[Lib:checkAllAwaitingStepsFinishedShared] Input parameters',
478
+ {
479
+ pendingStepId: pendingStepId,
480
+ currentAwaitingStepId: currentAwaitingStepId,
481
+ errorsFound: errorsFound
482
+ }
483
+ );
372
484
 
373
485
  if (currentAwaitingStepId) {
374
486
  await dynamodbSharedLib.updateItem(
@@ -381,7 +493,7 @@ export async function checkAllAwaitingStepsFinishedShared(
381
493
  {
382
494
  complete: true,
383
495
  errorsFound: errorsFound,
384
- ...additionalAttributes
496
+ additionalAttributes: additionalAttributes
385
497
  }
386
498
  );
387
499
  }
@@ -404,6 +516,15 @@ export async function checkAllAwaitingStepsFinished(
404
516
  errorsFound = [],
405
517
  additionalAttributes = {}
406
518
  ) {
519
+ _izContext.logger.debug(
520
+ '[Lib:checkAllAwaitingStepsFinished] Input parameters',
521
+ {
522
+ pendingStepId: pendingStepId,
523
+ currentAwaitingStepId: currentAwaitingStepId,
524
+ errorsFound: errorsFound
525
+ }
526
+ );
527
+
407
528
  await checkAllAwaitingStepsFinishedShared(
408
529
  _izContext,
409
530
  pendingStepId,
@@ -424,6 +545,9 @@ export async function checkAllAwaitingStepsFinished(
424
545
  if (!item.complete) return false;
425
546
  }
426
547
 
548
+ _izContext.logger.debug(
549
+ '[Lib:checkAllAwaitingStepsFinished] All steps are complete'
550
+ );
427
551
  return true;
428
552
  }
429
553
 
@@ -451,12 +575,21 @@ export async function checkAllAwaitingStepsFinishedWithReturnParams(
451
575
  errorsFound = [],
452
576
  additionalAttributes = {}
453
577
  ) {
454
- _izContext.logger.debug('Lib:checkAllAwaitingStepsFinishedWithReturnParams', {
455
- pendingStepId,
456
- currentAwaitingStepId,
457
- errorsFound,
458
- additionalAttributes
459
- });
578
+ _izContext.logger.debug(
579
+ '[Lib:checkAllAwaitingStepsFinishedWithReturnParams] Input parameters',
580
+ {
581
+ pendingStepId,
582
+ currentAwaitingStepId,
583
+ errorsFound,
584
+ additionalAttributes
585
+ }
586
+ );
587
+
588
+ if (!pendingStepId || !currentAwaitingStepId) {
589
+ throw NoRetryError(
590
+ '[Lib:checkAllAwaitingStepsFinishedWithReturnParams] pendingStepId or currentAwaitingStepId is required'
591
+ );
592
+ }
460
593
 
461
594
  await checkAllAwaitingStepsFinishedShared(
462
595
  _izContext,
@@ -473,7 +606,10 @@ export async function checkAllAwaitingStepsFinishedWithReturnParams(
473
606
  { limit: 50 }
474
607
  );
475
608
 
476
- _izContext.logger.debug('awaitingStepItems:::', awaitingStepItems);
609
+ _izContext.logger.debug(
610
+ '[Lib:checkAllAwaitingStepsFinishedWithReturnParams] awaitingStepItems:::',
611
+ awaitingStepItems
612
+ );
477
613
 
478
614
  // Pass 1: check completeness of all other steps before collecting any data
479
615
  for (const item of awaitingStepItems.Items) {
@@ -487,6 +623,10 @@ export async function checkAllAwaitingStepsFinishedWithReturnParams(
487
623
  }
488
624
  }
489
625
 
626
+ _izContext.logger.debug(
627
+ '[Lib:checkAllAwaitingStepsFinishedWithReturnParams] Pass 1: all steps are complete'
628
+ );
629
+
490
630
  // Pass 2: all steps are complete — collect errors and attributes
491
631
  const collectedAttributes = {};
492
632
  const collectedErrors = [];
@@ -505,6 +645,10 @@ export async function checkAllAwaitingStepsFinishedWithReturnParams(
505
645
  }
506
646
  }
507
647
 
648
+ _izContext.logger.debug(
649
+ '[Lib:checkAllAwaitingStepsFinishedWithReturnParams] Pass 2: all steps are complete — collect errors and attributes'
650
+ );
651
+
508
652
  return {
509
653
  isComplete: true,
510
654
  collectedAttributes,
@@ -521,17 +665,28 @@ export async function checkAllAwaitingStepsFinishedWithReturnParams(
521
665
  * @returns {Promise<boolean>} true if delete flow processed
522
666
  */
523
667
  export async function clearAllAwaitingSteps(_izContext, pendingStepId) {
668
+ _izContext.logger.debug('[Lib:clearAllAwaitingSteps] Input parameters', {
669
+ pendingStepId: pendingStepId
670
+ });
671
+
672
+ if (!pendingStepId) {
673
+ throw NoRetryError('[Lib:clearAllAwaitingSteps] pendingStepId is required');
674
+ }
675
+
524
676
  // ----- query items from GSI table
525
- let listPendingStepIds = await dynamodbSharedLib.query(
677
+ const listPendingStepIds = await dynamodbSharedLib.query(
526
678
  _izContext,
527
679
  dynamodbSharedLib.tableName(_izContext, 'AwaitingMultipleStepByPending'),
528
680
  {
529
681
  pendingStepId: pendingStepId
530
682
  }
531
683
  );
532
- _izContext.logger.debug('listPendingStepIds', listPendingStepIds);
684
+ _izContext.logger.debug(
685
+ '[Lib:clearAllAwaitingSteps] listPendingStepIds',
686
+ listPendingStepIds
687
+ );
533
688
 
534
- let promiseArray = [];
689
+ const promiseArray = [];
535
690
 
536
691
  for (let idx = 0; idx < listPendingStepIds.Items.length; idx++) {
537
692
  _izContext.logger.debug(`delete item in dynamodb AwaitingMultipleSteps`);
@@ -547,7 +702,7 @@ export async function clearAllAwaitingSteps(_izContext, pendingStepId) {
547
702
  );
548
703
 
549
704
  _izContext.logger.debug(
550
- `delete item in dynamodb AwaitingMultipleStepByPending`
705
+ '[Lib:clearAllAwaitingSteps] delete item in dynamodb AwaitingMultipleStepByPending'
551
706
  );
552
707
  promiseArray.push(
553
708
  dynamodbSharedLib.deleteItem(
@@ -585,19 +740,26 @@ export async function removeAwaitingMultipleStep(
585
740
  pendingStepId,
586
741
  errorsFound = []
587
742
  ) {
588
- _izContext.logger.debug('Lib:removeAwaitingMultipleStep', {
743
+ _izContext.logger.debug('[Lib:removeAwaitingMultipleStep] Input parameters', {
589
744
  awaitingStepId: awaitingStepId,
590
- pendingStepId: pendingStepId
745
+ pendingStepId: pendingStepId,
746
+ errorsFound: errorsFound
591
747
  });
592
748
 
593
- let promiseArray = [];
749
+ if (!awaitingStepId || !pendingStepId) {
750
+ throw NoRetryError(
751
+ '[Lib:removeAwaitingMultipleStep] awaitingStepId or pendingStepId is required'
752
+ );
753
+ }
754
+
755
+ const promiseArray = [];
594
756
 
595
- let keyValues = {
757
+ const keyValues = {
596
758
  awaitingStepId: awaitingStepId,
597
759
  pendingStepId: pendingStepId
598
760
  };
599
761
 
600
- let keyValuesForByPending = {
762
+ const keyValuesForByPending = {
601
763
  pendingStepId: pendingStepId,
602
764
  awaitingStepId: awaitingStepId
603
765
  };
@@ -607,7 +769,11 @@ export async function removeAwaitingMultipleStep(
607
769
  });
608
770
 
609
771
  _izContext.logger.debug(
610
- `delete item in dynamodb AwaitingMultipleSteps ==> awaitingStepId:${keyValues.awaitingStepId}`
772
+ '[Lib:removeAwaitingMultipleStep] delete item in dynamodb AwaitingMultipleSteps',
773
+ {
774
+ awaitingStepId: keyValues.awaitingStepId,
775
+ pendingStepId: keyValues.pendingStepId
776
+ }
611
777
  );
612
778
  promiseArray.push(
613
779
  dynamodbSharedLib.deleteItem(
@@ -635,6 +801,21 @@ export async function removeAwaitingMultipleStep(
635
801
  await Promise.all(promiseArray);
636
802
  }
637
803
 
804
+ /**
805
+ * Creates multiple awaiting steps with additional attributes and publishes corresponding messages to an SNS topic.
806
+ * Each message is augmented with a new `parentFlowId` representing its awaiting step before being published.
807
+ *
808
+ * @param {Object} _izContext - The execution context object containing logger and other utilities.
809
+ * @param {Array<Object>} messages - An array of messages to be augmented and published.
810
+ * @param {string} [prefix=''] - An optional prefix used when generating new awaiting step IDs.
811
+ * @param {Object} [flowType={}] - Defines the target SNS topic. Must contain `flowTag` and `serviceTag`.
812
+ * @param {string} flowType.flowTag - The flow tag identifier.
813
+ * @param {string} flowType.serviceTag - The service tag identifier.
814
+ * @param {Object} [additionalAttributes={}] - Additional attributes to save with each new awaiting step.
815
+ * @param {string} pendingStepId - The unique identifier of the parent pending step that waits for these new steps.
816
+ * @returns {Promise<void>} Resolves when all awaiting steps are created and messages are published.
817
+ * @throws {Error} Throws a NoRetryError if `messages` is not an array, or if `flowType` is missing `flowTag` or `serviceTag`.
818
+ */
638
819
  export async function createAwaitingMultipleStepsWithAdditionalAttributesAndPublish(
639
820
  _izContext,
640
821
  messages,
@@ -643,30 +824,28 @@ export async function createAwaitingMultipleStepsWithAdditionalAttributesAndPubl
643
824
  additionalAttributes = {},
644
825
  pendingStepId
645
826
  ) {
827
+ _izContext.logger.debug(
828
+ '[Lib:asyncFlow:createAwaitingMultipleStepsWithAdditionalAttributesAndPublish] Input parameters',
829
+ {
830
+ messages,
831
+ prefix,
832
+ flowType,
833
+ additionalAttributes,
834
+ pendingStepId
835
+ }
836
+ );
837
+
646
838
  if (!Array.isArray(messages)) {
647
- throw new Error('messages must be an array');
839
+ throw NoRetryError('messages must be an array');
648
840
  }
649
841
 
650
842
  const flowTag = flowType.flowTag;
651
843
  const serviceTag = flowType.serviceTag;
652
844
 
653
- _izContext.logger.debug(
654
- '[lib:asyncFlow:createAwaitingMultipleStepsWithAdditionalAttributesAndPublish] flowType',
655
- {
656
- flowTag,
657
- serviceTag
658
- }
659
- );
660
-
661
845
  if (flowTag === undefined || serviceTag === undefined) {
662
- throw new Error('flowType must have both flowTag and serviceTag');
846
+ throw NoRetryError('flowType must have both flowTag and serviceTag');
663
847
  }
664
848
 
665
- _izContext.logger.debug(
666
- 'Lib:asyncFlow:createAwaitingMultipleStepsWithAdditionalAttributesAndPublish',
667
- { count: messages.length, pendingStepId, flowType }
668
- );
669
-
670
849
  const topicArn = snsSharedLib.snsTopicArnByFlowSchema(
671
850
  _izContext,
672
851
  flowType.flowTag,
@@ -674,8 +853,8 @@ export async function createAwaitingMultipleStepsWithAdditionalAttributesAndPubl
674
853
  );
675
854
 
676
855
  _izContext.logger.debug(
677
- 'Lib:asyncFlow:createAwaitingMultipleStepsWithAdditionalAttributesAndPublish',
678
- { topicArn }
856
+ '[Lib:asyncFlow:createAwaitingMultipleStepsWithAdditionalAttributesAndPublish] Topic Arn',
857
+ topicArn
679
858
  );
680
859
 
681
860
  const messagesWithParentId = await Promise.all(
@@ -702,4 +881,8 @@ export async function createAwaitingMultipleStepsWithAdditionalAttributesAndPubl
702
881
  })
703
882
  )
704
883
  );
884
+
885
+ _izContext.logger.debug(
886
+ '[Lib:asyncFlow:createAwaitingMultipleStepsWithAdditionalAttributesAndPublish] Exit point'
887
+ );
705
888
  }
@@ -41,24 +41,25 @@ export async function createAwaitingStep(
41
41
  additionalAttributes = {}, // save in top level
42
42
  callingFlowConfig = {} // optional
43
43
  ) {
44
- _izContext.logger.debug('Lib createAwaitingStep:', {
44
+ _izContext.logger.debug('[Lib:AsyncFlow:createAwaitingStep] Input: ', {
45
45
  awaitingStepId,
46
46
  pendingStepId,
47
47
  additionalAttributes,
48
48
  callingFlowConfig
49
49
  });
50
50
 
51
- let attributesWhenCreate = {
51
+ const attributesWhenCreate = {
52
52
  awaitingStepId: awaitingStepId,
53
53
  pendingStepId: pendingStepId,
54
54
  timestamp: Date.now(),
55
55
  uniqueRequestId: _izContext.uniqueRequestId
56
56
  };
57
57
  // loop if not empty
58
- for (let additionalAttribute in additionalAttributes) {
58
+ for (const additionalAttribute in additionalAttributes) {
59
59
  attributesWhenCreate[additionalAttribute] =
60
60
  additionalAttributes[additionalAttribute]; // each additionalAttributes
61
61
  }
62
+
62
63
  if (Object.keys(callingFlowConfig).length > 0) {
63
64
  Object.assign(attributesWhenCreate, { callingFlowConfig });
64
65
  }
@@ -81,9 +82,20 @@ export async function findPendingStepIdsAwaitingStep(
81
82
  _izContext,
82
83
  awaitingStepId
83
84
  ) {
84
- let pendingStepIds = [];
85
+ _izContext.logger.debug(
86
+ '[Lib:AsyncFlow:findPendingStepIdsAwaitingStep] Input: ',
87
+ {
88
+ awaitingStepId
89
+ }
90
+ );
91
+
92
+ if (!awaitingStepId) {
93
+ throw NoRetryError('awaitingStepId is required');
94
+ }
95
+
96
+ const pendingStepIds = [];
85
97
 
86
- let listPendingStepIds = await dynamodbSharedLib.query(
98
+ const listPendingStepIds = await dynamodbSharedLib.query(
87
99
  _izContext,
88
100
  dynamodbSharedLib.tableName(_izContext, 'AwaitingStep'),
89
101
  {
@@ -106,7 +118,18 @@ export async function findPendingStepIdsAwaitingStep(
106
118
  * @returns {Promise<AwaitingStepItem[]>}
107
119
  */
108
120
  export async function findPendingStepsAwaitingStep(_izContext, awaitingStepId) {
109
- let listPendingSteps = await dynamodbSharedLib.query(
121
+ _izContext.logger.debug(
122
+ '[Lib:AsyncFlow:findPendingStepsAwaitingStep] Input: ',
123
+ {
124
+ awaitingStepId
125
+ }
126
+ );
127
+
128
+ if (!awaitingStepId) {
129
+ throw NoRetryError('awaitingStepId is required');
130
+ }
131
+
132
+ const listPendingSteps = await dynamodbSharedLib.query(
110
133
  _izContext,
111
134
  dynamodbSharedLib.tableName(_izContext, 'AwaitingStep'),
112
135
  {
@@ -126,17 +149,32 @@ export async function findPendingStepsAwaitingStep(_izContext, awaitingStepId) {
126
149
  * @throws {NoRetryError} if there is not exactly one item
127
150
  */
128
151
  export async function findPendingStepAwaitingStep(_izContext, awaitingStepId) {
129
- let listPendingSteps = await dynamodbSharedLib.query(
152
+ _izContext.logger.debug(
153
+ '[Lib:AsyncFlow:findPendingStepAwaitingStep] Input: ',
154
+ {
155
+ awaitingStepId
156
+ }
157
+ );
158
+
159
+ if (!awaitingStepId) {
160
+ throw NoRetryError('awaitingStepId is required');
161
+ }
162
+
163
+ const listPendingSteps = await dynamodbSharedLib.query(
130
164
  _izContext,
131
165
  dynamodbSharedLib.tableName(_izContext, 'AwaitingStep'),
132
166
  {
133
167
  awaitingStepId: awaitingStepId
134
168
  }
135
169
  );
136
- _izContext.logger.debug('Record of awaitingStepId', listPendingSteps);
170
+
171
+ _izContext.logger.debug(
172
+ '[Lib:AsyncFlow:findPendingStepAwaitingStep] Found records: ',
173
+ listPendingSteps
174
+ );
137
175
 
138
176
  if (listPendingSteps.Items.length !== 1) {
139
- throw new NoRetryError('listPendingSteps not equals 1');
177
+ throw NoRetryError('listPendingSteps not equals 1');
140
178
  }
141
179
  return listPendingSteps.Items[0];
142
180
  }
@@ -154,6 +192,17 @@ export async function findPendingStepAwaitingStepWithCallingFlow(
154
192
  _izContext,
155
193
  awaitingStepId
156
194
  ) {
195
+ _izContext.logger.debug(
196
+ '[Lib:AsyncFlow:findPendingStepAwaitingStepWithCallingFlow] Input: ',
197
+ {
198
+ awaitingStepId
199
+ }
200
+ );
201
+
202
+ if (!awaitingStepId) {
203
+ throw NoRetryError('awaitingStepId is required');
204
+ }
205
+
157
206
  let callingFlowConfig = null;
158
207
  let awaitingStep = await findPendingStepAwaitingStep(
159
208
  _izContext,
@@ -184,6 +233,15 @@ export async function removeAwaitingStep(
184
233
  awaitingStepId,
185
234
  pendingStepId
186
235
  ) {
236
+ _izContext.logger.debug('[Lib:AsyncFlow:removeAwaitingStep] Input: ', {
237
+ awaitingStepId,
238
+ pendingStepId
239
+ });
240
+
241
+ if (!awaitingStepId || !pendingStepId) {
242
+ throw NoRetryError('awaitingStepId and pendingStepId are required');
243
+ }
244
+
187
245
  await dynamodbSharedLib.deleteItem(
188
246
  _izContext,
189
247
  dynamodbSharedLib.tableName(_izContext, 'AwaitingStep'),
@@ -213,6 +271,22 @@ export async function removeAwaitingStepWithCheckUniqueRequestId(
213
271
  checkUniqueRequestId,
214
272
  prefix = ''
215
273
  ) {
274
+ _izContext.logger.debug(
275
+ '[Lib:AsyncFlow:removeAwaitingStepWithCheckUniqueRequestId] Input: ',
276
+ {
277
+ awaitingStepId,
278
+ pendingStepId,
279
+ checkUniqueRequestId,
280
+ prefix
281
+ }
282
+ );
283
+
284
+ if (!awaitingStepId || !pendingStepId || !checkUniqueRequestId) {
285
+ throw NoRetryError(
286
+ 'awaitingStepId, pendingStepId and checkUniqueRequestId are required'
287
+ );
288
+ }
289
+
216
290
  // if logicalElements add queryElements.logicalElements
217
291
  // set condition uniqueRequestId match with exists
218
292
  const queryElementsCondition = {